|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)tmps.c 1.12 9/9/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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.