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