|
|
1.1 root 1: # include "cpass1.h"
2: #ifndef lint
3: static char sccsid[] = "@(#)local.c 1.1 86/02/03 Copyr 1985 Sun Micro";
4: #endif
5:
6:
7: /*
8: * Copyright (c) 1985 by Sun Microsystems, Inc.
9: */
10:
11:
12: /*
13: * local.68 -- sym linked from local.c -- 68000 version
14: */
15:
16: /* this file contains code which is dependent on the target machine */
17:
18: NODE *
19: cast( p, t ) register NODE *p; TWORD t;
20: {
21: /* cast node p to type t */
22:
23: p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p );
24: p->in.left->in.op = FREE;
25: p->in.op = FREE;
26: return( p->in.right );
27: }
28:
29: NODE *
30: clocal(p) NODE *p;
31: {
32:
33: /* this is called to do local transformations on
34: an expression tree preparitory to its being
35: written out in intermediate code.
36: */
37:
38: /* the major essential job is rewriting the
39: automatic variables and arguments in terms of
40: REG and OREG nodes */
41: /* conversion ops which are not necessary are also clobbered here */
42: /* in addition, any special features (such as rewriting
43: exclusive or) are easily handled here as well */
44:
45: register struct symtab *q;
46: register NODE *r;
47: register o;
48: register m, ml;
49: int fldsize, fldoff;
50: TWORD fldtype;
51:
52: switch( o = p->in.op ){
53:
54: case NAME:
55: if( p->tn.rval<0 || p->tn.rval==NONAME ) { /* already processed; ignore... */
56: return(p);
57: }
58: if (BTYPE(p->in.type) == TERROR)
59: return(p);
60: q = STP(p->tn.rval);
61: switch( q->sclass ){
62:
63: case AUTO:
64: case PARAM:
65: /* fake up a structure reference */
66: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
67: r->tn.lval = 0;
68: r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG);
69: p = stref( block( STREF, r, p, 0, 0, 0 ) );
70: break;
71:
72: case ULABEL:
73: case LABEL:
74: case STATIC:
75: if( q->slevel == 0 ) break;
76: p->tn.lval = 0;
77: p->tn.rval = -q->offset;
78: break;
79:
80: case REGISTER:
81: p->in.op = REG;
82: p->tn.lval = 0;
83: p->tn.rval = q->offset;
84: break;
85:
86: }
87: break;
88:
89: case PCONV:
90: /* do pointer conversions for char and short */
91: ml = p->in.left->in.type;
92: if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ){
93: p->in.op = SCONV;
94: break;
95: }
96:
97: /* pointers all have the same representation; the type is inherited */
98:
99: inherit:
100: p->in.left->in.type = p->in.type;
101: p->in.left->fn.cdim = p->fn.cdim;
102: p->in.left->fn.csiz = p->fn.csiz;
103: p->in.op = FREE;
104: return( p->in.left );
105:
106: case SCONV:
107: /* now, look for conversions downwards */
108:
109: m = p->in.type;
110: ml = p->in.left->in.type;
111: if( p->in.left->in.op == ICON ){
112: /* simulate the conversion here */
113: CONSZ val;
114: if ((val=p->in.left->tn.rval) != NONAME
115: && dimtab[p->fn.csiz] < SZPOINT ){
116: /* a relocatable icon is being shortened */
117: /* DO NOT SHORTEN IT!! */
118: werror("shortening &%s may loose significance",
119: val<=0?"(constant)":STP(val)->sname);
120: break;
121: }
122: shorten_int:
123: val = p->in.left->tn.lval;
124: switch( m ){
125: case CHAR:
126: p->in.left->tn.lval = (char) val;
127: break;
128: case UCHAR:
129: p->in.left->tn.lval = val & 0XFF;
130: break;
131: case USHORT:
132: p->in.left->tn.lval = val & 0XFFFFL;
133: break;
134: case SHORT:
135: p->in.left->tn.lval = (short)val;
136: break;
137: case UNSIGNED:
138: p->in.left->tn.lval = val & 0xFFFFFFFFL;
139: break;
140: case INT:
141: p->in.left->tn.lval = (int)val;
142: break;
143: case DOUBLE:
144: case FLOAT:
145: p->in.left->fpn.dval = (double)val;
146: p->in.left->in.op = FCON;
147: break;
148: }
149: p->in.left->in.type = m;
150: } else if( p->in.left->in.op == FCON ){
151: /* simulate the conversion here */
152: if (m!=DOUBLE && m!=FLOAT){
153: /* conversion to int-like things */
154: /* convert to int first, then to actual thing */
155: p->in.left->tn.lval = (CONSZ)p->in.left->fpn.dval;
156: p->in.left->tn.rval = NONAME;
157: p->in.left->tn.name = (char*)0;
158: p->in.left->tn.op = ICON;
159: p->in.left->tn.type = INT;
160: if (m != INT)
161: goto shorten_int;
162: } else
163: p->in.left->in.type = m;
164: } else {
165: m = (m ==FLOAT || m ==DOUBLE);
166: ml = (ml==FLOAT || ml==DOUBLE);
167: if (m != ml ) break;
168: else if( tlen(p) == tlen(p->in.left) )
169: goto inherit;
170: else if (p->in.type != 0)
171: break;
172: /* fall through and clobber conversion to void */
173: }
174: p->in.op = FREE;
175: return( p->in.left ); /* conversion gets clobbered */
176:
177: case PVCONV:
178: case PMCONV:
179: if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
180: p->in.op = FREE;
181: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
182:
183: case CALL:
184: case UNARY CALL:
185: if (p->in.type == FLOAT)
186: #ifdef FLOATMATH
187: if (FLOATMATH<=1)
188: #endif
189: p->in.type = DOUBLE; /* no such thing as a float fn */
190: break;
191:
192: #ifdef FLOATMATH
193: case PLUS:
194: case MINUS:
195: case DIV:
196: case MUL:
197: case ASG PLUS:
198: case ASG MINUS:
199: case ASG DIV:
200: case ASG MUL:
201: if (!floatmath) break;
202: #endif FLOATMATH
203: case ASSIGN:
204: if (p->in.type == FLOAT && p->in.right->tn.op == FCON)
205: p->in.right->tn.type = p->in.right->fn.csiz = FLOAT;
206: break;
207:
208: case FORCE:
209: /* we do not FORCE little things. Ints or better only */
210: switch ( p->in.type ){
211: case CHAR:
212: case SHORT:
213: p->in.left = makety(p->in.left,INT,0,INT);
214: p->in.type = INT;
215: break;
216: case UCHAR:
217: case USHORT:
218: p->in.left = makety(p->in.left,UNSIGNED,0,UNSIGNED);
219: p->in.type = UNSIGNED;
220: break;
221: }
222: break;
223:
224:
225: } /* switch */
226:
227: return(p);
228: }
229:
230: andable( p ) NODE *p;
231: {
232: return(1); /* all names can have & taken on them */
233: }
234:
235: cendarg()
236: { /* at the end of the arguments of a ftn, set the automatic offset */
237: autooff = AUTOINIT;
238: }
239:
240: cisreg( t )
241: TWORD t;
242: {
243: /* is an automatic variable of type t OK for a register variable */
244: switch (t) {
245: case DOUBLE:
246: return( use68881 );
247: case FLOAT:
248: case INT:
249: case UNSIGNED:
250: case SHORT:
251: case USHORT:
252: case CHAR:
253: case UCHAR:
254: return(1);
255: default:
256: return( ISPTR(t) );
257: }
258: }
259:
260: NODE *
261: offcon( off, t, d, s ) OFFSZ off; TWORD t;
262: {
263:
264: /* return a node, for structure references, which is suitable for
265: being added to a pointer of type t, in order to be off bits offset
266: into a structure */
267:
268: register NODE *p;
269:
270: /* t, d, and s are the type, dimension offset, and sizeoffset */
271: /* in general they are necessary for offcon, but not on H'well */
272:
273: p = bcon(0);
274: p->tn.lval = off/SZCHAR;
275: return(p);
276:
277: }
278:
279:
280: static inwd; /* current bit offsed in word */
281: static word; /* word being built from fields */
282:
283: incode( p, sz ) register NODE *p;
284: {
285:
286: /* generate initialization code for assigning a constant c
287: to a field of width sz */
288: /* we assume that the proper alignment has been obtained */
289: /* inoff is updated to have the proper final value */
290: /* we also assume sz < SZINT */
291:
292: if((sz+inwd) > SZINT) cerror("incode: field > int");
293: word |= (p->tn.lval & ((1 << sz) -1)) << (SZINT - sz - inwd);
294: inwd += sz;
295: inoff += sz;
296: while (inwd >= 16) {
297: printf( " .word %ld\n", (word>>16)&0xFFFFL );
298: word <<= 16;
299: inwd -= 16;
300: }
301: }
302:
303: cinit( p, sz ) NODE *p;
304: {
305: /* arrange for the initialization of p into a space of
306: size sz */
307: /* the proper alignment has been opbtained */
308: /* inoff is updated to have the proper final value */
309: /*
310: as a favor (?) to people who want to write
311: int i = 9600/134.5;
312: we will, under the proper circumstances, do
313: a coersion here.
314: */
315: NODE *l;
316:
317: switch (p->in.type) {
318: case INT:
319: case UNSIGNED:
320: l = p->in.left;
321: if (l->in.op != SCONV || l->in.left->tn.op != FCON) break;
322: l->in.op = FREE;
323: l = l->in.left;
324: l->tn.lval = (long)(l->fpn.dval);
325: l->tn.rval = NONAME;
326: l->tn.op = ICON;
327: l->tn.type = INT;
328: p->in.left = l;
329: break;
330: }
331: ecode( p );
332: inoff += sz;
333: }
334:
335: vfdzero( n )
336: { /* define n bits of zeros in a vfd */
337:
338: if( n <= 0 ) return;
339:
340: inwd += n;
341: inoff += n;
342: while (inwd >= 16) {
343: printf( " .word %ld\n", (word>>16)&0xFFFFL );
344: word <<= 16;
345: inwd -= 16;
346: }
347: }
348:
349: char *
350: exname( p ) char *p;
351: {
352: /* make a name look like an external name in the local machine */
353:
354: #ifndef FLEXNAMES
355: static char text[NCHNAM+1];
356: #else
357: static char text[BUFSIZ+1];
358: #endif
359:
360: register i;
361:
362: text[0] = '_';
363: #ifndef FLEXNAMES
364: for( i=1; *p&&i<NCHNAM; ++i ){
365: #else
366: for( i=1; *p; ++i ){
367: #endif
368: text[i] = *p++;
369: }
370:
371: text[i] = '\0';
372: #ifndef FLEXNAMES
373: text[NCHNAM] = '\0'; /* truncate */
374: #endif
375:
376: return( text );
377: }
378:
379: ctype( type )
380: { /* map types which are not defined on the local machine */
381: switch( BTYPE(type) ){
382:
383: case LONG:
384: MODTYPE(type,INT);
385: break;
386:
387: case ULONG:
388: MODTYPE(type,UNSIGNED);
389: }
390: return( type );
391: }
392:
393: noinit( t )
394: { /* curid is a variable which is defined but
395: is not initialized (and not a function );
396: This routine returns the stroage class for an uninitialized declaration */
397:
398: return(EXTERN);
399:
400: }
401:
402: commdec( id )
403: { /* make a common declaration for id, if reasonable */
404: register struct symtab *q;
405: OFFSZ off, tsize();
406:
407: q = STP(id);
408: printf( " .comm %s,", exname( q->sname ) );
409: off = tsize( q->stype, q->dimoff, q->sizoff );
410: printf( CONFMT, off/SZCHAR );
411: printf( "\n" );
412: }
413:
414: isitlong( cb, ce )
415: { /* is lastcon to be long or short */
416: /* cb is the first character of the representation, ce the last */
417:
418: if( ce == 'l' || ce == 'L' ||
419: lastcon >= (1L << (SZINT-1) ) ) return (1);
420: return(0);
421: }
422:
423:
424: isitfloat( s ) char *s;
425: {
426: double atof();
427: dcon = atof(s);
428: return( FCON );
429: }
430:
431: ecode( p ) NODE *p; {
432:
433: /* walk the tree and write out the nodes.. */
434:
435: if( nerrors ) return;
436: p2tree( p );
437: p2compile( p );
438: }
439:
440: #ifndef ONEPASS
441: tlen(p) NODE *p;
442: {
443: switch(p->in.type) {
444: case CHAR:
445: case UCHAR:
446: return(1);
447:
448: case SHORT:
449: case USHORT:
450: return(2);
451:
452: case DOUBLE:
453: return(8);
454:
455: default:
456: return(4);
457: }
458: }
459: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.