xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 11853)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)tmps.c 1.9 04/06/83";
4 
5 #include "whoami.h"
6 #include "0.h"
7 #include "objfmt.h"
8 #ifdef PC
9 #   include "pc.h"
10 #endif PC
11 #include "align.h"
12 #include "tmps.h"
13 
14 /*
15  * This routine defines the register allocation strategy
16  * All temporaries are allocated here, and this routines decides
17  * where they are to be put.
18  */
19 #ifdef PC
20     /*
21      *	registers are allocated from highreg towards lowreg.
22      *	registers are of size regsize.
23      *	stack variables are allocated on a downward growing stack.
24      */
25 
26 #ifdef vax
27     /*
28      *	first pass register declaration constants
29      */
30 #   define	LONGREGTYPE	0
31 struct	regtype {
32     long	lowreg;
33     long	highreg;
34     long	regsize;
35 } regtypes[NUMREGTYPES] = {
36 	{ 6, 11, 4 },
37 };
38 #endif vax
39 
40 #ifdef mc68000
41     /*
42      *	first pass register declaration constants
43      */
44 #   define	DATAREGTYPE	0
45 #   define	ADDRREGTYPE	1
46 struct	regtype {
47     long	lowreg;
48     long	highreg;
49     long	regsize;
50 } regtypes[NUMREGTYPES] = {
51 	{ 2, 7, 0 },		/* off for now */
52 	{ 2, 5, 0 },		/* off for now */
53 };
54 #endif mc68000
55 #endif PC
56 
57 tmpinit(cbn)
58 	int	cbn;
59 {
60 	struct om	*sizesp = &sizes[cbn];
61 	int	i;
62 
63 	sizesp->om_max = -DPOFF1;
64 	sizesp->curtmps.om_off = -DPOFF1;
65 #	ifdef PC
66 		for (i = 0; i < NUMREGTYPES; i++) {
67 			sizesp->low_water[i] = regtypes[i].highreg + 1;
68 			sizesp->curtmps.next_avail[i] = regtypes[i].highreg;
69 		}
70 #	endif PC
71 }
72 
73 /*
74  * allocate runtime temporary variables
75  */
76 struct nl *
77 tmpalloc(size, type, mode)
78 	long size;
79 	struct nl *type;
80 	int mode;
81 {
82 	register struct om	*op = &sizes[ cbn ];
83 	register int		offset;
84 	register struct nl	*nlp;
85 	long			alignment;
86 
87 #	ifdef PC
88 #	    ifdef vax
89 		if (  mode == REGOK
90 		   && size == regtypes[REG_GENERAL].regsize
91 		   && op->curtmps.next_avail[REG_GENERAL]
92 			    >= regtypes[REG_GENERAL].lowreg) {
93 			offset = op->curtmps.next_avail[REG_GENERAL]--;
94 			if (offset < op->low_water[REG_GENERAL]) {
95 				op->low_water[REG_GENERAL] = offset;
96 			}
97 			nlp = defnl( 0 , VAR , type , offset );
98 			nlp -> extra_flags = NLOCAL | NREGVAR;
99 			putlbracket(ftnno, op);
100 			return nlp;
101 		}
102 #	    endif vax
103 #	endif PC
104 	if (type == NIL) {
105 	    alignment = A_STACK;
106 	} else {
107 	    alignment = align(type);
108 	}
109         op->curtmps.om_off =
110 	    roundup((int)(op->curtmps.om_off - size), alignment);
111 	offset = op->curtmps.om_off;
112 	if ( offset < op->om_max ) {
113 	        op->om_max = offset;
114 	}
115 	nlp = defnl( 0 , VAR , type , offset );
116 #	ifdef PC
117 	    nlp -> extra_flags = NLOCAL;
118 	    putlbracket(ftnno, op);
119 #	endif PC
120 	return nlp;
121 }
122 
123 /*
124  * deallocate runtime temporary variables
125  */
126 tmpfree(restore)
127     register struct tmps	*restore;
128 {
129     register struct om		*op = &sizes[ cbn ];
130     bool			change = FALSE;
131 
132 #   ifdef PC
133 	    /* i think this never gives back storage!	... peter */
134 #	ifdef vax
135 	    if (restore->next_avail[REG_GENERAL]
136 		> op->curtmps.next_avail[REG_GENERAL]) {
137 		    op->curtmps.next_avail[REG_GENERAL]
138 			= restore->next_avail[REG_GENERAL];
139 		    change = TRUE;
140 	    }
141 #	endif vax
142 #   endif PC
143     if (restore->om_off > op->curtmps.om_off) {
144 	    op->curtmps.om_off = restore->om_off;
145 	    change = TRUE;
146     }
147 #   ifdef PC
148 	if (change) {
149 	    putlbracket(ftnno, op);
150 	}
151 #   endif PC
152 }
153 
154 #ifdef PC
155 #ifdef vax
156 /*
157  * create a save mask for registers which have been used
158  * in this level
159  */
160 savmask()
161 {
162 	int mask;
163 	int i;
164 
165 	mask = RSAVEMASK;
166 	if (opt('t'))
167 	        mask |= RUNCHECK;
168 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
169 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
170 		mask |= 1 << i;
171 	    }
172 	}
173 	return mask;
174 }
175 #endif vax
176 #endif PC
177