|
|
1.1 root 1: # include "mfile1"
2: extern int eprint();
3:
4: /* this file contains code which is dependent on the target machine */
5:
6: NODE *
7: cast( p, t ) register NODE *p; TWORD t; {
8: /* cast node p to type t */
9:
10: p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p );
11: p->left->op = FREE;
12: p->op = FREE;
13: return( p->right );
14: }
15:
16: NODE *
17: clocal(p) NODE *p; {
18:
19: /* this is called to do local transformations on
20: an expression tree preparitory to its being
21: written out in intermediate code.
22: */
23:
24: /* the major essential job is rewriting the
25: automatic variables and arguments in terms of
26: REG and OREG nodes */
27: /* conversion ops which are not necessary are also clobbered here */
28: /* in addition, any special features (such as rewriting
29: exclusive or) are easily handled here as well */
30:
31: register struct symtab *q;
32: register NODE *r;
33: register o;
34: register m, ml;
35:
36: switch( o = p->op ){
37:
38: case NAME:
39: if( p->rval < 0 ) { /* already processed; ignore... */
40: return(p);
41: }
42: q = &stab[p->rval];
43: switch( q->sclass ){
44:
45: case AUTO:
46: case PARAM:
47: /* fake up a structure reference */
48: r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
49: r->lval = 0;
50: r->rval = (q->sclass==AUTO?STKREG:ARGREG);
51: p = stref( block( STREF, r, p, 0, 0, 0 ) );
52: break;
53:
54: case ULABEL:
55: case LABEL:
56: case STATIC:
57: if( q->slevel == 0 ) break;
58: p->lval = 0;
59: p->rval = -q->offset;
60: break;
61:
62: case REGISTER:
63: p->op = REG;
64: p->lval = 0;
65: p->rval = q->offset;
66: break;
67:
68: }
69: break;
70:
71: case PCONV:
72: /* do pointer conversions for char and longs */
73: ml = p->left->type;
74: if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->left->op != ICON ) break;
75:
76: /* pointers all have the same representation; the type is inherited */
77:
78: inherit:
79: p->left->type = p->type;
80: p->left->cdim = p->cdim;
81: p->left->csiz = p->csiz;
82: p->op = FREE;
83: return( p->left );
84:
85: case SCONV:
86: m = (p->type == FLOAT || p->type == DOUBLE );
87: ml = (p->left->type == FLOAT || p->left->type == DOUBLE );
88: if( m != ml ) break;
89:
90: /* now, look for conversions downwards */
91:
92: m = p->type;
93: ml = p->left->type;
94: if( p->left->op == ICON ){ /* simulate the conversion here */
95: CONSZ val;
96: val = p->left->lval;
97: switch( m ){
98: case CHAR:
99: p->left->lval = (char) val;
100: break;
101: case UCHAR:
102: p->left->lval = val & 0XFF;
103: break;
104: case USHORT:
105: p->left->lval = val & 0XFFFFL;
106: break;
107: case SHORT:
108: p->left->lval = (short)val;
109: break;
110: case UNSIGNED:
111: p->left->lval = val & 0xFFFFFFFFL;
112: break;
113: case INT:
114: p->left->lval = (int)val;
115: break;
116: }
117: p->left->type = m;
118: }
119: else {
120: /* meaningful ones are conversion of int to char, int to short,
121: and short to char, and unsigned version of them */
122: if( m==CHAR || m==UCHAR ){
123: if( ml!=CHAR && ml!= UCHAR ) break;
124: }
125: else if( m==SHORT || m==USHORT ){
126: if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break;
127: }
128: }
129:
130: /* clobber conversion */
131: if( tlen(p) == tlen(p->left) ) goto inherit;
132: p->op = FREE;
133: return( p->left ); /* conversion gets clobbered */
134:
135: case PVCONV:
136: case PMCONV:
137: if( p->right->op != ICON ) cerror( "bad conversion", 0);
138: p->op = FREE;
139: return( buildtree( o==PMCONV?MUL:DIV, p->left, p->right ) );
140:
141: case RS:
142: case ASG RS:
143: /* convert >> to << with negative shift count */
144: /* only if type of left operand is not unsigned */
145: if( ISUNSIGNED(p->left->type) ) break;
146: p->right = buildtree( UNARY MINUS, p->right, NIL );
147: if( p->op == RS ) p->op = LS;
148: else p->op = ASG LS;
149: break;
150:
151: case FLD:
152: if( p->left->op == UNARY MUL && (r=p->left->left)->op == PCONV)
153: if( r->left->op == PLUS || r->left->op == MINUS )
154: if( ISPTR(r->type) ) {
155: if( ISUNSIGNED(p->left->type) )
156: p->left->type = UCHAR;
157: else
158: p->left->type = CHAR;
159: }
160: break;
161: }
162:
163: return(p);
164: }
165:
166: andable( p ) NODE *p; {
167: return(1); /* all names can have & taken on them */
168: }
169:
170: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
171: autooff = AUTOINIT;
172: }
173:
174: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
175:
176: if( t==INT || t==UNSIGNED || t==LONG || t==ULONG /* tbl */
177: || t==CHAR || t==UCHAR || t==SHORT || t==USHORT /* tbl */
178: || t==FLOAT || t==DOUBLE || ISPTR(t)) return(1); /* tbl */
179: return(0);
180: }
181:
182: NODE *
183: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
184:
185: /* return a node, for structure references, which is suitable for
186: being added to a pointer of type t, in order to be off bits offset
187: into a structure */
188:
189: register NODE *p;
190:
191: /* t, d, and s are the type, dimension offset, and sizeoffset */
192: /* in general they are necessary for offcon, but not on H'well */
193:
194: p = bcon(0);
195: p->lval = off/SZCHAR;
196: return(p);
197:
198: }
199:
200:
201: static inwd /* current bit offsed in word */;
202: static word /* word being built from fields */;
203:
204: incode( p, sz ) register NODE *p; {
205:
206: /* generate initialization code for assigning a constant c
207: to a field of width sz */
208: /* we assume that the proper alignment has been obtained */
209: /* inoff is updated to have the proper final value */
210: /* we also assume sz < SZINT */
211:
212: if((sz+inwd) > SZINT) cerror("incode: field > int");
213: word |= ((unsigned)(p->lval<<(32-sz))) >> (32-sz-inwd);
214: inwd += sz;
215: inoff += sz;
216: if(inoff%SZINT == 0) {
217: printf( " .long 0x%x\n", word);
218: word = inwd = 0;
219: }
220: }
221:
222: fincode( d, sz ) double d; {
223: /* output code to initialize space of size sz to the value d */
224: /* the proper alignment has been obtained */
225: /* inoff is updated to have the proper final value */
226: /* on the target machine, write it out in octal! */
227:
228:
229: printf(" %s 0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float",
230: sz == SZDOUBLE ? 'd' : 'f', d);
231: inoff += sz;
232: }
233:
234: cinit( p, sz ) NODE *p; {
235: /* arrange for the initialization of p into a space of
236: size sz */
237: /* the proper alignment has been opbtained */
238: /* inoff is updated to have the proper final value */
239: ecode( p );
240: inoff += sz;
241: }
242:
243: vfdzero( n ){ /* define n bits of zeros in a vfd */
244:
245: if( n <= 0 ) return;
246:
247: inwd += n;
248: inoff += n;
249: if( inoff%ALINT ==0 ) {
250: printf( " .long 0x%x\n", word );
251: word = inwd = 0;
252: }
253: }
254:
255: char *
256: exname( p ) char *p; {
257: /* make a name look like an external name in the local machine */
258:
259: static char text[NCHNAM+1];
260:
261: register i;
262:
263: text[0] = '_';
264: for( i=1; *p&&i<NCHNAM; ++i ){
265: text[i] = *p++;
266: }
267:
268: text[i] = '\0';
269: text[NCHNAM] = '\0'; /* truncate */
270:
271: return( text );
272: }
273:
274: ctype( type ){ /* map types which are not defined on the local machine */
275: switch( BTYPE(type) ){
276:
277: case LONG:
278: MODTYPE(type,INT);
279: break;
280:
281: case ULONG:
282: MODTYPE(type,UNSIGNED);
283: }
284: return( type );
285: }
286:
287: noinit( t ) { /* curid is a variable which is defined but
288: is not initialized (and not a function );
289: This routine returns the stroage class for an uninitialized declaration */
290:
291: return(EXTERN);
292:
293: }
294:
295: commdec( id ){ /* make a common declaration for id, if reasonable */
296: register struct symtab *q;
297: OFFSZ off, tsize();
298:
299: q = &stab[id];
300: printf( " .comm %s,", exname( q->sname ) );
301: off = tsize( q->stype, q->dimoff, q->sizoff );
302: printf( CONFMT, off/SZCHAR );
303: printf( "\n" );
304: }
305:
306: isitlong( cb, ce ){ /* is lastcon to be long or short */
307: /* cb is the first character of the representation, ce the last */
308:
309: if( ce == 'l' || ce == 'L' ||
310: lastcon >= (1L << (SZINT-1) ) ) return (1);
311: return(0);
312: }
313:
314:
315: isitfloat( s ) char *s; {
316: double atof();
317: dcon = atof(s);
318: return( FCON );
319: }
320:
321: ecode( p ) NODE *p; {
322:
323: /* walk the tree and write out the nodes.. */
324:
325: if( nerrors ) return;
326: p2tree( p );
327: p2compile( p );
328: }
329:
330: #include "a.out.h"
331: int ddebug;
332: int gdebug;
333:
334:
335: outstab(p)
336: struct symtab *p; {
337: register TWORD ptype;
338: register char *pname;
339: register char pclass;
340: register int poffset;
341:
342: if (!gdebug) return;
343:
344: ptype = p->stype;
345: pname = p->sname;
346: pclass = p->sclass;
347: poffset = p->offset;
348:
349: if (ISFTN(ptype)) {
350: return;
351: }
352:
353: switch (pclass) {
354:
355: case AUTO:
356: pstab(pname, N_LSYM);
357: printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR);
358: poffs(p);
359: return;
360:
361: case EXTDEF:
362: case EXTERN:
363: pstab(pname, N_GSYM);
364: printf("0,%d,0\n", ptype);
365: poffs(p);
366: return;
367:
368: case STATIC:
369: pstab(pname, N_STSYM);
370: if (p->slevel > 1) {
371: printf("0,%d,L%d\n", ptype, poffset);
372: } else {
373: printf("0,%d,%s\n", ptype, exname(pname));
374: }
375: poffs(p);
376: return;
377:
378: case REGISTER:
379: pstab(pname, N_RSYM);
380: printf("0,%d,%d\n", ptype, poffset);
381: poffs(p);
382: return;
383:
384: case MOS:
385: case MOU:
386: pstab(pname, N_SSYM);
387: printf("0,%d,%d\n", ptype, poffset/SZCHAR);
388: poffs(p);
389: return;
390:
391: case PARAM:
392: /* parameter stab entries are processed in dclargs() */
393: return;
394:
395: default:
396: if (ddebug) printf(" No .stab for %.8s\n", pname);
397: }
398: }
399:
400: pstab(name, type)
401: char *name;
402: int type;
403: {
404: register int i;
405: register char c;
406: if (!gdebug) return;
407: #ifdef ASSTRINGS
408: if ( name[0] == '\0')
409: printf("\t.stabn\t");
410: else
411: printf("\t.stabs\t\"%.8s\", ", name);
412: #else
413:
414: printf(" .stab ");
415: for(i=0; i<8; i++)
416: if (c = name[i]) printf("'%c,", c);
417: else printf("0,");
418: #endif
419: printf("0%o,", type);
420: }
421:
422: #ifdef STABDOT
423: pstabdot(type, value)
424: int type;
425: int value;
426: {
427: if ( ! gdebug) return;
428: printf("\t.stabd\t");
429: printf("0%o,0,0%o\n",type, value);
430: }
431: #endif
432:
433: poffs(p)
434: register struct symtab *p; {
435: int s;
436: if (!gdebug) return;
437: if ((s = dimtab[p->sizoff]/SZCHAR) > 1) {
438: pstab(p->sname, N_LENG);
439: printf("1,0,%d\n", s);
440: }
441: }
442:
443: char NULLNAME[8];
444: int labelno;
445: int fdefflag;
446:
447: psline() {
448: static int lastlineno;
449: register char *cp, *cq;
450: register int i;
451:
452: if (!gdebug) return;
453:
454: cq = ititle;
455: cp = ftitle;
456:
457: while ( *cq ) if ( *cp++ != *cq++ ) goto neq;
458: if ( *cp == '\0' ) goto eq;
459:
460: neq: for (i=0; i<100; i++)
461: ititle[i] = '\0';
462: cp = ftitle;
463: cq = ititle;
464: while ( *cp )
465: *cq++ = *cp++;
466: *cq = '\0';
467: *--cq = '\0';
468: for ( cp = ititle+1; *(cp-1); cp += 8 ) {
469: /*
470: * We use the old style stab to introduce the
471: * name of the file. This is the only place
472: * where we could use a stab, with the last
473: * expression the '.', but this is also the only
474: * place where the first argument to the stab is
475: * a string (namely the name of the file).
476: */
477: pstab(cp, N_SOL);
478: if (gdebug) printf("0,0,LL%d\n", labelno);
479: }
480: *cq = '"';
481: printf("LL%d:\n", labelno++);
482:
483: eq: if (lineno == lastlineno) return;
484: lastlineno = lineno;
485:
486: if (fdefflag) {
487: #ifdef STABDOT
488: pstabdot(N_SLINE, lineno);
489: #else
490: pstab(NULLNAME, N_SLINE);
491: printf("0,%d,LL%d\n", lineno, labelno);
492: printf("LL%d:\n", labelno++);
493: #endif
494: }
495: }
496:
497: plcstab(level) {
498: if (!gdebug) return;
499: #ifdef STABDOT
500: pstabdot(N_LBRAC, level);
501: #else
502: pstab(NULLNAME, N_LBRAC);
503: printf("0,%d,LL%d\n", level, labelno);
504: printf("LL%d:\n", labelno++);
505: #endif
506: }
507:
508: prcstab(level) {
509: if (!gdebug) return;
510: #ifdef STABDOT
511: pstabdot(N_RBRAC, level);
512: #else
513: pstab(NULLNAME, N_RBRAC);
514: printf("0,%d,LL%d\n", level, labelno);
515: printf("LL%d:\n", labelno++);
516: #endif
517: }
518:
519: pfstab(sname)
520: char *sname; {
521: if (!gdebug) return;
522: pstab(sname, N_FUN);
523: printf("0,%d,_%.7s\n", lineno, sname);
524: }
525:
526: #ifndef ONEPASS
527: tlen(p) NODE *p;
528: {
529: switch(p->type) {
530: case CHAR:
531: case UCHAR:
532: return(1);
533:
534: case SHORT:
535: case USHORT:
536: return(2);
537:
538: case DOUBLE:
539: return(8);
540:
541: default:
542: return(4);
543: }
544: }
545: #endif
546:
547:
548:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.