mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 16:34:07 +00:00
365 lines
10 KiB
Plaintext
365 lines
10 KiB
Plaintext
1File: UTIL.C Page 1
|
|
1 /*
|
|
2 Copyright 1982
|
|
3 Alcyon Corporation
|
|
4 8716 Production Ave.
|
|
5 San Diego, Ca. 92121
|
|
6 */
|
|
7
|
|
8 #include "cgen.h"
|
|
9 #include "cskel.h"
|
|
10
|
|
11 /* xnalloc - allocate address-indexed node*/
|
|
12 char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
|
|
13 int type; /* data type*/
|
|
14 int ar; /* address register*/
|
|
15 int off; /* 8-bit offset*/
|
|
16 int xr; /* index register*/
|
|
17 int xt; /* index register type*/
|
|
18 {
|
|
19 register struct indexnode *xp;
|
|
20
|
|
21 xp = talloc(sizeof(*xp));
|
|
22 xp->t_op = SYMBOL;
|
|
23 xp->t_type = type;
|
|
24 xp->t_sc = INDEXED;
|
|
25 xp->t_reg = ar;
|
|
26 xp->t_su = SU_ADDR;
|
|
27 xp->t_offset = off;
|
|
28 xp->t_xreg = xr;
|
|
29 xp->t_xtype = xt;
|
|
30 return(xp);
|
|
31 }
|
|
32
|
|
33 /* tcopy - expression tree copy*/
|
|
34 char *tcopy(tp) /* returns ptr to copied tree*/
|
|
35 struct tnode *tp;
|
|
36 {
|
|
37 register char *p;
|
|
38
|
|
39 switch( tp->t_op ) {
|
|
40
|
|
41 case SYMBOL:
|
|
42 if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
|
|
43 p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
|
|
44 else {
|
|
45 p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
|
|
46 p->t_label = tp->t_label;
|
|
47 }
|
|
48 p->t_offset = tp->t_offset;
|
|
49 p->t_reg = tp->t_reg;
|
|
50 return(p);
|
|
51
|
|
52 case CINT:
|
|
53 return(cnalloc(tp->t_type,tp->t_value));
|
|
54
|
|
55 case CLONG:
|
|
56 return(lcnalloc(tp->t_type,tp->t_lvalue));
|
|
57
|
|
58 case CFLOAT: /*[vlh] 3.4 */
|
|
59 return(fpcnalloc(tp->t_type,tp->t_lvalue));
|
|
1File: UTIL.C Page 2
|
|
60
|
|
61 case DCLONG:
|
|
62 p = lcnalloc(tp->t_type,tp->t_lvalue);
|
|
63 p->t_op = DCLONG;
|
|
64 return(p);
|
|
65
|
|
66 default:
|
|
67 if( binop(tp->t_op) )
|
|
68 return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
|
69 tcopy(tp->t_right)));
|
|
70 if( unaryop(tp->t_op) )
|
|
71 return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
|
|
72 null));
|
|
73 error("tcopy op=%d",tp->t_op);
|
|
74 return(tp);
|
|
75 }
|
|
76 }
|
|
77
|
|
78 /* outaexpr - output address expression*/
|
|
79 outaexpr(tp,flags) /* returns - none*/
|
|
80 struct tnode *tp; /* pointer to tree*/
|
|
81 int flags; /* flags (IMMED,LOFFSET,...)*/
|
|
82 {
|
|
83 register int off, reg, lab;
|
|
84 long l;
|
|
85
|
|
86 if( tp->t_op == ADDR ) {
|
|
87 tp = tp->t_left;
|
|
88 putchar('#');
|
|
89 }
|
|
90 off = tp->t_offset;
|
|
91 reg = tp->t_reg;
|
|
92 lab = tp->t_label;
|
|
93 switch( tp->t_op ) {
|
|
94
|
|
95 case AUTOINC:
|
|
96 printf("(R%d)+",reg);
|
|
97 break;
|
|
98
|
|
99 case AUTODEC:
|
|
100 printf("-(R%d)",reg);
|
|
101 break;
|
|
102
|
|
103 case CINT:
|
|
104 if( flags & IMMED )
|
|
105 putchar('#');
|
|
106 printf("%d",tp->t_value);
|
|
107 break;
|
|
108
|
|
109 case DCLONG:
|
|
110 case CLONG:
|
|
111 case CFLOAT: /*[vlh] 3.4 */
|
|
112 if( flags & IMMED )
|
|
113 putchar('#');
|
|
114 outlval(tp->t_lvalue);
|
|
115 break;
|
|
116
|
|
117 case SYMBOL:
|
|
118 if( off ) {
|
|
1File: UTIL.C Page 3
|
|
119 switch( tp->t_sc ) {
|
|
120
|
|
121 default:
|
|
122 printf("%d+",off);
|
|
123 break;
|
|
124
|
|
125 case REGOFF:
|
|
126 printf("%d",off);
|
|
127 case CINDR:
|
|
128 case CLINDR:
|
|
129 case CFINDR: /* [vlh] 3.4 */
|
|
130 case INDEXED:
|
|
131 break;
|
|
132
|
|
133 case REGISTER:
|
|
134 error("invalid register expression");
|
|
135 break;
|
|
136 }
|
|
137 }
|
|
138 switch( tp->t_sc ) {
|
|
139
|
|
140 case REGISTER:
|
|
141 printf("R%d",reg);
|
|
142 break;
|
|
143
|
|
144 case REGOFF:
|
|
145 printf("(R%d)",reg);
|
|
146 break;
|
|
147
|
|
148 case EXTERNAL:
|
|
149 printf("_%.8s",tp->t_symbol);
|
|
150 break;
|
|
151
|
|
152 case EXTOFF:
|
|
153 printf("_%.8s(R%d)",tp->t_symbol,reg);
|
|
154 break;
|
|
155
|
|
156 case STATIC:
|
|
157 printf("L%d",lab);
|
|
158 break;
|
|
159
|
|
160 case STATOFF:
|
|
161 printf("L%d(R%d)",lab,reg);
|
|
162 break;
|
|
163
|
|
164 case INDEXED:
|
|
165 printf("%d(R%d,R%d",off,reg,tp->t_xreg);
|
|
166 outatype(tp->t_xtype);
|
|
167 putchar(')');
|
|
168 break;
|
|
169
|
|
170 case CINDR:
|
|
171 printf("%d",off);
|
|
172 break;
|
|
173 /*
|
|
174 * the following will work on: PDP-11, 68000, IBM-360, VAX, etc.
|
|
175 * it will not work on word machines or on machines where either
|
|
176 * longs two ints or two shorts.
|
|
177 */
|
|
1File: UTIL.C Page 4
|
|
178 case CLINDR:
|
|
179 case CFINDR: /* [vlh] 3.4 */
|
|
180 l.hiword = tp->t_offset;
|
|
181 l.loword = tp->t_ssp;
|
|
182 outlval(l);
|
|
183 break;
|
|
184
|
|
185 default:
|
|
186 error("invalid storage class %d\n",tp->t_sc);
|
|
187 break;
|
|
188 }
|
|
189 break;
|
|
190
|
|
191 default:
|
|
192 error("invalid operator %d\n",tp->t_op);
|
|
193 break;
|
|
194 }
|
|
195 }
|
|
196
|
|
197 /* outlval - output long value*/
|
|
198 /* This is a big pain because the PDP-11 doesn't do long divides*/
|
|
199 /* in hardware.*/
|
|
200 outlval(lval)
|
|
201 long lval;
|
|
202 {
|
|
203 char digs[8];
|
|
204 register int i, c;
|
|
205
|
|
206 i = 0;
|
|
207 do {
|
|
208 digs[i++] = lval & 0xf;
|
|
209 lval =>> 4;
|
|
210 lval =& 0xfffffff;
|
|
211 } while ( lval );
|
|
212 putchar('$');
|
|
213 while( --i >= 0 ) {
|
|
214 c = digs[i];
|
|
215 putchar(c>=10?c+('a'-10):c+'0');
|
|
216 }
|
|
217 }
|
|
218
|
|
219 /* outtype - output 68000 type (null, .b, .l) depending on data type*/
|
|
220 outtype(type)
|
|
221 int type;
|
|
222 {
|
|
223 if( isfloat(type) )
|
|
224 printf(".l");
|
|
225 else if( longorptr(type) )
|
|
226 printf(".l");
|
|
227 else if( type == CHAR )
|
|
228 printf(".b");
|
|
229 }
|
|
230
|
|
231 /* outatype - output address type (.l or null) depending on data type*/
|
|
232 outatype(type)
|
|
233 int type;
|
|
234 {
|
|
235 if( longorptr(type) || isfloat(type) )
|
|
236 printf(".l");
|
|
1File: UTIL.C Page 5
|
|
237 }
|
|
238
|
|
239 /* outextend - output register extension to long depending on type*/
|
|
240 outextend(tp,type,reg) /* returns - none*/
|
|
241 struct tnode *tp; /* tree to convert from*/
|
|
242 int type; /* type to convert to*/
|
|
243 int reg; /* register to convert*/
|
|
244 {
|
|
245 if( (isdreg(reg)) && !(longorptr(tp->t_type)) && (longorptr(type)) ) {
|
|
246 if( unsign(tp->t_type) )
|
|
247 outuext(reg);
|
|
248 else
|
|
249 outext(reg);
|
|
250 }
|
|
251 }
|
|
252
|
|
253 /* outrr - output register to register instruction*/
|
|
254 outrr(ins,r1,r2,tp)
|
|
255 char *ins;
|
|
256 int r1;
|
|
257 int r2;
|
|
258 struct tnode *tp;
|
|
259 {
|
|
260 printf("%s",ins);
|
|
261 if( isareg(r1) || isareg(r2) )
|
|
262 outatype(tp->t_type);
|
|
263 else
|
|
264 outtype(tp->t_type);
|
|
265 printf(" R%d,R%d\n",r1,r2);
|
|
266 }
|
|
267
|
|
268 /* outmovr - output "move[type] R1,R2" instruction*/
|
|
269 outmovr(r1,r2,tp)
|
|
270 int r1;
|
|
271 int r2;
|
|
272 struct tnode *tp;
|
|
273 {
|
|
274 if( r1 != r2 )
|
|
275 outrr("move",r1,r2,tp);
|
|
276 }
|
|
277
|
|
278 /* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
|
|
279 outcmpm(tp)
|
|
280 struct tnode *tp;
|
|
281 {
|
|
282 printf("cmpm");
|
|
283 outtype(tp->t_left->t_type);
|
|
284 printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
|
|
285 }
|
|
286
|
|
287 /* outcreg - output reference to compiler temp register*/
|
|
288 outcreg(reg)
|
|
289 int reg;
|
|
290 {
|
|
291 if( (dreg(reg)) > HICREG )
|
|
292 error("expression too complex");
|
|
293 printf("R%d",reg);
|
|
294 }
|
|
295
|
|
1File: UTIL.C Page 6
|
|
296 /* outcmp0 - output a compare with 0, special for address register*/
|
|
297 outcmp0(reg,tp)
|
|
298 int reg;
|
|
299 struct tnode *tp;
|
|
300 {
|
|
301 if( isareg(reg) ) {
|
|
302 printf("cmp");
|
|
303 outatype(tp->t_type);
|
|
304 printf(" #0,R%d\n",reg);
|
|
305 }
|
|
306 else {
|
|
307 printf("tst");
|
|
308 outtype(tp->t_type);
|
|
309 printf(" R%d\n",reg);
|
|
310 }
|
|
311 }
|
|
312
|
|
313 /* outrpush - output "move[type] R1,[-](sp)"*/
|
|
314 outrpush(reg,tp,pflag)
|
|
315 int reg;
|
|
316 struct tnode *tp;
|
|
317 int pflag;
|
|
318 {
|
|
319 printf("move");
|
|
320 outatype(tp->t_type);
|
|
321 printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
|
|
322 }
|
|
323
|
|
324 outdbra(reg,lab)
|
|
325 int reg;
|
|
326 int lab;
|
|
327 {
|
|
328 printf("dbra R%d,L%d\n",reg,lab);
|
|
329 }
|
|
330
|
|
331 /* cenalloc - code generator external node allocation*/
|
|
332 /* This may be coalesced into enalloc in parser.*/
|
|
333 char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
|
|
334 int type; /* type of symbol*/
|
|
335 int sc; /* storage class*/
|
|
336 char *sym; /* symbol name*/
|
|
337 {
|
|
338 register struct extnode *ep;
|
|
339
|
|
340 ep = talloc(sizeof(*ep));
|
|
341 ep->t_op = SYMBOL;
|
|
342 ep->t_type = type;
|
|
343 ep->t_sc = sc;
|
|
344 ep->t_su = 0;
|
|
345 ep->t_offset = 0;
|
|
346 symcopy(sym,ep->t_symbol);
|
|
347 return(ep);
|
|
348 }
|
|
349
|
|
350 /*popstack - clear off the stack after a call if necessary */
|
|
351 popstack(nb)
|
|
352 {
|
|
353 if (nb > 0 && nb <= 8)
|
|
354 printf("addq.l #%d,sp\n",nb);
|
|
1File: UTIL.C Page 7
|
|
355 else if (nb > 0)
|
|
356 printf("adda.l #%d,sp\n",nb);
|
|
357 }
|