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