|
|
1.1 root 1: # include "mfile1"
2:
3: /* this file contains code which is dependent on the target machine */
4:
5: NODE *
6: clocal(p) NODE *p; {
7:
8: /* this is called to do local transformations on
9: an expression tree preparitory to its being
10: written out in intermediate code.
11: */
12:
13: /* the major essential job is rewriting the
14: automatic variables and arguments in terms of
15: REG and OREG nodes */
16: /* conversion ops which are not necessary are also clobbered here */
17: /* in addition, any special features (such as rewriting
18: exclusive or) are easily handled here as well */
19:
20: register struct symtab *q;
21: register NODE *r;
22: register o;
23: register m, ml;
24:
25: switch( o = p->in.op ){
26:
27: case NAME:
28: if( p->tn.rval < 0 ) { /* already processed; ignore... */
29: return(p);
30: }
31: q = &stab[p->tn.rval];
32: switch( q->sclass ){
33:
34: case AUTO:
35: case PARAM:
36: /* fake up a structure reference */
37: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
38: r->tn.lval = 0;
39: r->tn.rval = STKREG;
40: p = stref( block( STREF, r, p, 0, 0, 0 ) );
41: break;
42:
43: case ULABEL:
44: case LABEL:
45: case STATIC:
46: if( q->slevel == 0 ) break;
47: p->tn.lval = 0;
48: p->tn.rval = -q->offset;
49: break;
50:
51: case REGISTER:
52: p->in.op = REG;
53: p->tn.lval = 0;
54: p->tn.rval = q->offset;
55: #ifdef REG_CHAR
56: m = p->in.type;
57: if( m==CHAR || m==SHORT )
58: p->in.type = INT;
59: else if( m==UCHAR || m==USHORT )
60: p->in.type = UNSIGNED;
61: #endif
62: break;
63:
64: }
65: break;
66:
67: case LT:
68: case LE:
69: case GT:
70: case GE:
71: if( ISPTR( p->in.left->in.type ) || ISPTR( p->in.right->in.type ) ){
72: p->in.op += (ULT-LT);
73: }
74: break;
75:
76: case PCONV:
77: /* do pointer conversions for char and longs */
78: ml = p->in.left->in.type;
79: if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break;
80:
81: /* pointers all have the same representation; the type is inherited */
82:
83: inherit:
84: p->in.left->in.type = p->in.type;
85: p->in.left->fn.cdim = p->fn.cdim;
86: p->in.left->fn.csiz = p->fn.csiz;
87: p->in.op = FREE;
88: return( p->in.left );
89:
90: case SCONV:
91: m = (p->in.type == FLOAT || p->in.type == DOUBLE );
92: ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE );
93: if( m != ml ) break;
94:
95: /* now, look for conversions downwards */
96:
97: m = p->in.type;
98: ml = p->in.left->in.type;
99: if( p->in.left->in.op == ICON ){ /* simulate the conversion here */
100: CONSZ val;
101: val = p->in.left->tn.lval;
102: switch( m ){
103: case CHAR:
104: p->in.left->tn.lval = (char) val;
105: break;
106: case UCHAR:
107: p->in.left->tn.lval = val & 0XFF;
108: break;
109: case USHORT:
110: p->in.left->tn.lval = val & 0XFFFFL;
111: break;
112: case SHORT:
113: p->in.left->tn.lval = (short)val;
114: break;
115: case UNSIGNED:
116: p->in.left->tn.lval = val & 0xFFFFFFFFL;
117: break;
118: case INT:
119: p->in.left->tn.lval = (int)val;
120: break;
121: }
122: p->in.left->in.type = m;
123: }
124: else {
125: /* meaningful ones are conversion of int to char, int to short,
126: and short to char, and unsigned versions thereof */
127: if( m==CHAR || m==UCHAR ){
128: if( ml!=CHAR && ml!= UCHAR ) break;
129: }
130: else if( m==SHORT || m==USHORT ){
131: if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break;
132: }
133: }
134:
135: /* clobber conversion */
136: if( tlen(p) == tlen(p->in.left) ) goto inherit;
137: p->in.op = FREE;
138: return( p->in.left ); /* conversion gets clobbered */
139:
140: case PVCONV:
141: case PMCONV:
142: if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
143: p->in.op = FREE;
144: return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
145:
146: case FLD:
147: /* make sure that the second pass does not make the
148: descendant of a FLD operator into a doubly indexed OREG */
149:
150: if( p->in.left->in.op == UNARY MUL
151: && (r=p->in.left->in.left)->in.op == PCONV)
152: if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS )
153: if( ISPTR(r->in.type) ) {
154: if( ISUNSIGNED(p->in.left->in.type) )
155: p->in.left->in.type = UNSIGNED;
156: else
157: p->in.left->in.type = INT;
158: }
159: break;
160: }
161:
162: return(p);
163: }
164:
165: andable( p ) NODE *p; {
166: return(1); /* all names can have & taken on them */
167: }
168:
169: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
170: autooff = AUTOINIT;
171: }
172:
173: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
174:
175: if( t==INT || t==UNSIGNED || t==LONG || t==ULONG /* tbl */
176: #ifdef REG_CHAR
177: || t==CHAR || t==UCHAR || t==SHORT || t==USHORT /* tbl */
178: #endif
179: || ISPTR(t)) return (1); /* wnj */
180: return(0);
181: }
182:
183: NODE *
184: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
185:
186: /* return a node, for structure references, which is suitable for
187: being added to a pointer of type t, in order to be off bits offset
188: into a structure */
189:
190: register NODE *p;
191:
192: /* t, d, and s are the type, dimension offset, and sizeoffset */
193: /* in general they are necessary for offcon, but not on H'well */
194:
195: p = bcon(0);
196: p->tn.lval = off/SZCHAR;
197: return(p);
198:
199: }
200:
201:
202: static inwd /* current bit offsed in word */;
203: static CONSZ word /* word being built from fields */;
204:
205: incode( p, sz ) register NODE *p; {
206:
207: /* generate initialization code for assigning a constant c
208: to a field of width sz */
209: /* we assume that the proper alignment has been obtained */
210: /* inoff is updated to have the proper final value */
211: /* we also assume sz < SZINT */
212:
213: inwd += sz;
214: if(inwd > SZINT) cerror("incode: field > int");
215: word |= (p->tn.lval&((1L<<sz)-1)) << (SZINT-inwd);
216: inoff += sz;
217: if(inoff%SZINT == 0) {
218: printf( " .long 0x%08X\n", word);
219: word = inwd = 0;
220: }
221: }
222:
223: fincode( d, sz ) double d; register sz; {
224: /* output code to initialize space of size sz to the value d */
225: /* the proper alignment has been obtained */
226: /* inoff is updated to have the proper final value */
227: /* this code should be the same for PDP, VAX and Tahoe */
228:
229: register struct sh4 {
230: unsigned short sh[4];
231: } *x;
232: # ifdef SFCON
233: register type;
234: # endif
235:
236: x = (struct sh4 *)&d;
237: printf(" .long 0x%04x%04x", x->sh[0], x->sh[1]);
238: # ifdef SFCON
239: if(sz==0)
240: if(x->sh[2]==0 && x->sh[3]==0) {
241: sz = SZFLOAT;
242: type = FLOAT;
243: } else {
244: sz = SZDOUBLE;
245: type = DOUBLE;
246: }
247: # endif
248: if(sz == SZDOUBLE) {
249: printf(", 0x%04x%04x", x->sh[2], x->sh[3]);
250: printf(" # .double");
251: } else
252: printf(" # .float");
253: printf(" %.20g\n", d);
254: inoff += sz;
255: # ifdef SFCON
256: return type;
257: # endif
258: }
259:
260: cinit( p, sz ) NODE *p; {
261: /* arrange for the initialization of p into a space of
262: size sz */
263: /* the proper alignment has been opbtained */
264: /* inoff is updated to have the proper final value */
265: ecode( p );
266: inoff += sz;
267: }
268:
269: vfdzero( n ){ /* define n bits of zeros in a vfd */
270:
271: if( n <= 0 ) return;
272:
273: inwd += n;
274: inoff += n;
275: if( inoff%ALINT ==0 ) {
276: printf( " .long 0x%08X\n", word );
277: word = inwd = 0;
278: }
279: }
280:
281: char *
282: exname( p ) char *p; {
283: /* make a name look like an external name in the local machine */
284:
285: #ifndef FLEXNAMES
286: static char text[NCHNAM+1];
287: #else
288: static char text[BUFSIZ+1];
289: #endif
290:
291: register i;
292:
293: text[0] = '_';
294: #ifndef FLEXNAMES
295: for( i=1; *p&&i<NCHNAM; ++i ){
296: #else
297: for( i=1; *p; ++i ){
298: #endif
299: text[i] = *p++;
300: }
301:
302: text[i] = '\0';
303: #ifndef FLEXNAMES
304: text[NCHNAM] = '\0'; /* truncate */
305: #endif
306:
307: return( text );
308: }
309:
310: ctype( type )TWORD type;{ /* map types which are not defined on the local machine */
311: switch( BTYPE(type) ){
312:
313: case LONG:
314: MODTYPE(type,INT);
315: break;
316:
317: case ULONG:
318: MODTYPE(type,UNSIGNED);
319: }
320: return( type );
321: }
322:
323: noinit() { /* curid is a variable which is defined but
324: is not initialized (and not a function );
325: This routine returns the stroage class for an uninitialized declaration */
326:
327: return(EXTERN);
328:
329: }
330:
331: commdec( id ){ /* make a common declaration for id, if reasonable */
332: register struct symtab *q;
333: OFFSZ off, tsize();
334:
335: q = &stab[id];
336: printf( " .comm %s,", exname( q->sname ) );
337: off = tsize( q->stype, q->dimoff, q->sizoff );
338: printf( "%d" /*CONFMT*/, off/SZCHAR );
339: printf( "\n" );
340: }
341:
342:
343: isitfloat( s ) char *s; {
344: double atof();
345: dcon = atof(s);
346: return( FCON );
347: }
348:
349: ecode( p ) NODE *p; {
350:
351: /* walk the tree and write out the nodes.. */
352:
353: if( nerrors ) return;
354: p2tree( p );
355: p2compile( p );
356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.