xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 14907)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)tmps.c 1.10 09/05/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,
100 				offset + regtypes[REG_GENERAL].regno_offset );
101 			nlp -> extra_flags = NLOCAL | NREGVAR;
102 			putlbracket(ftnno, op);
103 			return nlp;
104 		}
105 #	    endif vax
106 #	    ifdef mc68000
107 		if (  mode == REGOK
108 		   && type != nl + TPTR
109 		   && size == regtypes[REG_DATA].regsize
110 		   && op->curtmps.next_avail[REG_DATA]
111 			    >= regtypes[REG_DATA].lowreg) {
112 			offset = op->curtmps.next_avail[REG_DATA]--;
113 			if (offset < op->low_water[REG_DATA]) {
114 				op->low_water[REG_DATA] = offset;
115 			}
116 			nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET );
117 			nlp -> extra_flags = NLOCAL | NREGVAR;
118 			putlbracket(ftnno, op);
119 			return nlp;
120 		}
121 		if (  mode == REGOK
122 		   && type == nl + TPTR
123 		   && size == regtypes[REG_ADDR].regsize
124 		   && op->curtmps.next_avail[REG_ADDR]
125 			    >= regtypes[REG_ADDR].lowreg) {
126 			offset = op->curtmps.next_avail[REG_ADDR]--;
127 			if (offset < op->low_water[REG_ADDR]) {
128 				op->low_water[REG_ADDR] = offset;
129 			}
130 			nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET );
131 			nlp -> extra_flags = NLOCAL | NREGVAR;
132 			putlbracket(ftnno, op);
133 			return nlp;
134 		}
135 #	    endif mc68000
136 #	endif PC
137 	if (type == NIL) {
138 	    alignment = A_STACK;
139 	} else {
140 	    alignment = align(type);
141 	}
142         op->curtmps.om_off =
143 	    roundup((int)(op->curtmps.om_off - size), alignment);
144 	offset = op->curtmps.om_off;
145 	if ( offset < op->om_max ) {
146 	        op->om_max = offset;
147 	}
148 	nlp = defnl( 0 , VAR , type , offset );
149 #	ifdef PC
150 	    nlp -> extra_flags = NLOCAL;
151 	    putlbracket(ftnno, op);
152 #	endif PC
153 	return nlp;
154 }
155 
156 /*
157  * deallocate runtime temporary variables
158  */
159 tmpfree(restore)
160     register struct tmps	*restore;
161 {
162     register struct om		*op = &sizes[ cbn ];
163     bool			change = FALSE;
164 
165 #   ifdef PC
166 #	ifdef vax
167 	    if (restore->next_avail[REG_GENERAL]
168 		> op->curtmps.next_avail[REG_GENERAL]) {
169 		    op->curtmps.next_avail[REG_GENERAL]
170 			= restore->next_avail[REG_GENERAL];
171 		    change = TRUE;
172 	    }
173 #	endif vax
174 #	ifdef mc68000
175 	    if (restore->next_avail[REG_DATA]
176 		> op->curtmps.next_avail[REG_DATA]) {
177 		    op->curtmps.next_avail[REG_DATA]
178 			= restore->next_avail[REG_DATA];
179 		    change = TRUE;
180 	    }
181 	    if (restore->next_avail[REG_ADDR]
182 		> op->curtmps.next_avail[REG_ADDR]) {
183 		    op->curtmps.next_avail[REG_ADDR]
184 			= restore->next_avail[REG_ADDR];
185 		    change = TRUE;
186 	    }
187 #	endif mc68000
188 #   endif PC
189     if (restore->om_off > op->curtmps.om_off) {
190 	    op->curtmps.om_off = restore->om_off;
191 	    change = TRUE;
192     }
193 #   ifdef PC
194 	if (change) {
195 	    putlbracket(ftnno, op);
196 	}
197 #   endif PC
198 }
199 
200 #ifdef PC
201 #ifdef vax
202 /*
203  * create a save mask for registers which have been used
204  * in this level
205  */
206 savmask()
207 {
208 	int mask;
209 	int i;
210 
211 	mask = RSAVEMASK;
212 	if (opt('t'))
213 	        mask |= RUNCHECK;
214 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
215 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
216 		mask |= 1 << i;
217 	    }
218 	}
219 	return mask;
220 }
221 #endif vax
222 #endif PC
223