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