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
tmpinit(cbn)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 *
tmpalloc(size,type,mode)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*/
tmpfree(restore)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 */
savmask()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