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