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