Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/c168/util.lis
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

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 }