xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 14931)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)tmps.c 1.12 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 if (type == nl+TPTR) {
139 	    alignment = A_POINT;
140 	} else {
141 	    alignment = align(type);
142 	}
143         op->curtmps.om_off =
144 	    roundup((int)(op->curtmps.om_off - size), alignment);
145 	offset = op->curtmps.om_off;
146 	if ( offset < op->om_max ) {
147 	        op->om_max = offset;
148 	}
149 	nlp = defnl( 0 , VAR , type , offset );
150 #	ifdef PC
151 	    nlp -> extra_flags = NLOCAL;
152 	    putlbracket(ftnno, op);
153 #	endif PC
154 	return nlp;
155 }
156 
157 /*
158  * deallocate runtime temporary variables
159  */
160 tmpfree(restore)
161     register struct tmps	*restore;
162 {
163     register struct om		*op = &sizes[ cbn ];
164     bool			change = FALSE;
165 
166 #   ifdef PC
167 #	ifdef vax
168 	    if (restore->next_avail[REG_GENERAL]
169 		> op->curtmps.next_avail[REG_GENERAL]) {
170 		    op->curtmps.next_avail[REG_GENERAL]
171 			= restore->next_avail[REG_GENERAL];
172 		    change = TRUE;
173 	    }
174 #	endif vax
175 #	ifdef mc68000
176 	    if (restore->next_avail[REG_DATA]
177 		> op->curtmps.next_avail[REG_DATA]) {
178 		    op->curtmps.next_avail[REG_DATA]
179 			= restore->next_avail[REG_DATA];
180 		    change = TRUE;
181 	    }
182 	    if (restore->next_avail[REG_ADDR]
183 		> op->curtmps.next_avail[REG_ADDR]) {
184 		    op->curtmps.next_avail[REG_ADDR]
185 			= restore->next_avail[REG_ADDR];
186 		    change = TRUE;
187 	    }
188 #	endif mc68000
189 #   endif PC
190     if (restore->om_off > op->curtmps.om_off) {
191 	    op->curtmps.om_off = restore->om_off;
192 	    change = TRUE;
193     }
194 #   ifdef PC
195 	if (change) {
196 	    putlbracket(ftnno, op);
197 	}
198 #   endif PC
199 }
200 
201 #ifdef PC
202 #ifdef vax
203 /*
204  * create a save mask for registers which have been used
205  * in this level
206  */
207 savmask()
208 {
209 	int mask;
210 	int i;
211 
212 	mask = RSAVEMASK;
213 	if (opt('t'))
214 	        mask |= RUNCHECK;
215 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
216 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
217 		mask |= 1 << i;
218 	    }
219 	}
220 	return mask;
221 }
222 #endif vax
223 #endif PC
224