xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 14930)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)tmps.c 1.11 09/09/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      *	register temporaries
22      *	- are allocated from highreg towards lowreg.
23      *	- are of size regsize.
24      *	- register numbers from the various register types are mapped to
25      *	  integer register numbers using the offsets.  (cf. pcc/mac2defs)
26      *
27      *	stack temporaries
28      *	- are allocated on a downward growing stack.
29      */
30 
31 #ifdef vax
32     /*
33      *	first pass register declaration constants
34      */
35 struct	regtype {
36     long	lowreg;
37     long	highreg;
38     long	regsize;
39 } regtypes[NUMREGTYPES] = {
40 	{ 6, 11, 4 },		/* r6..r11 */
41 };
42 #endif vax
43 
44 #ifdef mc68000
45     /*
46      *	first pass register declaration constants
47      */
48 struct	regtype {
49     long	lowreg;
50     long	highreg;
51     long	regsize;
52 } regtypes[NUMREGTYPES] = {
53 	{ 2, 7, 4 },		/* d2..d7 */
54 	{ 2, 5, 4 },		/* a2..a5 */
55 };
56 #endif mc68000
57 #endif PC
58 
59 tmpinit(cbn)
60 	int	cbn;
61 {
62 	struct om	*sizesp = &sizes[cbn];
63 	int	i;
64 
65 	sizesp->om_max = -DPOFF1;
66 	sizesp->curtmps.om_off = -DPOFF1;
67 #	ifdef PC
68 		for (i = 0; i < NUMREGTYPES; i++) {
69 			sizesp->low_water[i] = regtypes[i].highreg + 1;
70 			sizesp->curtmps.next_avail[i] = regtypes[i].highreg;
71 		}
72 #	endif PC
73 }
74 
75 /*
76  * allocate runtime temporary variables
77  */
78 struct nl *
79 tmpalloc(size, type, mode)
80 	long size;
81 	struct nl *type;
82 	int mode;
83 {
84 	register struct om	*op = &sizes[ cbn ];
85 	register int		offset;
86 	register struct nl	*nlp;
87 	long			alignment;
88 
89 #	ifdef PC
90 #	    ifdef vax
91 		if (  mode == REGOK
92 		   && size == regtypes[REG_GENERAL].regsize
93 		   && op->curtmps.next_avail[REG_GENERAL]
94 			    >= regtypes[REG_GENERAL].lowreg) {
95 			offset = op->curtmps.next_avail[REG_GENERAL]--;
96 			if (offset < op->low_water[REG_GENERAL]) {
97 				op->low_water[REG_GENERAL] = offset;
98 			}
99 			nlp = defnl(0, VAR, type, offset );
100 			nlp -> extra_flags = NLOCAL | NREGVAR;
101 			putlbracket(ftnno, op);
102 			return nlp;
103 		}
104 #	    endif vax
105 #	    ifdef mc68000
106 		if (  mode == REGOK
107 		   && type != nl + TPTR
108 		   && size == regtypes[REG_DATA].regsize
109 		   && op->curtmps.next_avail[REG_DATA]
110 			    >= regtypes[REG_DATA].lowreg) {
111 			offset = op->curtmps.next_avail[REG_DATA]--;
112 			if (offset < op->low_water[REG_DATA]) {
113 				op->low_water[REG_DATA] = offset;
114 			}
115 			nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET );
116 			nlp -> extra_flags = NLOCAL | NREGVAR;
117 			putlbracket(ftnno, op);
118 			return nlp;
119 		}
120 		if (  mode == REGOK
121 		   && type == nl + TPTR
122 		   && size == regtypes[REG_ADDR].regsize
123 		   && op->curtmps.next_avail[REG_ADDR]
124 			    >= regtypes[REG_ADDR].lowreg) {
125 			offset = op->curtmps.next_avail[REG_ADDR]--;
126 			if (offset < op->low_water[REG_ADDR]) {
127 				op->low_water[REG_ADDR] = offset;
128 			}
129 			nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET );
130 			nlp -> extra_flags = NLOCAL | NREGVAR;
131 			putlbracket(ftnno, op);
132 			return nlp;
133 		}
134 #	    endif mc68000
135 #	endif PC
136 	if (type == NIL) {
137 	    alignment = A_STACK;
138 	} else {
139 	    alignment = align(type);
140 	}
141         op->curtmps.om_off =
142 	    roundup((int)(op->curtmps.om_off - size), alignment);
143 	offset = op->curtmps.om_off;
144 	if ( offset < op->om_max ) {
145 	        op->om_max = offset;
146 	}
147 	nlp = defnl( 0 , VAR , type , offset );
148 #	ifdef PC
149 	    nlp -> extra_flags = NLOCAL;
150 	    putlbracket(ftnno, op);
151 #	endif PC
152 	return nlp;
153 }
154 
155 /*
156  * deallocate runtime temporary variables
157  */
158 tmpfree(restore)
159     register struct tmps	*restore;
160 {
161     register struct om		*op = &sizes[ cbn ];
162     bool			change = FALSE;
163 
164 #   ifdef PC
165 #	ifdef vax
166 	    if (restore->next_avail[REG_GENERAL]
167 		> op->curtmps.next_avail[REG_GENERAL]) {
168 		    op->curtmps.next_avail[REG_GENERAL]
169 			= restore->next_avail[REG_GENERAL];
170 		    change = TRUE;
171 	    }
172 #	endif vax
173 #	ifdef mc68000
174 	    if (restore->next_avail[REG_DATA]
175 		> op->curtmps.next_avail[REG_DATA]) {
176 		    op->curtmps.next_avail[REG_DATA]
177 			= restore->next_avail[REG_DATA];
178 		    change = TRUE;
179 	    }
180 	    if (restore->next_avail[REG_ADDR]
181 		> op->curtmps.next_avail[REG_ADDR]) {
182 		    op->curtmps.next_avail[REG_ADDR]
183 			= restore->next_avail[REG_ADDR];
184 		    change = TRUE;
185 	    }
186 #	endif mc68000
187 #   endif PC
188     if (restore->om_off > op->curtmps.om_off) {
189 	    op->curtmps.om_off = restore->om_off;
190 	    change = TRUE;
191     }
192 #   ifdef PC
193 	if (change) {
194 	    putlbracket(ftnno, op);
195 	}
196 #   endif PC
197 }
198 
199 #ifdef PC
200 #ifdef vax
201 /*
202  * create a save mask for registers which have been used
203  * in this level
204  */
205 savmask()
206 {
207 	int mask;
208 	int i;
209 
210 	mask = RSAVEMASK;
211 	if (opt('t'))
212 	        mask |= RUNCHECK;
213 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
214 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
215 		mask |= 1 << i;
216 	    }
217 	}
218 	return mask;
219 }
220 #endif vax
221 #endif PC
222