1*16181Sralph static char *sccsid ="@(#)local2.c 1.2 (Berkeley) 03/14/84"; 29702Slinton # include "mfile2" 39702Slinton # include "ctype.h" 49702Slinton # ifdef FORT 59702Slinton int ftlab1, ftlab2; 69702Slinton # endif 79702Slinton /* a lot of the machine dependent parts of the second pass */ 89702Slinton 99702Slinton # define BITMASK(n) ((1L<<n)-1) 109702Slinton 119702Slinton where(c){ 129702Slinton fprintf( stderr, "%s, line %d: ", filename, lineno ); 139702Slinton } 149702Slinton 159702Slinton lineid( l, fn ) char *fn; { 169702Slinton /* identify line l and file fn */ 179702Slinton printf( "# line %d, file %s\n", l, fn ); 189702Slinton } 199702Slinton 209702Slinton 219702Slinton eobl2(){ 229702Slinton OFFSZ spoff; /* offset from stack pointer */ 239702Slinton #ifdef FORT 249702Slinton spoff = maxoff; 259702Slinton if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 269702Slinton spoff /= SZCHAR; 279702Slinton SETOFF(spoff,4); 289702Slinton #ifndef FLEXNAMES 299702Slinton printf( " .set .F%d,%ld\n", ftnno, spoff ); 309702Slinton #else 319702Slinton /* SHOULD BE L%d ... ftnno but must change pc/f77 */ 329702Slinton printf( " .set LF%d,%ld\n", ftnno, spoff ); 339702Slinton #endif 349702Slinton #else 359702Slinton extern int ftlab1, ftlab2; 369702Slinton 379702Slinton spoff = maxoff; 389702Slinton if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 399702Slinton spoff /= SZCHAR; 409702Slinton SETOFF(spoff,4); 419702Slinton printf( "L%d:\n", ftlab1); 429702Slinton if( spoff!=0 ) 439702Slinton if( spoff < 64 ) 449702Slinton printf( " subl2 $%ld,sp\n", spoff); 459702Slinton else 469702Slinton printf( " movab -%ld(sp),sp\n", spoff); 479702Slinton printf( " jbr L%d\n", ftlab2); 489702Slinton #endif 499702Slinton maxargs = -1; 509702Slinton } 519702Slinton 529702Slinton struct hoptab { int opmask; char * opstring; } ioptab[] = { 539702Slinton 549702Slinton ASG PLUS, "add", 559702Slinton ASG MINUS, "sub", 569702Slinton ASG MUL, "mul", 579702Slinton ASG DIV, "div", 589702Slinton ASG OR, "bis", 599702Slinton ASG ER, "xor", 609702Slinton ASG AND, "bic", 619702Slinton PLUS, "add", 629702Slinton MINUS, "sub", 639702Slinton MUL, "mul", 649702Slinton DIV, "div", 659702Slinton OR, "bis", 669702Slinton ER, "xor", 679702Slinton AND, "bic", 689702Slinton -1, "" }; 699702Slinton 709702Slinton hopcode( f, o ){ 719702Slinton /* output the appropriate string from the above table */ 729702Slinton 739702Slinton register struct hoptab *q; 749702Slinton 759702Slinton for( q = ioptab; q->opmask>=0; ++q ){ 769702Slinton if( q->opmask == o ){ 779702Slinton printf( "%s", q->opstring ); 789702Slinton /* tbl 799702Slinton if( f == 'F' ) printf( "e" ); 809702Slinton else if( f == 'D' ) printf( "d" ); 819702Slinton tbl */ 829702Slinton /* tbl */ 839702Slinton switch( f ) { 849702Slinton case 'L': 859702Slinton case 'W': 869702Slinton case 'B': 879702Slinton case 'D': 889702Slinton case 'F': 899702Slinton printf("%c", tolower(f)); 909702Slinton break; 919702Slinton 929702Slinton } 939702Slinton /* tbl */ 949702Slinton return; 959702Slinton } 969702Slinton } 979702Slinton cerror( "no hoptab for %s", opst[o] ); 989702Slinton } 999702Slinton 1009702Slinton char * 1019702Slinton rnames[] = { /* keyed to register number tokens */ 1029702Slinton 1039702Slinton "r0", "r1", 1049702Slinton "r2", "r3", "r4", "r5", 1059702Slinton "r6", "r7", "r8", "r9", "r10", "r11", 1069702Slinton "ap", "fp", "sp", "pc", 1079702Slinton 1089702Slinton }; 1099702Slinton 1109702Slinton int rstatus[] = { 1119702Slinton SAREG|STAREG, SAREG|STAREG, 1129702Slinton SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, 1139702Slinton SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, 1149702Slinton SAREG, SAREG, SAREG, SAREG, 1159702Slinton 1169702Slinton }; 1179702Slinton 1189702Slinton tlen(p) NODE *p; 1199702Slinton { 1209702Slinton switch(p->in.type) { 1219702Slinton case CHAR: 1229702Slinton case UCHAR: 1239702Slinton return(1); 1249702Slinton 1259702Slinton case SHORT: 1269702Slinton case USHORT: 1279702Slinton return(2); 1289702Slinton 1299702Slinton case DOUBLE: 1309702Slinton return(8); 1319702Slinton 1329702Slinton default: 1339702Slinton return(4); 1349702Slinton } 1359702Slinton } 1369702Slinton 1379702Slinton mixtypes(p, q) NODE *p, *q; 1389702Slinton { 139*16181Sralph register TWORD tp, tq; 1409702Slinton 1419702Slinton tp = p->in.type; 1429702Slinton tq = q->in.type; 1439702Slinton 1449702Slinton return( (tp==FLOAT || tp==DOUBLE) != 1459702Slinton (tq==FLOAT || tq==DOUBLE) ); 1469702Slinton } 1479702Slinton 1489702Slinton prtype(n) NODE *n; 1499702Slinton { 1509702Slinton switch (n->in.type) 1519702Slinton { 1529702Slinton case DOUBLE: 1539702Slinton printf("d"); 1549702Slinton return; 1559702Slinton 1569702Slinton case FLOAT: 1579702Slinton printf("f"); 1589702Slinton return; 1599702Slinton 1609702Slinton case LONG: 1619702Slinton case ULONG: 1629702Slinton case INT: 1639702Slinton case UNSIGNED: 1649702Slinton printf("l"); 1659702Slinton return; 1669702Slinton 1679702Slinton case SHORT: 1689702Slinton case USHORT: 1699702Slinton printf("w"); 1709702Slinton return; 1719702Slinton 1729702Slinton case CHAR: 1739702Slinton case UCHAR: 1749702Slinton printf("b"); 1759702Slinton return; 1769702Slinton 1779702Slinton default: 1789702Slinton if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type"); 1799702Slinton else { 1809702Slinton printf("l"); 1819702Slinton return; 1829702Slinton } 1839702Slinton } 1849702Slinton } 1859702Slinton 1869702Slinton zzzcode( p, c ) register NODE *p; { 1879702Slinton register m; 1889702Slinton CONSZ val; 1899702Slinton switch( c ){ 1909702Slinton 1919702Slinton case 'N': /* logical ops, turned into 0-1 */ 1929702Slinton /* use register given by register 1 */ 1939702Slinton cbgen( 0, m=getlab(), 'I' ); 1949702Slinton deflab( p->bn.label ); 1959702Slinton printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] ); 1969702Slinton deflab( m ); 1979702Slinton return; 1989702Slinton 1999702Slinton case 'I': 2009702Slinton case 'P': 2019702Slinton cbgen( p->in.op, p->bn.label, c ); 2029702Slinton return; 2039702Slinton 2049702Slinton case 'A': 2059702Slinton { 2069702Slinton register NODE *l, *r; 2079702Slinton 2089702Slinton if (xdebug) eprint(p, 0, &val, &val); 2099702Slinton r = getlr(p, 'R'); 210*16181Sralph if (p->in.op == ASSIGN) 211*16181Sralph l = getlr(p, 'L'); 212*16181Sralph else if (p->in.op == SCONV) 2139702Slinton { 2149702Slinton l = resc; 215*16181Sralph #ifdef FORT 216*16181Sralph l->in.type = r->in.type; 217*16181Sralph #else 218*16181Sralph l->in.type = r->in.type==FLOAT ? DOUBLE : r->in.type; 219*16181Sralph #endif 220*16181Sralph r = getlr(p, 'L'); 221*16181Sralph } 222*16181Sralph else 223*16181Sralph { /* OPLTYPE */ 224*16181Sralph l = resc; 225*16181Sralph #ifdef FORT 226*16181Sralph l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? r->in.type : INT); 227*16181Sralph #else 2289702Slinton l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); 229*16181Sralph #endif 2309702Slinton } 2319702Slinton if (r->in.op == ICON) 232*16181Sralph if (r->in.name[0] == '\0') 2339702Slinton { 2349702Slinton if (r->tn.lval == 0) 2359702Slinton { 2369702Slinton printf("clr"); 2379702Slinton prtype(l); 2389702Slinton printf(" "); 2399702Slinton adrput(l); 2409702Slinton return; 2419702Slinton } 2429702Slinton if (r->tn.lval < 0 && r->tn.lval >= -63) 2439702Slinton { 2449702Slinton printf("mneg"); 2459702Slinton prtype(l); 2469702Slinton r->tn.lval = -r->tn.lval; 2479702Slinton goto ops; 2489702Slinton } 2499702Slinton r->in.type = (r->tn.lval < 0 ? 2509702Slinton (r->tn.lval >= -128 ? CHAR 2519702Slinton : (r->tn.lval >= -32768 ? SHORT 2529702Slinton : INT )) : r->in.type); 2539702Slinton r->in.type = (r->tn.lval >= 0 ? 2549702Slinton (r->tn.lval <= 63 ? INT 2559702Slinton : ( r->tn.lval <= 127 ? CHAR 2569702Slinton : (r->tn.lval <= 255 ? UCHAR 2579702Slinton : (r->tn.lval <= 32767 ? SHORT 2589702Slinton : (r->tn.lval <= 65535 ? USHORT 2599702Slinton : INT ))))) : r->in.type ); 2609702Slinton } 261*16181Sralph else 262*16181Sralph { 263*16181Sralph printf("moval"); 264*16181Sralph printf(" "); 265*16181Sralph acon(r); 266*16181Sralph printf(","); 267*16181Sralph adrput(l); 268*16181Sralph return; 269*16181Sralph } 2709702Slinton 2719702Slinton if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) 2729702Slinton { 273*16181Sralph if (tlen(l) < tlen(r) && !mixtypes(l,r)) 2749702Slinton { 275*16181Sralph if (ISUNSIGNED(l->in.type)) 276*16181Sralph printf("movz"); 2779702Slinton else 2789702Slinton printf("cvt"); 279*16181Sralph prtype(l); 280*16181Sralph printf("l"); 281*16181Sralph goto ops; 2829702Slinton } 2839702Slinton else 284*16181Sralph l->in.type = INT; 2859702Slinton } 2869702Slinton if (!mixtypes(l,r)) 2879702Slinton { 2889702Slinton if (tlen(l) == tlen(r)) 2899702Slinton { 2909702Slinton printf("mov"); 2919702Slinton prtype(l); 2929702Slinton goto ops; 2939702Slinton } 2949702Slinton else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) 2959702Slinton { 2969702Slinton printf("movz"); 2979702Slinton } 2989702Slinton else 2999702Slinton { 3009702Slinton printf("cvt"); 3019702Slinton } 3029702Slinton } 3039702Slinton else 3049702Slinton { 3059702Slinton printf("cvt"); 3069702Slinton } 3079702Slinton prtype(r); 3089702Slinton prtype(l); 3099702Slinton ops: 3109702Slinton printf(" "); 3119702Slinton adrput(r); 3129702Slinton printf(","); 3139702Slinton adrput(l); 3149702Slinton return; 3159702Slinton } 3169702Slinton 3179702Slinton case 'B': /* get oreg value in temp register for left shift */ 3189702Slinton { 3199702Slinton register NODE *r; 3209702Slinton if (xdebug) eprint(p, 0, &val, &val); 3219702Slinton r = p->in.right; 3229702Slinton if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) 3239702Slinton printf("movl"); 3249702Slinton else { 3259702Slinton printf("cvt"); 3269702Slinton prtype(r); 3279702Slinton printf("l"); 3289702Slinton } 3299702Slinton return; 3309702Slinton } 3319702Slinton 3329702Slinton case 'C': /* num words pushed on arg stack */ 3339702Slinton { 3349702Slinton extern int gc_numbytes; 3359702Slinton extern int xdebug; 3369702Slinton 3379702Slinton if (xdebug) printf("->%d<-",gc_numbytes); 3389702Slinton 3399702Slinton printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); 3409702Slinton return; 3419702Slinton } 3429702Slinton 3439702Slinton case 'D': /* INCR and DECR */ 3449702Slinton zzzcode(p->in.left, 'A'); 3459702Slinton printf("\n "); 3469702Slinton 3479702Slinton case 'E': /* INCR and DECR, FOREFF */ 3489702Slinton if (p->in.right->tn.lval == 1) 3499702Slinton { 3509702Slinton printf("%s", (p->in.op == INCR ? "inc" : "dec") ); 3519702Slinton prtype(p->in.left); 3529702Slinton printf(" "); 3539702Slinton adrput(p->in.left); 3549702Slinton return; 3559702Slinton } 3569702Slinton printf("%s", (p->in.op == INCR ? "add" : "sub") ); 3579702Slinton prtype(p->in.left); 3589702Slinton printf("2 "); 3599702Slinton adrput(p->in.right); 3609702Slinton printf(","); 3619702Slinton adrput(p->in.left); 3629702Slinton return; 3639702Slinton 3649702Slinton case 'F': /* register type of right operand */ 3659702Slinton { 3669702Slinton register NODE *n; 3679702Slinton extern int xdebug; 3689702Slinton register int ty; 3699702Slinton 3709702Slinton n = getlr( p, 'R' ); 3719702Slinton ty = n->in.type; 3729702Slinton 3739702Slinton if (xdebug) printf("->%d<-", ty); 3749702Slinton 3759702Slinton if ( ty==DOUBLE) printf("d"); 3769702Slinton else if ( ty==FLOAT ) printf("f"); 3779702Slinton else printf("l"); 3789702Slinton return; 3799702Slinton } 3809702Slinton 3819702Slinton case 'L': /* type of left operand */ 3829702Slinton case 'R': /* type of right operand */ 3839702Slinton { 3849702Slinton register NODE *n; 3859702Slinton extern int xdebug; 3869702Slinton 387*16181Sralph n = getlr( p, c ); 3889702Slinton if (xdebug) printf("->%d<-", n->in.type); 3899702Slinton 3909702Slinton prtype(n); 3919702Slinton return; 3929702Slinton } 3939702Slinton 3949702Slinton case 'Z': /* complement mask for bit instr */ 3959702Slinton printf("$%ld", ~p->in.right->tn.lval); 3969702Slinton return; 3979702Slinton 3989702Slinton case 'U': /* 32 - n, for unsigned right shifts */ 3999702Slinton printf("$%d", 32 - p->in.right->tn.lval ); 4009702Slinton return; 4019702Slinton 4029702Slinton case 'T': /* rounded structure length for arguments */ 4039702Slinton { 4049702Slinton int size; 4059702Slinton 4069702Slinton size = p->stn.stsize; 4079702Slinton SETOFF( size, 4); 4089702Slinton printf("$%d", size); 4099702Slinton return; 4109702Slinton } 4119702Slinton 4129702Slinton case 'S': /* structure assignment */ 4139702Slinton { 4149702Slinton register NODE *l, *r; 4159702Slinton register size; 4169702Slinton 4179702Slinton if( p->in.op == STASG ){ 4189702Slinton l = p->in.left; 4199702Slinton r = p->in.right; 4209702Slinton 4219702Slinton } 4229702Slinton else if( p->in.op == STARG ){ /* store an arg into a temporary */ 4239702Slinton l = getlr( p, '3' ); 4249702Slinton r = p->in.left; 4259702Slinton } 4269702Slinton else cerror( "STASG bad" ); 4279702Slinton 4289702Slinton if( r->in.op == ICON ) r->in.op = NAME; 4299702Slinton else if( r->in.op == REG ) r->in.op = OREG; 4309702Slinton else if( r->in.op != OREG ) cerror( "STASG-r" ); 4319702Slinton 4329702Slinton size = p->stn.stsize; 4339702Slinton 4349702Slinton if( size <= 0 || size > 65535 ) 4359702Slinton cerror("structure size <0=0 or >65535"); 4369702Slinton 4379702Slinton switch(size) { 4389702Slinton case 1: 4399702Slinton printf(" movb "); 4409702Slinton break; 4419702Slinton case 2: 4429702Slinton printf(" movw "); 4439702Slinton break; 4449702Slinton case 4: 4459702Slinton printf(" movl "); 4469702Slinton break; 4479702Slinton case 8: 4489702Slinton printf(" movq "); 4499702Slinton break; 4509702Slinton default: 4519702Slinton printf(" movc3 $%d,", size); 4529702Slinton break; 4539702Slinton } 4549702Slinton adrput(r); 4559702Slinton printf(","); 4569702Slinton adrput(l); 4579702Slinton printf("\n"); 4589702Slinton 4599702Slinton if( r->in.op == NAME ) r->in.op = ICON; 4609702Slinton else if( r->in.op == OREG ) r->in.op = REG; 4619702Slinton 4629702Slinton } 4639702Slinton break; 4649702Slinton 4659702Slinton default: 4669702Slinton cerror( "illegal zzzcode" ); 4679702Slinton } 4689702Slinton } 4699702Slinton 4709702Slinton rmove( rt, rs, t ){ 4719702Slinton printf( " %s %s,%s\n", 4729702Slinton (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), 4739702Slinton rnames[rs], rnames[rt] ); 4749702Slinton } 4759702Slinton 4769702Slinton struct respref 4779702Slinton respref[] = { 4789702Slinton INTAREG|INTBREG, INTAREG|INTBREG, 4799702Slinton INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, 4809702Slinton INTEMP, INTEMP, 4819702Slinton FORARG, FORARG, 4829702Slinton INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 4839702Slinton 0, 0 }; 4849702Slinton 4859702Slinton setregs(){ /* set up temporary registers */ 4869702Slinton fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ 4879702Slinton ; 4889702Slinton } 4899702Slinton 4909702Slinton szty(t){ /* size, in registers, needed to hold thing of type t */ 491*16181Sralph #ifdef FORT 492*16181Sralph return( (t==DOUBLE) ? 2 : 1 ); 493*16181Sralph #else 4949702Slinton return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); 495*16181Sralph #endif 4969702Slinton } 4979702Slinton 4989702Slinton rewfld( p ) NODE *p; { 4999702Slinton return(1); 5009702Slinton } 5019702Slinton 5029702Slinton callreg(p) NODE *p; { 5039702Slinton return( R0 ); 5049702Slinton } 5059702Slinton 5069702Slinton base( p ) register NODE *p; { 5079702Slinton register int o = p->in.op; 5089702Slinton 5099702Slinton if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ 5109702Slinton if( o==REG ) return( p->tn.rval ); 5119702Slinton if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) 5129702Slinton return( p->in.left->tn.rval ); 5139702Slinton if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5149702Slinton return( p->tn.rval + 0200*1 ); 5159702Slinton if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); 5169702Slinton if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); 5179702Slinton if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG 5189702Slinton && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5199702Slinton return( p->in.left->in.left->tn.rval + 0200*(1+2) ); 5209702Slinton return( -1 ); 5219702Slinton } 5229702Slinton 5239702Slinton offset( p, tyl ) register NODE *p; int tyl; { 5249702Slinton 5259702Slinton if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); 5269702Slinton if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && 5279702Slinton (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') 5289702Slinton && (1<<p->in.right->tn.lval)==tyl)) 5299702Slinton return( p->in.left->tn.rval ); 5309702Slinton return( -1 ); 5319702Slinton } 5329702Slinton 5339702Slinton makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { 5349702Slinton register NODE *t; 5359702Slinton register int i; 5369702Slinton NODE *f; 5379702Slinton 5389702Slinton p->in.op = OREG; 5399702Slinton f = p->in.left; /* have to free this subtree later */ 5409702Slinton 5419702Slinton /* init base */ 5429702Slinton switch (q->in.op) { 5439702Slinton case ICON: 5449702Slinton case REG: 5459702Slinton case OREG: 5469702Slinton t = q; 5479702Slinton break; 5489702Slinton 5499702Slinton case MINUS: 5509702Slinton q->in.right->tn.lval = -q->in.right->tn.lval; 5519702Slinton case PLUS: 5529702Slinton t = q->in.right; 5539702Slinton break; 5549702Slinton 5559702Slinton case INCR: 5569702Slinton case ASG MINUS: 5579702Slinton t = q->in.left; 5589702Slinton break; 5599702Slinton 5609702Slinton case UNARY MUL: 5619702Slinton t = q->in.left->in.left; 5629702Slinton break; 5639702Slinton 5649702Slinton default: 5659702Slinton cerror("illegal makeor2"); 5669702Slinton } 5679702Slinton 5689702Slinton p->tn.lval = t->tn.lval; 5699702Slinton #ifndef FLEXNAMES 5709702Slinton for(i=0; i<NCHNAM; ++i) 5719702Slinton p->in.name[i] = t->in.name[i]; 5729702Slinton #else 5739702Slinton p->in.name = t->in.name; 5749702Slinton #endif 5759702Slinton 5769702Slinton /* init offset */ 5779702Slinton p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); 5789702Slinton 5799702Slinton tfree(f); 5809702Slinton return; 5819702Slinton } 5829702Slinton 5839702Slinton canaddr( p ) NODE *p; { 5849702Slinton register int o = p->in.op; 5859702Slinton 5869702Slinton if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); 5879702Slinton return(0); 5889702Slinton } 5899702Slinton 5909702Slinton shltype( o, p ) register NODE *p; { 5919702Slinton return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); 5929702Slinton } 5939702Slinton 5949702Slinton flshape( p ) register NODE *p; { 5959702Slinton return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || 5969702Slinton (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); 5979702Slinton } 5989702Slinton 5999702Slinton shtemp( p ) register NODE *p; { 6009702Slinton if( p->in.op == STARG ) p = p->in.left; 6019702Slinton return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); 6029702Slinton } 6039702Slinton 6049702Slinton shumul( p ) register NODE *p; { 6059702Slinton register o; 6069702Slinton extern int xdebug; 6079702Slinton 6089702Slinton if (xdebug) { 6099702Slinton printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); 6109702Slinton printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); 6119702Slinton } 6129702Slinton 6139702Slinton 6149702Slinton o = p->in.op; 6159702Slinton if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); 6169702Slinton 6179702Slinton if( ( o == INCR || o == ASG MINUS ) && 6189702Slinton ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && 6199702Slinton p->in.right->in.name[0] == '\0' ) 6209702Slinton { 6219702Slinton switch (p->in.left->in.type) 6229702Slinton { 6239702Slinton case CHAR|PTR: 6249702Slinton case UCHAR|PTR: 6259702Slinton o = 1; 6269702Slinton break; 6279702Slinton 6289702Slinton case SHORT|PTR: 6299702Slinton case USHORT|PTR: 6309702Slinton o = 2; 6319702Slinton break; 6329702Slinton 6339702Slinton case INT|PTR: 6349702Slinton case UNSIGNED|PTR: 6359702Slinton case LONG|PTR: 6369702Slinton case ULONG|PTR: 6379702Slinton case FLOAT|PTR: 6389702Slinton o = 4; 6399702Slinton break; 6409702Slinton 6419702Slinton case DOUBLE|PTR: 6429702Slinton o = 8; 6439702Slinton break; 6449702Slinton 6459702Slinton default: 6469702Slinton if ( ISPTR(p->in.left->in.type) ) { 6479702Slinton o = 4; 6489702Slinton break; 6499702Slinton } 6509702Slinton else return(0); 6519702Slinton } 6529702Slinton return( p->in.right->tn.lval == o ? STARREG : 0); 6539702Slinton } 6549702Slinton 6559702Slinton return( 0 ); 6569702Slinton } 6579702Slinton 6589702Slinton adrcon( val ) CONSZ val; { 6599702Slinton printf( "$" ); 6609702Slinton printf( CONFMT, val ); 6619702Slinton } 6629702Slinton 6639702Slinton conput( p ) register NODE *p; { 6649702Slinton switch( p->in.op ){ 6659702Slinton 6669702Slinton case ICON: 6679702Slinton acon( p ); 6689702Slinton return; 6699702Slinton 6709702Slinton case REG: 6719702Slinton printf( "%s", rnames[p->tn.rval] ); 6729702Slinton return; 6739702Slinton 6749702Slinton default: 6759702Slinton cerror( "illegal conput" ); 6769702Slinton } 6779702Slinton } 6789702Slinton 6799702Slinton insput( p ) register NODE *p; { 6809702Slinton cerror( "insput" ); 6819702Slinton } 6829702Slinton 6839702Slinton upput( p ) register NODE *p; { 6849702Slinton cerror( "upput" ); 6859702Slinton } 6869702Slinton 6879702Slinton adrput( p ) register NODE *p; { 6889702Slinton register int r; 6899702Slinton /* output an address, with offsets, from p */ 6909702Slinton 6919702Slinton if( p->in.op == FLD ){ 6929702Slinton p = p->in.left; 6939702Slinton } 6949702Slinton switch( p->in.op ){ 6959702Slinton 6969702Slinton case NAME: 6979702Slinton acon( p ); 6989702Slinton return; 6999702Slinton 7009702Slinton case ICON: 7019702Slinton /* addressable value of the constant */ 7029702Slinton printf( "$" ); 7039702Slinton acon( p ); 7049702Slinton return; 7059702Slinton 7069702Slinton case REG: 7079702Slinton printf( "%s", rnames[p->tn.rval] ); 7089702Slinton return; 7099702Slinton 7109702Slinton case OREG: 7119702Slinton r = p->tn.rval; 7129702Slinton if( R2TEST(r) ){ /* double indexing */ 7139702Slinton register int flags; 7149702Slinton 7159702Slinton flags = R2UPK3(r); 7169702Slinton if( flags & 1 ) printf("*"); 7179702Slinton if( flags & 4 ) printf("-"); 7189702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); 7199702Slinton if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); 7209702Slinton if( flags & 2 ) printf("+"); 7219702Slinton printf( "[%s]", rnames[R2UPK2(r)] ); 7229702Slinton return; 7239702Slinton } 7249702Slinton if( r == AP ){ /* in the argument region */ 7259702Slinton if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); 7269702Slinton printf( CONFMT, p->tn.lval ); 7279702Slinton printf( "(ap)" ); 7289702Slinton return; 7299702Slinton } 7309702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); 7319702Slinton printf( "(%s)", rnames[p->tn.rval] ); 7329702Slinton return; 7339702Slinton 7349702Slinton case UNARY MUL: 7359702Slinton /* STARNM or STARREG found */ 7369702Slinton if( tshape(p, STARNM) ) { 7379702Slinton printf( "*" ); 7389702Slinton adrput( p->in.left); 7399702Slinton } 7409702Slinton else { /* STARREG - really auto inc or dec */ 7419702Slinton register NODE *q; 7429702Slinton 7439702Slinton /* tbl 7449702Slinton p = p->in.left; 7459702Slinton p->in.left->in.op = OREG; 7469702Slinton if( p->in.op == INCR ) { 7479702Slinton adrput( p->in.left ); 7489702Slinton printf( "+" ); 7499702Slinton } 7509702Slinton else { 7519702Slinton printf( "-" ); 7529702Slinton adrput( p->in.left ); 7539702Slinton } 7549702Slinton tbl */ 7559702Slinton printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"), 7569702Slinton rnames[p->in.left->in.left->tn.rval], 7579702Slinton (p->in.left->in.op==INCR ? "+" : "") ); 7589702Slinton p->in.op = OREG; 7599702Slinton p->tn.rval = p->in.left->in.left->tn.rval; 7609702Slinton q = p->in.left; 7619702Slinton p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0); 7629702Slinton #ifndef FLEXNAMES 7639702Slinton p->in.name[0] = '\0'; 7649702Slinton #else 7659702Slinton p->in.name = ""; 7669702Slinton #endif 7679702Slinton tfree(q); 7689702Slinton } 7699702Slinton return; 7709702Slinton 7719702Slinton default: 7729702Slinton cerror( "illegal address" ); 7739702Slinton return; 7749702Slinton 7759702Slinton } 7769702Slinton 7779702Slinton } 7789702Slinton 7799702Slinton acon( p ) register NODE *p; { /* print out a constant */ 7809702Slinton 7819702Slinton if( p->in.name[0] == '\0' ){ 7829702Slinton printf( CONFMT, p->tn.lval); 7839702Slinton } 7849702Slinton else if( p->tn.lval == 0 ) { 7859702Slinton #ifndef FLEXNAMES 7869702Slinton printf( "%.8s", p->in.name ); 7879702Slinton #else 7889702Slinton printf( "%s", p->in.name ); 7899702Slinton #endif 7909702Slinton } 7919702Slinton else { 7929702Slinton #ifndef FLEXNAMES 7939702Slinton printf( "%.8s+", p->in.name ); 7949702Slinton #else 7959702Slinton printf( "%s+", p->in.name ); 7969702Slinton #endif 7979702Slinton printf( CONFMT, p->tn.lval ); 7989702Slinton } 7999702Slinton } 8009702Slinton 8019702Slinton /* 8029702Slinton aacon( p ) register NODE *p; { /* print out a constant */ 8039702Slinton /* 8049702Slinton 8059702Slinton if( p->in.name[0] == '\0' ){ 8069702Slinton printf( CONFMT, p->tn.lval); 8079702Slinton return( 0 ); 8089702Slinton } 8099702Slinton else if( p->tn.lval == 0 ) { 8109702Slinton #ifndef FLEXNAMES 8119702Slinton printf( "$%.8s", p->in.name ); 8129702Slinton #else 8139702Slinton printf( "$%s", p->in.name ); 8149702Slinton #endif 8159702Slinton return( 1 ); 8169702Slinton } 8179702Slinton else { 8189702Slinton printf( "$(" ); 8199702Slinton printf( CONFMT, p->tn.lval ); 8209702Slinton printf( "+" ); 8219702Slinton #ifndef FLEXNAMES 8229702Slinton printf( "%.8s)", p->in.name ); 8239702Slinton #else 8249702Slinton printf( "%s)", p->in.name ); 8259702Slinton #endif 8269702Slinton return(1); 8279702Slinton } 8289702Slinton } 8299702Slinton */ 8309702Slinton 8319702Slinton genscall( p, cookie ) register NODE *p; { 8329702Slinton /* structure valued call */ 8339702Slinton return( gencall( p, cookie ) ); 8349702Slinton } 8359702Slinton 8369702Slinton /* tbl */ 8379702Slinton int gc_numbytes; 8389702Slinton /* tbl */ 8399702Slinton 8409702Slinton gencall( p, cookie ) register NODE *p; { 8419702Slinton /* generate the call given by p */ 8429702Slinton register NODE *p1, *ptemp; 8439702Slinton register temp, temp1; 8449702Slinton register m; 8459702Slinton 8469702Slinton if( p->in.right ) temp = argsize( p->in.right ); 8479702Slinton else temp = 0; 8489702Slinton 8499702Slinton if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ 8509702Slinton /* set aside room for structure return */ 8519702Slinton 8529702Slinton if( p->stn.stsize > temp ) temp1 = p->stn.stsize; 8539702Slinton else temp1 = temp; 8549702Slinton } 8559702Slinton 8569702Slinton if( temp > maxargs ) maxargs = temp; 8579702Slinton SETOFF(temp1,4); 8589702Slinton 8599702Slinton if( p->in.right ){ /* make temp node, put offset in, and generate args */ 8609702Slinton ptemp = talloc(); 8619702Slinton ptemp->in.op = OREG; 8629702Slinton ptemp->tn.lval = -1; 8639702Slinton ptemp->tn.rval = SP; 8649702Slinton #ifndef FLEXNAMES 8659702Slinton ptemp->in.name[0] = '\0'; 8669702Slinton #else 8679702Slinton ptemp->in.name = ""; 8689702Slinton #endif 8699702Slinton ptemp->in.rall = NOPREF; 8709702Slinton ptemp->in.su = 0; 8719702Slinton genargs( p->in.right, ptemp ); 8729702Slinton ptemp->in.op = FREE; 8739702Slinton } 8749702Slinton 8759702Slinton p1 = p->in.left; 8769702Slinton if( p1->in.op != ICON ){ 8779702Slinton if( p1->in.op != REG ){ 8789702Slinton if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ 8799702Slinton if( p1->in.op != NAME ){ 8809702Slinton order( p1, INAREG ); 8819702Slinton } 8829702Slinton } 8839702Slinton } 8849702Slinton } 8859702Slinton 8869702Slinton /* 8879702Slinton if( p1->in.op == REG && p->tn.rval == R5 ){ 8889702Slinton cerror( "call register overwrite" ); 8899702Slinton } 8909702Slinton */ 8919702Slinton /* tbl 8929702Slinton setup gc_numbytes so reference to ZC works */ 8939702Slinton 8949702Slinton gc_numbytes = temp&(0x3ff); 8959702Slinton /* tbl */ 8969702Slinton 8979702Slinton p->in.op = UNARY CALL; 8989702Slinton m = match( p, INTAREG|INTBREG ); 8999702Slinton 9009702Slinton /* compensate for deficiency in 'ret' instruction ... wah,kre */ 9019702Slinton /* (plus in assignment to gc_numbytes above, for neatness only) */ 9029702Slinton if (temp >= 1024) 9039702Slinton printf(" addl2 $%d,sp\n", (temp&(~0x3ff))); 9049702Slinton 9059702Slinton /* tbl 9069702Slinton switch( temp ) { 9079702Slinton case 0: 9089702Slinton break; 9099702Slinton case 2: 9109702Slinton printf( " tst (sp)+\n" ); 9119702Slinton break; 9129702Slinton case 4: 9139702Slinton printf( " cmp (sp)+,(sp)+\n" ); 9149702Slinton break; 9159702Slinton default: 9169702Slinton printf( " add $%d,sp\n", temp); 9179702Slinton } 9189702Slinton tbl */ 9199702Slinton return(m != MDONE); 9209702Slinton } 9219702Slinton 9229702Slinton /* tbl */ 9239702Slinton char * 9249702Slinton ccbranches[] = { 9259702Slinton " jeql L%d\n", 9269702Slinton " jneq L%d\n", 9279702Slinton " jleq L%d\n", 9289702Slinton " jlss L%d\n", 9299702Slinton " jgeq L%d\n", 9309702Slinton " jgtr L%d\n", 9319702Slinton " jlequ L%d\n", 9329702Slinton " jlssu L%d\n", 9339702Slinton " jgequ L%d\n", 9349702Slinton " jgtru L%d\n", 9359702Slinton }; 9369702Slinton /* tbl */ 9379702Slinton 9389702Slinton cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 9399702Slinton 9409702Slinton /* tbl */ 9419702Slinton if( o == 0 ) printf( " jbr L%d\n", lab ); 9429702Slinton /* tbl */ 9439702Slinton else { 9449702Slinton if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 9459702Slinton printf( ccbranches[o-EQ], lab ); 9469702Slinton } 9479702Slinton } 9489702Slinton 9499702Slinton nextcook( p, cookie ) NODE *p; { 9509702Slinton /* we have failed to match p with cookie; try another */ 9519702Slinton if( cookie == FORREW ) return( 0 ); /* hopeless! */ 9529702Slinton if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 9539702Slinton if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 9549702Slinton return( FORREW ); 9559702Slinton } 9569702Slinton 9579702Slinton lastchance( p, cook ) NODE *p; { 9589702Slinton /* forget it! */ 9599702Slinton return(0); 9609702Slinton } 9619702Slinton 9629702Slinton optim2( p ) register NODE *p; { 9639702Slinton /* do local tree transformations and optimizations */ 9649702Slinton 965*16181Sralph register NODE *l, *r; 966*16181Sralph int m, ml; 9679702Slinton 9689702Slinton switch( p->in.op ) { 9699702Slinton 9709702Slinton case AND: 9719702Slinton /* commute L and R to eliminate compliments and constants */ 972*16181Sralph if( (l = p->in.left)->in.op == ICON && l->in.name[0] == 0 || 973*16181Sralph l->in.op == COMPL ) { 9749702Slinton p->in.left = p->in.right; 975*16181Sralph p->in.right = l; 9769702Slinton } 9779702Slinton case ASG AND: 9789702Slinton /* change meaning of AND to ~R&L - bic on pdp11 */ 9799702Slinton r = p->in.right; 9809702Slinton if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */ 9819702Slinton r->tn.lval = ~r->tn.lval; 9829702Slinton } 9839702Slinton else if( r->in.op==COMPL ) { /* ~~A => A */ 9849702Slinton r->in.op = FREE; 9859702Slinton p->in.right = r->in.left; 9869702Slinton } 9879702Slinton else { /* insert complement node */ 988*16181Sralph p->in.right = l = talloc(); 989*16181Sralph l->in.op = COMPL; 990*16181Sralph l->in.rall = NOPREF; 991*16181Sralph l->in.type = r->in.type; 992*16181Sralph l->in.left = r; 993*16181Sralph l->in.right = NULL; 9949702Slinton } 9959702Slinton break; 9969702Slinton 997*16181Sralph case SCONV: 998*16181Sralph m = (p->in.type == FLOAT || p->in.type == DOUBLE); 999*16181Sralph ml = ((l = p->in.left)->in.type == FLOAT || l->in.type == DOUBLE); 1000*16181Sralph if( m != ml ) break; 1001*16181Sralph m = p->in.type; 1002*16181Sralph ml = l->in.type; 1003*16181Sralph /* meaningful ones are conversion of int to char, int to short, 1004*16181Sralph and short to char, and unsigned version of them */ 1005*16181Sralph if( m==CHAR || m==UCHAR ){ 1006*16181Sralph if( ml!=CHAR && ml!= UCHAR ) 1007*16181Sralph break; 1008*16181Sralph } 1009*16181Sralph else if( m==SHORT || m==USHORT ){ 1010*16181Sralph if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) 1011*16181Sralph break; 1012*16181Sralph } 1013*16181Sralph 1014*16181Sralph /* clobber conversion */ 1015*16181Sralph if( tlen( p ) == tlen( l ) && l->in.op != FLD ) 1016*16181Sralph l->in.type = p->in.type; 1017*16181Sralph ncopy( p, l ); 1018*16181Sralph l->in.op = FREE; 1019*16181Sralph break; 1020*16181Sralph 10219702Slinton } 10229702Slinton } 10239702Slinton 10249702Slinton NODE * addroreg(l) 10259702Slinton /* OREG was built in clocal() 10269702Slinton * for an auto or formal parameter 10279702Slinton * now its address is being taken 10289702Slinton * local code must unwind it 10299702Slinton * back to PLUS/MINUS REG ICON 10309702Slinton * according to local conventions 10319702Slinton */ 10329702Slinton { 10339702Slinton cerror("address of OREG taken"); 10349702Slinton } 10359702Slinton 10369702Slinton 10379702Slinton 10389702Slinton # ifndef ONEPASS 10399702Slinton main( argc, argv ) char *argv[]; { 10409702Slinton return( mainp2( argc, argv ) ); 10419702Slinton } 10429702Slinton # endif 10439702Slinton 10449702Slinton 10459702Slinton /* added by jwf */ 10469702Slinton struct functbl { 10479702Slinton int fop; 10489702Slinton TWORD ftype; 10499702Slinton char *func; 10509702Slinton } opfunc[] = { 10519702Slinton DIV, TANY, "udiv", 10529702Slinton MOD, TANY, "urem", 10539702Slinton ASG DIV, TANY, "udiv", 10549702Slinton ASG MOD, TANY, "urem", 10559702Slinton 0, 0, 0 }; 10569702Slinton 10579702Slinton hardops(p) register NODE *p; { 10589702Slinton /* change hard to do operators into function calls. */ 10599702Slinton register NODE *q; 10609702Slinton register struct functbl *f; 10619702Slinton register o; 10629702Slinton register TWORD t; 10639702Slinton 10649702Slinton o = p->in.op; 10659702Slinton t = p->in.type; 10669702Slinton if( t!=UNSIGNED && t!=ULONG ) return; 10679702Slinton 10689702Slinton for( f=opfunc; f->fop; f++ ) { 10699702Slinton if( o==f->fop ) goto convert; 10709702Slinton } 10719702Slinton return; 10729702Slinton 10739702Slinton /* need to rewrite tree for ASG OP */ 10749702Slinton /* must change ASG OP to a simple OP */ 10759702Slinton convert: 10769702Slinton if( asgop( o ) ) { 10779702Slinton q = talloc(); 10789702Slinton switch( p->in.op ) { 10799702Slinton case ASG DIV: 10809702Slinton q->in.op = DIV; 10819702Slinton break; 10829702Slinton case ASG MOD: 10839702Slinton q->in.op = MOD; 10849702Slinton break; 10859702Slinton } 10869702Slinton q->in.rall = NOPREF; 10879702Slinton q->in.type = p->in.type; 10889702Slinton q->in.left = tcopy(p->in.left); 10899702Slinton q->in.right = p->in.right; 10909702Slinton p->in.op = ASSIGN; 10919702Slinton p->in.right = q; 10929702Slinton zappost(q->in.left); /* remove post-INCR(DECR) from new node */ 10939702Slinton fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */ 10949702Slinton p = q; 10959702Slinton 10969702Slinton } 10979702Slinton 10989702Slinton /* build comma op for args to function */ 10999702Slinton q = talloc(); 11009702Slinton q->in.op = CM; 11019702Slinton q->in.rall = NOPREF; 11029702Slinton q->in.type = INT; 11039702Slinton q->in.left = p->in.left; 11049702Slinton q->in.right = p->in.right; 11059702Slinton p->in.op = CALL; 11069702Slinton p->in.right = q; 11079702Slinton 11089702Slinton /* put function name in left node of call */ 11099702Slinton p->in.left = q = talloc(); 11109702Slinton q->in.op = ICON; 11119702Slinton q->in.rall = NOPREF; 11129702Slinton q->in.type = INCREF( FTN + p->in.type ); 11139702Slinton #ifndef FLEXNAMES 11149702Slinton strcpy( q->in.name, f->func ); 11159702Slinton #else 11169702Slinton q->in.name = f->func; 11179702Slinton #endif 11189702Slinton q->tn.lval = 0; 11199702Slinton q->tn.rval = 0; 11209702Slinton 11219702Slinton return; 11229702Slinton 11239702Slinton } 11249702Slinton 11259702Slinton zappost(p) NODE *p; { 11269702Slinton /* look for ++ and -- operators and remove them */ 11279702Slinton 11289702Slinton register o, ty; 11299702Slinton register NODE *q; 11309702Slinton o = p->in.op; 11319702Slinton ty = optype( o ); 11329702Slinton 11339702Slinton switch( o ){ 11349702Slinton 11359702Slinton case INCR: 11369702Slinton case DECR: 11379702Slinton q = p->in.left; 11389702Slinton p->in.right->in.op = FREE; /* zap constant */ 11399702Slinton ncopy( p, q ); 11409702Slinton q->in.op = FREE; 11419702Slinton return; 11429702Slinton 11439702Slinton } 11449702Slinton 11459702Slinton if( ty == BITYPE ) zappost( p->in.right ); 11469702Slinton if( ty != LTYPE ) zappost( p->in.left ); 11479702Slinton } 11489702Slinton 11499702Slinton fixpre(p) NODE *p; { 11509702Slinton 11519702Slinton register o, ty; 11529702Slinton o = p->in.op; 11539702Slinton ty = optype( o ); 11549702Slinton 11559702Slinton switch( o ){ 11569702Slinton 11579702Slinton case ASG PLUS: 11589702Slinton p->in.op = PLUS; 11599702Slinton break; 11609702Slinton case ASG MINUS: 11619702Slinton p->in.op = MINUS; 11629702Slinton break; 11639702Slinton } 11649702Slinton 11659702Slinton if( ty == BITYPE ) fixpre( p->in.right ); 11669702Slinton if( ty != LTYPE ) fixpre( p->in.left ); 11679702Slinton } 11689702Slinton 11699702Slinton myreader(p) register NODE *p; { 11709702Slinton walkf( p, hardops ); /* convert ops to function calls */ 11719702Slinton canon( p ); /* expands r-vals for fileds */ 11729702Slinton walkf( p, optim2 ); 11739702Slinton /* jwf toff = 0; /* stack offset swindle */ 11749702Slinton } 11759702Slinton 11769702Slinton 1177