1*16573Sralph static char *sccsid ="@(#)local2.c 1.4 (Berkeley) 06/06/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 { 13916181Sralph 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'); 21016181Sralph if (p->in.op == ASSIGN) 21116181Sralph l = getlr(p, 'L'); 21216181Sralph else if (p->in.op == SCONV) 2139702Slinton { 2149702Slinton l = resc; 21516181Sralph #ifdef FORT 21616181Sralph l->in.type = r->in.type; 21716181Sralph #else 21816181Sralph l->in.type = r->in.type==FLOAT ? DOUBLE : r->in.type; 21916181Sralph #endif 22016181Sralph r = getlr(p, 'L'); 22116181Sralph } 22216181Sralph else 22316181Sralph { /* OPLTYPE */ 22416181Sralph l = resc; 22516181Sralph #ifdef FORT 22616181Sralph l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? r->in.type : INT); 22716181Sralph #else 2289702Slinton l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); 22916181Sralph #endif 2309702Slinton } 2319702Slinton if (r->in.op == ICON) 23216181Sralph 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 } 26116181Sralph else 26216181Sralph { 26316181Sralph printf("moval"); 26416181Sralph printf(" "); 26516181Sralph acon(r); 26616181Sralph printf(","); 26716181Sralph adrput(l); 26816181Sralph return; 26916181Sralph } 2709702Slinton 2719702Slinton if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) 2729702Slinton { 27316181Sralph if (tlen(l) < tlen(r) && !mixtypes(l,r)) 2749702Slinton { 27516181Sralph if (ISUNSIGNED(l->in.type)) 27616181Sralph printf("movz"); 2779702Slinton else 2789702Slinton printf("cvt"); 27916181Sralph prtype(l); 28016181Sralph printf("l"); 28116181Sralph goto ops; 2829702Slinton } 2839702Slinton else 28416181Sralph 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 38716181Sralph 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 r = p->in.left; 4249702Slinton } 4259702Slinton else cerror( "STASG bad" ); 4269702Slinton 4279702Slinton if( r->in.op == ICON ) r->in.op = NAME; 4289702Slinton else if( r->in.op == REG ) r->in.op = OREG; 4299702Slinton else if( r->in.op != OREG ) cerror( "STASG-r" ); 4309702Slinton 4319702Slinton size = p->stn.stsize; 4329702Slinton 4339702Slinton if( size <= 0 || size > 65535 ) 4349702Slinton cerror("structure size <0=0 or >65535"); 4359702Slinton 4369702Slinton switch(size) { 4379702Slinton case 1: 4389702Slinton printf(" movb "); 4399702Slinton break; 4409702Slinton case 2: 4419702Slinton printf(" movw "); 4429702Slinton break; 4439702Slinton case 4: 4449702Slinton printf(" movl "); 4459702Slinton break; 4469702Slinton case 8: 4479702Slinton printf(" movq "); 4489702Slinton break; 4499702Slinton default: 4509702Slinton printf(" movc3 $%d,", size); 4519702Slinton break; 4529702Slinton } 4539702Slinton adrput(r); 45416418Sralph if( p->in.op == STASG ){ 45516418Sralph printf(","); 45616418Sralph adrput(l); 45716418Sralph printf("\n"); 45816418Sralph } 45916418Sralph else 46016418Sralph printf(",(sp)\n"); 4619702Slinton 4629702Slinton if( r->in.op == NAME ) r->in.op = ICON; 4639702Slinton else if( r->in.op == OREG ) r->in.op = REG; 4649702Slinton 4659702Slinton } 4669702Slinton break; 4679702Slinton 4689702Slinton default: 4699702Slinton cerror( "illegal zzzcode" ); 4709702Slinton } 4719702Slinton } 4729702Slinton 4739702Slinton rmove( rt, rs, t ){ 4749702Slinton printf( " %s %s,%s\n", 4759702Slinton (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), 4769702Slinton rnames[rs], rnames[rt] ); 4779702Slinton } 4789702Slinton 4799702Slinton struct respref 4809702Slinton respref[] = { 4819702Slinton INTAREG|INTBREG, INTAREG|INTBREG, 4829702Slinton INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, 4839702Slinton INTEMP, INTEMP, 4849702Slinton FORARG, FORARG, 4859702Slinton INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 4869702Slinton 0, 0 }; 4879702Slinton 4889702Slinton setregs(){ /* set up temporary registers */ 4899702Slinton fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ 4909702Slinton ; 4919702Slinton } 4929702Slinton 4939702Slinton szty(t){ /* size, in registers, needed to hold thing of type t */ 49416181Sralph #ifdef FORT 49516181Sralph return( (t==DOUBLE) ? 2 : 1 ); 49616181Sralph #else 4979702Slinton return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); 49816181Sralph #endif 4999702Slinton } 5009702Slinton 5019702Slinton rewfld( p ) NODE *p; { 5029702Slinton return(1); 5039702Slinton } 5049702Slinton 5059702Slinton callreg(p) NODE *p; { 5069702Slinton return( R0 ); 5079702Slinton } 5089702Slinton 5099702Slinton base( p ) register NODE *p; { 5109702Slinton register int o = p->in.op; 5119702Slinton 5129702Slinton if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ 5139702Slinton if( o==REG ) return( p->tn.rval ); 5149702Slinton if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) 5159702Slinton return( p->in.left->tn.rval ); 5169702Slinton if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5179702Slinton return( p->tn.rval + 0200*1 ); 5189702Slinton if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); 5199702Slinton if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); 5209702Slinton if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG 5219702Slinton && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5229702Slinton return( p->in.left->in.left->tn.rval + 0200*(1+2) ); 5239702Slinton return( -1 ); 5249702Slinton } 5259702Slinton 5269702Slinton offset( p, tyl ) register NODE *p; int tyl; { 5279702Slinton 5289702Slinton if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); 5299702Slinton if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && 5309702Slinton (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') 5319702Slinton && (1<<p->in.right->tn.lval)==tyl)) 5329702Slinton return( p->in.left->tn.rval ); 5339702Slinton return( -1 ); 5349702Slinton } 5359702Slinton 5369702Slinton makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { 5379702Slinton register NODE *t; 5389702Slinton register int i; 5399702Slinton NODE *f; 5409702Slinton 5419702Slinton p->in.op = OREG; 5429702Slinton f = p->in.left; /* have to free this subtree later */ 5439702Slinton 5449702Slinton /* init base */ 5459702Slinton switch (q->in.op) { 5469702Slinton case ICON: 5479702Slinton case REG: 5489702Slinton case OREG: 5499702Slinton t = q; 5509702Slinton break; 5519702Slinton 5529702Slinton case MINUS: 5539702Slinton q->in.right->tn.lval = -q->in.right->tn.lval; 5549702Slinton case PLUS: 5559702Slinton t = q->in.right; 5569702Slinton break; 5579702Slinton 5589702Slinton case INCR: 5599702Slinton case ASG MINUS: 5609702Slinton t = q->in.left; 5619702Slinton break; 5629702Slinton 5639702Slinton case UNARY MUL: 5649702Slinton t = q->in.left->in.left; 5659702Slinton break; 5669702Slinton 5679702Slinton default: 5689702Slinton cerror("illegal makeor2"); 5699702Slinton } 5709702Slinton 5719702Slinton p->tn.lval = t->tn.lval; 5729702Slinton #ifndef FLEXNAMES 5739702Slinton for(i=0; i<NCHNAM; ++i) 5749702Slinton p->in.name[i] = t->in.name[i]; 5759702Slinton #else 5769702Slinton p->in.name = t->in.name; 5779702Slinton #endif 5789702Slinton 5799702Slinton /* init offset */ 5809702Slinton p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); 5819702Slinton 5829702Slinton tfree(f); 5839702Slinton return; 5849702Slinton } 5859702Slinton 5869702Slinton canaddr( p ) NODE *p; { 5879702Slinton register int o = p->in.op; 5889702Slinton 5899702Slinton if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); 5909702Slinton return(0); 5919702Slinton } 5929702Slinton 5939702Slinton shltype( o, p ) register NODE *p; { 5949702Slinton return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); 5959702Slinton } 5969702Slinton 5979702Slinton flshape( p ) register NODE *p; { 5989702Slinton return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || 5999702Slinton (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); 6009702Slinton } 6019702Slinton 6029702Slinton shtemp( p ) register NODE *p; { 6039702Slinton if( p->in.op == STARG ) p = p->in.left; 6049702Slinton return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); 6059702Slinton } 6069702Slinton 6079702Slinton shumul( p ) register NODE *p; { 6089702Slinton register o; 6099702Slinton extern int xdebug; 6109702Slinton 6119702Slinton if (xdebug) { 6129702Slinton printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); 6139702Slinton printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); 6149702Slinton } 6159702Slinton 6169702Slinton 6179702Slinton o = p->in.op; 6189702Slinton if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); 6199702Slinton 6209702Slinton if( ( o == INCR || o == ASG MINUS ) && 6219702Slinton ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && 6229702Slinton p->in.right->in.name[0] == '\0' ) 6239702Slinton { 6249702Slinton switch (p->in.left->in.type) 6259702Slinton { 6269702Slinton case CHAR|PTR: 6279702Slinton case UCHAR|PTR: 6289702Slinton o = 1; 6299702Slinton break; 6309702Slinton 6319702Slinton case SHORT|PTR: 6329702Slinton case USHORT|PTR: 6339702Slinton o = 2; 6349702Slinton break; 6359702Slinton 6369702Slinton case INT|PTR: 6379702Slinton case UNSIGNED|PTR: 6389702Slinton case LONG|PTR: 6399702Slinton case ULONG|PTR: 6409702Slinton case FLOAT|PTR: 6419702Slinton o = 4; 6429702Slinton break; 6439702Slinton 6449702Slinton case DOUBLE|PTR: 6459702Slinton o = 8; 6469702Slinton break; 6479702Slinton 6489702Slinton default: 6499702Slinton if ( ISPTR(p->in.left->in.type) ) { 6509702Slinton o = 4; 6519702Slinton break; 6529702Slinton } 6539702Slinton else return(0); 6549702Slinton } 6559702Slinton return( p->in.right->tn.lval == o ? STARREG : 0); 6569702Slinton } 6579702Slinton 6589702Slinton return( 0 ); 6599702Slinton } 6609702Slinton 6619702Slinton adrcon( val ) CONSZ val; { 6629702Slinton printf( "$" ); 6639702Slinton printf( CONFMT, val ); 6649702Slinton } 6659702Slinton 6669702Slinton conput( p ) register NODE *p; { 6679702Slinton switch( p->in.op ){ 6689702Slinton 6699702Slinton case ICON: 6709702Slinton acon( p ); 6719702Slinton return; 6729702Slinton 6739702Slinton case REG: 6749702Slinton printf( "%s", rnames[p->tn.rval] ); 6759702Slinton return; 6769702Slinton 6779702Slinton default: 6789702Slinton cerror( "illegal conput" ); 6799702Slinton } 6809702Slinton } 6819702Slinton 6829702Slinton insput( p ) register NODE *p; { 6839702Slinton cerror( "insput" ); 6849702Slinton } 6859702Slinton 6869702Slinton upput( p ) register NODE *p; { 6879702Slinton cerror( "upput" ); 6889702Slinton } 6899702Slinton 6909702Slinton adrput( p ) register NODE *p; { 6919702Slinton register int r; 6929702Slinton /* output an address, with offsets, from p */ 6939702Slinton 6949702Slinton if( p->in.op == FLD ){ 6959702Slinton p = p->in.left; 6969702Slinton } 6979702Slinton switch( p->in.op ){ 6989702Slinton 6999702Slinton case NAME: 7009702Slinton acon( p ); 7019702Slinton return; 7029702Slinton 7039702Slinton case ICON: 7049702Slinton /* addressable value of the constant */ 7059702Slinton printf( "$" ); 7069702Slinton acon( p ); 7079702Slinton return; 7089702Slinton 7099702Slinton case REG: 7109702Slinton printf( "%s", rnames[p->tn.rval] ); 7119702Slinton return; 7129702Slinton 7139702Slinton case OREG: 7149702Slinton r = p->tn.rval; 7159702Slinton if( R2TEST(r) ){ /* double indexing */ 7169702Slinton register int flags; 7179702Slinton 7189702Slinton flags = R2UPK3(r); 7199702Slinton if( flags & 1 ) printf("*"); 7209702Slinton if( flags & 4 ) printf("-"); 7219702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); 7229702Slinton if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); 7239702Slinton if( flags & 2 ) printf("+"); 7249702Slinton printf( "[%s]", rnames[R2UPK2(r)] ); 7259702Slinton return; 7269702Slinton } 7279702Slinton if( r == AP ){ /* in the argument region */ 7289702Slinton if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); 7299702Slinton printf( CONFMT, p->tn.lval ); 7309702Slinton printf( "(ap)" ); 7319702Slinton return; 7329702Slinton } 7339702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); 7349702Slinton printf( "(%s)", rnames[p->tn.rval] ); 7359702Slinton return; 7369702Slinton 7379702Slinton case UNARY MUL: 7389702Slinton /* STARNM or STARREG found */ 7399702Slinton if( tshape(p, STARNM) ) { 7409702Slinton printf( "*" ); 7419702Slinton adrput( p->in.left); 7429702Slinton } 7439702Slinton else { /* STARREG - really auto inc or dec */ 7449702Slinton register NODE *q; 7459702Slinton 7469702Slinton /* tbl 7479702Slinton p = p->in.left; 7489702Slinton p->in.left->in.op = OREG; 7499702Slinton if( p->in.op == INCR ) { 7509702Slinton adrput( p->in.left ); 7519702Slinton printf( "+" ); 7529702Slinton } 7539702Slinton else { 7549702Slinton printf( "-" ); 7559702Slinton adrput( p->in.left ); 7569702Slinton } 7579702Slinton tbl */ 7589702Slinton printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"), 7599702Slinton rnames[p->in.left->in.left->tn.rval], 7609702Slinton (p->in.left->in.op==INCR ? "+" : "") ); 7619702Slinton p->in.op = OREG; 7629702Slinton p->tn.rval = p->in.left->in.left->tn.rval; 7639702Slinton q = p->in.left; 7649702Slinton p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0); 7659702Slinton #ifndef FLEXNAMES 7669702Slinton p->in.name[0] = '\0'; 7679702Slinton #else 7689702Slinton p->in.name = ""; 7699702Slinton #endif 7709702Slinton tfree(q); 7719702Slinton } 7729702Slinton return; 7739702Slinton 7749702Slinton default: 7759702Slinton cerror( "illegal address" ); 7769702Slinton return; 7779702Slinton 7789702Slinton } 7799702Slinton 7809702Slinton } 7819702Slinton 7829702Slinton acon( p ) register NODE *p; { /* print out a constant */ 7839702Slinton 7849702Slinton if( p->in.name[0] == '\0' ){ 7859702Slinton printf( CONFMT, p->tn.lval); 7869702Slinton } 7879702Slinton else if( p->tn.lval == 0 ) { 7889702Slinton #ifndef FLEXNAMES 7899702Slinton printf( "%.8s", p->in.name ); 7909702Slinton #else 7919702Slinton printf( "%s", p->in.name ); 7929702Slinton #endif 7939702Slinton } 7949702Slinton else { 7959702Slinton #ifndef FLEXNAMES 7969702Slinton printf( "%.8s+", p->in.name ); 7979702Slinton #else 7989702Slinton printf( "%s+", p->in.name ); 7999702Slinton #endif 8009702Slinton printf( CONFMT, p->tn.lval ); 8019702Slinton } 8029702Slinton } 8039702Slinton 8049702Slinton /* 8059702Slinton aacon( p ) register NODE *p; { /* print out a constant */ 8069702Slinton /* 8079702Slinton 8089702Slinton if( p->in.name[0] == '\0' ){ 8099702Slinton printf( CONFMT, p->tn.lval); 8109702Slinton return( 0 ); 8119702Slinton } 8129702Slinton else if( p->tn.lval == 0 ) { 8139702Slinton #ifndef FLEXNAMES 8149702Slinton printf( "$%.8s", p->in.name ); 8159702Slinton #else 8169702Slinton printf( "$%s", p->in.name ); 8179702Slinton #endif 8189702Slinton return( 1 ); 8199702Slinton } 8209702Slinton else { 8219702Slinton printf( "$(" ); 8229702Slinton printf( CONFMT, p->tn.lval ); 8239702Slinton printf( "+" ); 8249702Slinton #ifndef FLEXNAMES 8259702Slinton printf( "%.8s)", p->in.name ); 8269702Slinton #else 8279702Slinton printf( "%s)", p->in.name ); 8289702Slinton #endif 8299702Slinton return(1); 8309702Slinton } 8319702Slinton } 8329702Slinton */ 8339702Slinton 8349702Slinton genscall( p, cookie ) register NODE *p; { 8359702Slinton /* structure valued call */ 8369702Slinton return( gencall( p, cookie ) ); 8379702Slinton } 8389702Slinton 8399702Slinton /* tbl */ 8409702Slinton int gc_numbytes; 8419702Slinton /* tbl */ 8429702Slinton 8439702Slinton gencall( p, cookie ) register NODE *p; { 8449702Slinton /* generate the call given by p */ 84516418Sralph register NODE *p1; 8469702Slinton register temp, temp1; 8479702Slinton register m; 8489702Slinton 8499702Slinton if( p->in.right ) temp = argsize( p->in.right ); 8509702Slinton else temp = 0; 8519702Slinton 8529702Slinton if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ 8539702Slinton /* set aside room for structure return */ 8549702Slinton 8559702Slinton if( p->stn.stsize > temp ) temp1 = p->stn.stsize; 8569702Slinton else temp1 = temp; 8579702Slinton } 8589702Slinton 8599702Slinton if( temp > maxargs ) maxargs = temp; 8609702Slinton SETOFF(temp1,4); 8619702Slinton 8629702Slinton if( p->in.right ){ /* make temp node, put offset in, and generate args */ 86316418Sralph genargs( p->in.right ); 8649702Slinton } 8659702Slinton 8669702Slinton p1 = p->in.left; 8679702Slinton if( p1->in.op != ICON ){ 8689702Slinton if( p1->in.op != REG ){ 8699702Slinton if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ 8709702Slinton if( p1->in.op != NAME ){ 8719702Slinton order( p1, INAREG ); 8729702Slinton } 8739702Slinton } 8749702Slinton } 8759702Slinton } 8769702Slinton 8779702Slinton /* 8789702Slinton if( p1->in.op == REG && p->tn.rval == R5 ){ 8799702Slinton cerror( "call register overwrite" ); 8809702Slinton } 8819702Slinton */ 8829702Slinton /* tbl 8839702Slinton setup gc_numbytes so reference to ZC works */ 8849702Slinton 8859702Slinton gc_numbytes = temp&(0x3ff); 8869702Slinton /* tbl */ 8879702Slinton 8889702Slinton p->in.op = UNARY CALL; 8899702Slinton m = match( p, INTAREG|INTBREG ); 8909702Slinton 8919702Slinton /* compensate for deficiency in 'ret' instruction ... wah,kre */ 8929702Slinton /* (plus in assignment to gc_numbytes above, for neatness only) */ 8939702Slinton if (temp >= 1024) 8949702Slinton printf(" addl2 $%d,sp\n", (temp&(~0x3ff))); 8959702Slinton 8969702Slinton /* tbl 8979702Slinton switch( temp ) { 8989702Slinton case 0: 8999702Slinton break; 9009702Slinton case 2: 9019702Slinton printf( " tst (sp)+\n" ); 9029702Slinton break; 9039702Slinton case 4: 9049702Slinton printf( " cmp (sp)+,(sp)+\n" ); 9059702Slinton break; 9069702Slinton default: 9079702Slinton printf( " add $%d,sp\n", temp); 9089702Slinton } 9099702Slinton tbl */ 9109702Slinton return(m != MDONE); 9119702Slinton } 9129702Slinton 9139702Slinton /* tbl */ 9149702Slinton char * 9159702Slinton ccbranches[] = { 9169702Slinton " jeql L%d\n", 9179702Slinton " jneq L%d\n", 9189702Slinton " jleq L%d\n", 9199702Slinton " jlss L%d\n", 9209702Slinton " jgeq L%d\n", 9219702Slinton " jgtr L%d\n", 9229702Slinton " jlequ L%d\n", 9239702Slinton " jlssu L%d\n", 9249702Slinton " jgequ L%d\n", 9259702Slinton " jgtru L%d\n", 9269702Slinton }; 9279702Slinton /* tbl */ 9289702Slinton 9299702Slinton cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 9309702Slinton 9319702Slinton /* tbl */ 9329702Slinton if( o == 0 ) printf( " jbr L%d\n", lab ); 9339702Slinton /* tbl */ 9349702Slinton else { 9359702Slinton if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 9369702Slinton printf( ccbranches[o-EQ], lab ); 9379702Slinton } 9389702Slinton } 9399702Slinton 9409702Slinton nextcook( p, cookie ) NODE *p; { 9419702Slinton /* we have failed to match p with cookie; try another */ 9429702Slinton if( cookie == FORREW ) return( 0 ); /* hopeless! */ 9439702Slinton if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 9449702Slinton if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 9459702Slinton return( FORREW ); 9469702Slinton } 9479702Slinton 9489702Slinton lastchance( p, cook ) NODE *p; { 9499702Slinton /* forget it! */ 9509702Slinton return(0); 9519702Slinton } 9529702Slinton 9539702Slinton optim2( p ) register NODE *p; { 9549702Slinton /* do local tree transformations and optimizations */ 9559702Slinton 95616181Sralph register NODE *l, *r; 95716181Sralph int m, ml; 9589702Slinton 9599702Slinton switch( p->in.op ) { 9609702Slinton 9619702Slinton case AND: 9629702Slinton /* commute L and R to eliminate compliments and constants */ 96316181Sralph if( (l = p->in.left)->in.op == ICON && l->in.name[0] == 0 || 96416181Sralph l->in.op == COMPL ) { 9659702Slinton p->in.left = p->in.right; 96616181Sralph p->in.right = l; 9679702Slinton } 9689702Slinton case ASG AND: 9699702Slinton /* change meaning of AND to ~R&L - bic on pdp11 */ 9709702Slinton r = p->in.right; 9719702Slinton if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */ 9729702Slinton r->tn.lval = ~r->tn.lval; 9739702Slinton } 9749702Slinton else if( r->in.op==COMPL ) { /* ~~A => A */ 9759702Slinton r->in.op = FREE; 9769702Slinton p->in.right = r->in.left; 9779702Slinton } 9789702Slinton else { /* insert complement node */ 97916181Sralph p->in.right = l = talloc(); 98016181Sralph l->in.op = COMPL; 98116181Sralph l->in.rall = NOPREF; 98216181Sralph l->in.type = r->in.type; 98316181Sralph l->in.left = r; 98416181Sralph l->in.right = NULL; 9859702Slinton } 9869702Slinton break; 9879702Slinton 98816181Sralph case SCONV: 989*16573Sralph #ifdef FORT 990*16573Sralph if( p->in.type == FLOAT || p->in.type == DOUBLE || 991*16573Sralph (l = p->in.left)->in.type == FLOAT || l->in.type == DOUBLE ) 992*16573Sralph break; 993*16573Sralph #else 99416181Sralph m = (p->in.type == FLOAT || p->in.type == DOUBLE); 99516181Sralph ml = ((l = p->in.left)->in.type == FLOAT || l->in.type == DOUBLE); 99616181Sralph if( m != ml ) break; 997*16573Sralph #endif 99816181Sralph m = p->in.type; 99916181Sralph ml = l->in.type; 100016181Sralph /* meaningful ones are conversion of int to char, int to short, 100116181Sralph and short to char, and unsigned version of them */ 100216181Sralph if( m==CHAR || m==UCHAR ){ 100316181Sralph if( ml!=CHAR && ml!= UCHAR ) 100416181Sralph break; 100516181Sralph } 100616181Sralph else if( m==SHORT || m==USHORT ){ 100716181Sralph if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) 100816181Sralph break; 100916181Sralph } 101016181Sralph 101116181Sralph /* clobber conversion */ 101216181Sralph if( tlen( p ) == tlen( l ) && l->in.op != FLD ) 101316181Sralph l->in.type = p->in.type; 101416181Sralph ncopy( p, l ); 101516181Sralph l->in.op = FREE; 101616181Sralph break; 101716181Sralph 10189702Slinton } 10199702Slinton } 10209702Slinton 10219702Slinton NODE * addroreg(l) 10229702Slinton /* OREG was built in clocal() 10239702Slinton * for an auto or formal parameter 10249702Slinton * now its address is being taken 10259702Slinton * local code must unwind it 10269702Slinton * back to PLUS/MINUS REG ICON 10279702Slinton * according to local conventions 10289702Slinton */ 10299702Slinton { 10309702Slinton cerror("address of OREG taken"); 10319702Slinton } 10329702Slinton 10339702Slinton 10349702Slinton 10359702Slinton # ifndef ONEPASS 10369702Slinton main( argc, argv ) char *argv[]; { 10379702Slinton return( mainp2( argc, argv ) ); 10389702Slinton } 10399702Slinton # endif 10409702Slinton 10419702Slinton 10429702Slinton /* added by jwf */ 10439702Slinton struct functbl { 10449702Slinton int fop; 10459702Slinton TWORD ftype; 10469702Slinton char *func; 10479702Slinton } opfunc[] = { 10489702Slinton DIV, TANY, "udiv", 10499702Slinton MOD, TANY, "urem", 10509702Slinton ASG DIV, TANY, "udiv", 10519702Slinton ASG MOD, TANY, "urem", 10529702Slinton 0, 0, 0 }; 10539702Slinton 10549702Slinton hardops(p) register NODE *p; { 10559702Slinton /* change hard to do operators into function calls. */ 10569702Slinton register NODE *q; 10579702Slinton register struct functbl *f; 10589702Slinton register o; 10599702Slinton register TWORD t; 10609702Slinton 10619702Slinton o = p->in.op; 10629702Slinton t = p->in.type; 10639702Slinton if( t!=UNSIGNED && t!=ULONG ) return; 10649702Slinton 10659702Slinton for( f=opfunc; f->fop; f++ ) { 10669702Slinton if( o==f->fop ) goto convert; 10679702Slinton } 10689702Slinton return; 10699702Slinton 10709702Slinton /* need to rewrite tree for ASG OP */ 10719702Slinton /* must change ASG OP to a simple OP */ 10729702Slinton convert: 10739702Slinton if( asgop( o ) ) { 10749702Slinton q = talloc(); 10759702Slinton switch( p->in.op ) { 10769702Slinton case ASG DIV: 10779702Slinton q->in.op = DIV; 10789702Slinton break; 10799702Slinton case ASG MOD: 10809702Slinton q->in.op = MOD; 10819702Slinton break; 10829702Slinton } 10839702Slinton q->in.rall = NOPREF; 10849702Slinton q->in.type = p->in.type; 10859702Slinton q->in.left = tcopy(p->in.left); 10869702Slinton q->in.right = p->in.right; 10879702Slinton p->in.op = ASSIGN; 10889702Slinton p->in.right = q; 10899702Slinton zappost(q->in.left); /* remove post-INCR(DECR) from new node */ 10909702Slinton fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */ 10919702Slinton p = q; 10929702Slinton 10939702Slinton } 10949702Slinton 10959702Slinton /* build comma op for args to function */ 10969702Slinton q = talloc(); 10979702Slinton q->in.op = CM; 10989702Slinton q->in.rall = NOPREF; 10999702Slinton q->in.type = INT; 11009702Slinton q->in.left = p->in.left; 11019702Slinton q->in.right = p->in.right; 11029702Slinton p->in.op = CALL; 11039702Slinton p->in.right = q; 11049702Slinton 11059702Slinton /* put function name in left node of call */ 11069702Slinton p->in.left = q = talloc(); 11079702Slinton q->in.op = ICON; 11089702Slinton q->in.rall = NOPREF; 11099702Slinton q->in.type = INCREF( FTN + p->in.type ); 11109702Slinton #ifndef FLEXNAMES 11119702Slinton strcpy( q->in.name, f->func ); 11129702Slinton #else 11139702Slinton q->in.name = f->func; 11149702Slinton #endif 11159702Slinton q->tn.lval = 0; 11169702Slinton q->tn.rval = 0; 11179702Slinton 11189702Slinton return; 11199702Slinton 11209702Slinton } 11219702Slinton 11229702Slinton zappost(p) NODE *p; { 11239702Slinton /* look for ++ and -- operators and remove them */ 11249702Slinton 11259702Slinton register o, ty; 11269702Slinton register NODE *q; 11279702Slinton o = p->in.op; 11289702Slinton ty = optype( o ); 11299702Slinton 11309702Slinton switch( o ){ 11319702Slinton 11329702Slinton case INCR: 11339702Slinton case DECR: 11349702Slinton q = p->in.left; 11359702Slinton p->in.right->in.op = FREE; /* zap constant */ 11369702Slinton ncopy( p, q ); 11379702Slinton q->in.op = FREE; 11389702Slinton return; 11399702Slinton 11409702Slinton } 11419702Slinton 11429702Slinton if( ty == BITYPE ) zappost( p->in.right ); 11439702Slinton if( ty != LTYPE ) zappost( p->in.left ); 11449702Slinton } 11459702Slinton 11469702Slinton fixpre(p) NODE *p; { 11479702Slinton 11489702Slinton register o, ty; 11499702Slinton o = p->in.op; 11509702Slinton ty = optype( o ); 11519702Slinton 11529702Slinton switch( o ){ 11539702Slinton 11549702Slinton case ASG PLUS: 11559702Slinton p->in.op = PLUS; 11569702Slinton break; 11579702Slinton case ASG MINUS: 11589702Slinton p->in.op = MINUS; 11599702Slinton break; 11609702Slinton } 11619702Slinton 11629702Slinton if( ty == BITYPE ) fixpre( p->in.right ); 11639702Slinton if( ty != LTYPE ) fixpre( p->in.left ); 11649702Slinton } 11659702Slinton 11669702Slinton myreader(p) register NODE *p; { 11679702Slinton walkf( p, hardops ); /* convert ops to function calls */ 11689702Slinton canon( p ); /* expands r-vals for fileds */ 11699702Slinton walkf( p, optim2 ); 11709702Slinton /* jwf toff = 0; /* stack offset swindle */ 11719702Slinton } 11729702Slinton 11739702Slinton 1174