1*17715Sralph static char *sccsid ="@(#)local2.c 1.7 (Berkeley) 01/15/85"; 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'); 21217208Sralph else if (p->in.op == SCONV) { 2139702Slinton l = resc; 21416181Sralph #ifdef FORT 21516181Sralph l->in.type = r->in.type; 21616181Sralph #else 21716181Sralph l->in.type = r->in.type==FLOAT ? DOUBLE : r->in.type; 21816181Sralph #endif 21916181Sralph r = getlr(p, 'L'); 22016181Sralph } 22117208Sralph else { /* OPLTYPE */ 22216181Sralph l = resc; 22316181Sralph #ifdef FORT 22416181Sralph l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? r->in.type : INT); 22516181Sralph #else 2269702Slinton l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); 22716181Sralph #endif 2289702Slinton } 2299702Slinton if (r->in.op == ICON) 23017208Sralph if (r->in.name[0] == '\0') { 23117208Sralph if (r->tn.lval == 0) { 2329702Slinton printf("clr"); 2339702Slinton prtype(l); 2349702Slinton printf(" "); 2359702Slinton adrput(l); 2369702Slinton return; 2379702Slinton } 23817208Sralph if (r->tn.lval < 0 && r->tn.lval >= -63) { 2399702Slinton printf("mneg"); 2409702Slinton prtype(l); 2419702Slinton r->tn.lval = -r->tn.lval; 2429702Slinton goto ops; 2439702Slinton } 24417208Sralph if (r->tn.lval < 0) 24517208Sralph r->in.type = r->tn.lval >= -128 ? CHAR 2469702Slinton : (r->tn.lval >= -32768 ? SHORT 24717208Sralph : INT); 24817208Sralph else if (l->in.type == FLOAT || 24917208Sralph l->in.type == DOUBLE) 25017208Sralph r->in.type = r->tn.lval <= 63 ? INT 25117208Sralph : (r->tn.lval <= 127 ? CHAR 25217208Sralph : (r->tn.lval <= 32767 ? SHORT 25317208Sralph : INT)); 25417208Sralph else 25517208Sralph r->in.type = r->tn.lval <= 63 ? INT 25617208Sralph : (r->tn.lval <= 127 ? CHAR 2579702Slinton : (r->tn.lval <= 255 ? UCHAR 2589702Slinton : (r->tn.lval <= 32767 ? SHORT 2599702Slinton : (r->tn.lval <= 65535 ? USHORT 26017208Sralph : INT)))); 2619702Slinton } 26217208Sralph else { 26316181Sralph printf("moval"); 26416181Sralph printf(" "); 26516181Sralph acon(r); 26616181Sralph printf(","); 26716181Sralph adrput(l); 26816181Sralph return; 26916181Sralph } 2709702Slinton 27117208Sralph if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) { 27217208Sralph if (tlen(l) < tlen(r) && !mixtypes(l,r)) { 27316181Sralph if (ISUNSIGNED(l->in.type)) 27416181Sralph printf("movz"); 2759702Slinton else 2769702Slinton printf("cvt"); 27716181Sralph prtype(l); 27816181Sralph printf("l"); 27916181Sralph goto ops; 2809702Slinton } 2819702Slinton else 28216181Sralph l->in.type = INT; 2839702Slinton } 28417208Sralph if (!mixtypes(l,r)) { 28517208Sralph if (tlen(l) == tlen(r)) { 2869702Slinton printf("mov"); 2879702Slinton prtype(l); 2889702Slinton goto ops; 2899702Slinton } 2909702Slinton else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) 2919702Slinton printf("movz"); 2929702Slinton else 2939702Slinton printf("cvt"); 2949702Slinton } 2959702Slinton else 2969702Slinton printf("cvt"); 2979702Slinton prtype(r); 2989702Slinton prtype(l); 2999702Slinton ops: 3009702Slinton printf(" "); 3019702Slinton adrput(r); 3029702Slinton printf(","); 3039702Slinton adrput(l); 3049702Slinton return; 3059702Slinton } 3069702Slinton 3079702Slinton case 'B': /* get oreg value in temp register for left shift */ 3089702Slinton { 3099702Slinton register NODE *r; 3109702Slinton if (xdebug) eprint(p, 0, &val, &val); 3119702Slinton r = p->in.right; 3129702Slinton if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) 3139702Slinton printf("movl"); 3149702Slinton else { 3159702Slinton printf("cvt"); 3169702Slinton prtype(r); 3179702Slinton printf("l"); 3189702Slinton } 3199702Slinton return; 3209702Slinton } 3219702Slinton 3229702Slinton case 'C': /* num words pushed on arg stack */ 3239702Slinton { 3249702Slinton extern int gc_numbytes; 3259702Slinton extern int xdebug; 3269702Slinton 3279702Slinton if (xdebug) printf("->%d<-",gc_numbytes); 3289702Slinton 3299702Slinton printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); 3309702Slinton return; 3319702Slinton } 3329702Slinton 3339702Slinton case 'D': /* INCR and DECR */ 3349702Slinton zzzcode(p->in.left, 'A'); 3359702Slinton printf("\n "); 3369702Slinton 3379702Slinton case 'E': /* INCR and DECR, FOREFF */ 3389702Slinton if (p->in.right->tn.lval == 1) 3399702Slinton { 3409702Slinton printf("%s", (p->in.op == INCR ? "inc" : "dec") ); 3419702Slinton prtype(p->in.left); 3429702Slinton printf(" "); 3439702Slinton adrput(p->in.left); 3449702Slinton return; 3459702Slinton } 3469702Slinton printf("%s", (p->in.op == INCR ? "add" : "sub") ); 3479702Slinton prtype(p->in.left); 3489702Slinton printf("2 "); 3499702Slinton adrput(p->in.right); 3509702Slinton printf(","); 3519702Slinton adrput(p->in.left); 3529702Slinton return; 3539702Slinton 3549702Slinton case 'F': /* register type of right operand */ 3559702Slinton { 3569702Slinton register NODE *n; 3579702Slinton extern int xdebug; 3589702Slinton register int ty; 3599702Slinton 3609702Slinton n = getlr( p, 'R' ); 3619702Slinton ty = n->in.type; 3629702Slinton 3639702Slinton if (xdebug) printf("->%d<-", ty); 3649702Slinton 3659702Slinton if ( ty==DOUBLE) printf("d"); 3669702Slinton else if ( ty==FLOAT ) printf("f"); 3679702Slinton else printf("l"); 3689702Slinton return; 3699702Slinton } 3709702Slinton 3719702Slinton case 'L': /* type of left operand */ 3729702Slinton case 'R': /* type of right operand */ 3739702Slinton { 3749702Slinton register NODE *n; 3759702Slinton extern int xdebug; 3769702Slinton 37716181Sralph n = getlr( p, c ); 3789702Slinton if (xdebug) printf("->%d<-", n->in.type); 3799702Slinton 3809702Slinton prtype(n); 3819702Slinton return; 3829702Slinton } 3839702Slinton 3849702Slinton case 'Z': /* complement mask for bit instr */ 3859702Slinton printf("$%ld", ~p->in.right->tn.lval); 3869702Slinton return; 3879702Slinton 3889702Slinton case 'U': /* 32 - n, for unsigned right shifts */ 3899702Slinton printf("$%d", 32 - p->in.right->tn.lval ); 3909702Slinton return; 3919702Slinton 3929702Slinton case 'T': /* rounded structure length for arguments */ 3939702Slinton { 3949702Slinton int size; 3959702Slinton 3969702Slinton size = p->stn.stsize; 3979702Slinton SETOFF( size, 4); 3989702Slinton printf("$%d", size); 3999702Slinton return; 4009702Slinton } 4019702Slinton 4029702Slinton case 'S': /* structure assignment */ 4039702Slinton { 4049702Slinton register NODE *l, *r; 4059702Slinton register size; 4069702Slinton 4079702Slinton if( p->in.op == STASG ){ 4089702Slinton l = p->in.left; 4099702Slinton r = p->in.right; 4109702Slinton 4119702Slinton } 4129702Slinton else if( p->in.op == STARG ){ /* store an arg into a temporary */ 4139702Slinton r = p->in.left; 4149702Slinton } 4159702Slinton else cerror( "STASG bad" ); 4169702Slinton 4179702Slinton if( r->in.op == ICON ) r->in.op = NAME; 4189702Slinton else if( r->in.op == REG ) r->in.op = OREG; 4199702Slinton else if( r->in.op != OREG ) cerror( "STASG-r" ); 4209702Slinton 4219702Slinton size = p->stn.stsize; 4229702Slinton 4239702Slinton if( size <= 0 || size > 65535 ) 4249702Slinton cerror("structure size <0=0 or >65535"); 4259702Slinton 4269702Slinton switch(size) { 4279702Slinton case 1: 4289702Slinton printf(" movb "); 4299702Slinton break; 4309702Slinton case 2: 4319702Slinton printf(" movw "); 4329702Slinton break; 4339702Slinton case 4: 4349702Slinton printf(" movl "); 4359702Slinton break; 4369702Slinton case 8: 4379702Slinton printf(" movq "); 4389702Slinton break; 4399702Slinton default: 4409702Slinton printf(" movc3 $%d,", size); 4419702Slinton break; 4429702Slinton } 4439702Slinton adrput(r); 44416418Sralph if( p->in.op == STASG ){ 44516418Sralph printf(","); 44616418Sralph adrput(l); 44716418Sralph printf("\n"); 44816418Sralph } 44916418Sralph else 45016418Sralph printf(",(sp)\n"); 4519702Slinton 4529702Slinton if( r->in.op == NAME ) r->in.op = ICON; 4539702Slinton else if( r->in.op == OREG ) r->in.op = REG; 4549702Slinton 4559702Slinton } 4569702Slinton break; 4579702Slinton 4589702Slinton default: 4599702Slinton cerror( "illegal zzzcode" ); 4609702Slinton } 4619702Slinton } 4629702Slinton 4639702Slinton rmove( rt, rs, t ){ 4649702Slinton printf( " %s %s,%s\n", 4659702Slinton (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), 4669702Slinton rnames[rs], rnames[rt] ); 4679702Slinton } 4689702Slinton 4699702Slinton struct respref 4709702Slinton respref[] = { 4719702Slinton INTAREG|INTBREG, INTAREG|INTBREG, 4729702Slinton INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, 4739702Slinton INTEMP, INTEMP, 4749702Slinton FORARG, FORARG, 4759702Slinton INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 4769702Slinton 0, 0 }; 4779702Slinton 4789702Slinton setregs(){ /* set up temporary registers */ 4799702Slinton fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ 4809702Slinton ; 4819702Slinton } 4829702Slinton 4839702Slinton szty(t){ /* size, in registers, needed to hold thing of type t */ 48416181Sralph #ifdef FORT 48516181Sralph return( (t==DOUBLE) ? 2 : 1 ); 48616181Sralph #else 4879702Slinton return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); 48816181Sralph #endif 4899702Slinton } 4909702Slinton 4919702Slinton rewfld( p ) NODE *p; { 4929702Slinton return(1); 4939702Slinton } 4949702Slinton 4959702Slinton callreg(p) NODE *p; { 4969702Slinton return( R0 ); 4979702Slinton } 4989702Slinton 4999702Slinton base( p ) register NODE *p; { 5009702Slinton register int o = p->in.op; 5019702Slinton 5029702Slinton if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ 5039702Slinton if( o==REG ) return( p->tn.rval ); 5049702Slinton if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) 5059702Slinton return( p->in.left->tn.rval ); 5069702Slinton if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5079702Slinton return( p->tn.rval + 0200*1 ); 5089702Slinton if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); 5099702Slinton if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); 5109702Slinton if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG 5119702Slinton && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5129702Slinton return( p->in.left->in.left->tn.rval + 0200*(1+2) ); 5139702Slinton return( -1 ); 5149702Slinton } 5159702Slinton 5169702Slinton offset( p, tyl ) register NODE *p; int tyl; { 5179702Slinton 5189702Slinton if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); 5199702Slinton if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && 5209702Slinton (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') 5219702Slinton && (1<<p->in.right->tn.lval)==tyl)) 5229702Slinton return( p->in.left->tn.rval ); 5239702Slinton return( -1 ); 5249702Slinton } 5259702Slinton 5269702Slinton makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { 5279702Slinton register NODE *t; 5289702Slinton register int i; 5299702Slinton NODE *f; 5309702Slinton 5319702Slinton p->in.op = OREG; 5329702Slinton f = p->in.left; /* have to free this subtree later */ 5339702Slinton 5349702Slinton /* init base */ 5359702Slinton switch (q->in.op) { 5369702Slinton case ICON: 5379702Slinton case REG: 5389702Slinton case OREG: 5399702Slinton t = q; 5409702Slinton break; 5419702Slinton 5429702Slinton case MINUS: 5439702Slinton q->in.right->tn.lval = -q->in.right->tn.lval; 5449702Slinton case PLUS: 5459702Slinton t = q->in.right; 5469702Slinton break; 5479702Slinton 5489702Slinton case INCR: 5499702Slinton case ASG MINUS: 5509702Slinton t = q->in.left; 5519702Slinton break; 5529702Slinton 5539702Slinton case UNARY MUL: 5549702Slinton t = q->in.left->in.left; 5559702Slinton break; 5569702Slinton 5579702Slinton default: 5589702Slinton cerror("illegal makeor2"); 5599702Slinton } 5609702Slinton 5619702Slinton p->tn.lval = t->tn.lval; 5629702Slinton #ifndef FLEXNAMES 5639702Slinton for(i=0; i<NCHNAM; ++i) 5649702Slinton p->in.name[i] = t->in.name[i]; 5659702Slinton #else 5669702Slinton p->in.name = t->in.name; 5679702Slinton #endif 5689702Slinton 5699702Slinton /* init offset */ 5709702Slinton p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); 5719702Slinton 5729702Slinton tfree(f); 5739702Slinton return; 5749702Slinton } 5759702Slinton 5769702Slinton canaddr( p ) NODE *p; { 5779702Slinton register int o = p->in.op; 5789702Slinton 5799702Slinton if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); 5809702Slinton return(0); 5819702Slinton } 5829702Slinton 5839702Slinton shltype( o, p ) register NODE *p; { 5849702Slinton return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); 5859702Slinton } 5869702Slinton 5879702Slinton flshape( p ) register NODE *p; { 5889702Slinton return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || 5899702Slinton (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); 5909702Slinton } 5919702Slinton 5929702Slinton shtemp( p ) register NODE *p; { 5939702Slinton if( p->in.op == STARG ) p = p->in.left; 5949702Slinton return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); 5959702Slinton } 5969702Slinton 5979702Slinton shumul( p ) register NODE *p; { 5989702Slinton register o; 5999702Slinton extern int xdebug; 6009702Slinton 6019702Slinton if (xdebug) { 6029702Slinton printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); 6039702Slinton printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); 6049702Slinton } 6059702Slinton 6069702Slinton 6079702Slinton o = p->in.op; 6089702Slinton if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); 6099702Slinton 6109702Slinton if( ( o == INCR || o == ASG MINUS ) && 6119702Slinton ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && 6129702Slinton p->in.right->in.name[0] == '\0' ) 6139702Slinton { 61417659Sralph switch (p->in.type) 6159702Slinton { 6169702Slinton case CHAR|PTR: 6179702Slinton case UCHAR|PTR: 6189702Slinton o = 1; 6199702Slinton break; 6209702Slinton 6219702Slinton case SHORT|PTR: 6229702Slinton case USHORT|PTR: 6239702Slinton o = 2; 6249702Slinton break; 6259702Slinton 6269702Slinton case INT|PTR: 6279702Slinton case UNSIGNED|PTR: 6289702Slinton case LONG|PTR: 6299702Slinton case ULONG|PTR: 6309702Slinton case FLOAT|PTR: 6319702Slinton o = 4; 6329702Slinton break; 6339702Slinton 6349702Slinton case DOUBLE|PTR: 6359702Slinton o = 8; 6369702Slinton break; 6379702Slinton 6389702Slinton default: 63917659Sralph if ( ISPTR(p->in.type) ) { 6409702Slinton o = 4; 6419702Slinton break; 6429702Slinton } 6439702Slinton else return(0); 6449702Slinton } 6459702Slinton return( p->in.right->tn.lval == o ? STARREG : 0); 6469702Slinton } 6479702Slinton 6489702Slinton return( 0 ); 6499702Slinton } 6509702Slinton 6519702Slinton adrcon( val ) CONSZ val; { 6529702Slinton printf( "$" ); 6539702Slinton printf( CONFMT, val ); 6549702Slinton } 6559702Slinton 6569702Slinton conput( p ) register NODE *p; { 6579702Slinton switch( p->in.op ){ 6589702Slinton 6599702Slinton case ICON: 6609702Slinton acon( p ); 6619702Slinton return; 6629702Slinton 6639702Slinton case REG: 6649702Slinton printf( "%s", rnames[p->tn.rval] ); 6659702Slinton return; 6669702Slinton 6679702Slinton default: 6689702Slinton cerror( "illegal conput" ); 6699702Slinton } 6709702Slinton } 6719702Slinton 6729702Slinton insput( p ) register NODE *p; { 6739702Slinton cerror( "insput" ); 6749702Slinton } 6759702Slinton 6769702Slinton upput( p ) register NODE *p; { 6779702Slinton cerror( "upput" ); 6789702Slinton } 6799702Slinton 6809702Slinton adrput( p ) register NODE *p; { 6819702Slinton register int r; 6829702Slinton /* output an address, with offsets, from p */ 6839702Slinton 6849702Slinton if( p->in.op == FLD ){ 6859702Slinton p = p->in.left; 6869702Slinton } 6879702Slinton switch( p->in.op ){ 6889702Slinton 6899702Slinton case NAME: 6909702Slinton acon( p ); 6919702Slinton return; 6929702Slinton 6939702Slinton case ICON: 6949702Slinton /* addressable value of the constant */ 6959702Slinton printf( "$" ); 6969702Slinton acon( p ); 6979702Slinton return; 6989702Slinton 6999702Slinton case REG: 7009702Slinton printf( "%s", rnames[p->tn.rval] ); 7019702Slinton return; 7029702Slinton 7039702Slinton case OREG: 7049702Slinton r = p->tn.rval; 7059702Slinton if( R2TEST(r) ){ /* double indexing */ 7069702Slinton register int flags; 7079702Slinton 7089702Slinton flags = R2UPK3(r); 7099702Slinton if( flags & 1 ) printf("*"); 7109702Slinton if( flags & 4 ) printf("-"); 7119702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); 7129702Slinton if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); 7139702Slinton if( flags & 2 ) printf("+"); 7149702Slinton printf( "[%s]", rnames[R2UPK2(r)] ); 7159702Slinton return; 7169702Slinton } 7179702Slinton if( r == AP ){ /* in the argument region */ 7189702Slinton if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); 7199702Slinton printf( CONFMT, p->tn.lval ); 7209702Slinton printf( "(ap)" ); 7219702Slinton return; 7229702Slinton } 7239702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); 7249702Slinton printf( "(%s)", rnames[p->tn.rval] ); 7259702Slinton return; 7269702Slinton 7279702Slinton case UNARY MUL: 7289702Slinton /* STARNM or STARREG found */ 7299702Slinton if( tshape(p, STARNM) ) { 7309702Slinton printf( "*" ); 7319702Slinton adrput( p->in.left); 7329702Slinton } 7339702Slinton else { /* STARREG - really auto inc or dec */ 7349702Slinton register NODE *q; 7359702Slinton 7369702Slinton /* tbl 7379702Slinton p = p->in.left; 7389702Slinton p->in.left->in.op = OREG; 7399702Slinton if( p->in.op == INCR ) { 7409702Slinton adrput( p->in.left ); 7419702Slinton printf( "+" ); 7429702Slinton } 7439702Slinton else { 7449702Slinton printf( "-" ); 7459702Slinton adrput( p->in.left ); 7469702Slinton } 7479702Slinton tbl */ 74817659Sralph q = p->in.left; 74917659Sralph printf("%s(%s)%s", (q->in.op==INCR ? "" : "-"), 75017659Sralph rnames[q->in.left->tn.rval], 75117659Sralph (q->in.op==INCR ? "+" : "") ); 7529702Slinton p->in.op = OREG; 75317659Sralph p->tn.rval = q->in.left->tn.rval; 75417659Sralph p->tn.lval = (q->in.op == INCR ? -q->in.right->tn.lval : 0); 7559702Slinton #ifndef FLEXNAMES 7569702Slinton p->in.name[0] = '\0'; 7579702Slinton #else 7589702Slinton p->in.name = ""; 7599702Slinton #endif 7609702Slinton tfree(q); 7619702Slinton } 7629702Slinton return; 7639702Slinton 7649702Slinton default: 7659702Slinton cerror( "illegal address" ); 7669702Slinton return; 7679702Slinton 7689702Slinton } 7699702Slinton 7709702Slinton } 7719702Slinton 7729702Slinton acon( p ) register NODE *p; { /* print out a constant */ 7739702Slinton 7749702Slinton if( p->in.name[0] == '\0' ){ 7759702Slinton printf( CONFMT, p->tn.lval); 7769702Slinton } 7779702Slinton else if( p->tn.lval == 0 ) { 7789702Slinton #ifndef FLEXNAMES 7799702Slinton printf( "%.8s", p->in.name ); 7809702Slinton #else 7819702Slinton printf( "%s", p->in.name ); 7829702Slinton #endif 7839702Slinton } 7849702Slinton else { 7859702Slinton #ifndef FLEXNAMES 7869702Slinton printf( "%.8s+", p->in.name ); 7879702Slinton #else 7889702Slinton printf( "%s+", p->in.name ); 7899702Slinton #endif 7909702Slinton printf( CONFMT, p->tn.lval ); 7919702Slinton } 7929702Slinton } 7939702Slinton 7949702Slinton /* 7959702Slinton aacon( p ) register NODE *p; { /* print out a constant */ 7969702Slinton /* 7979702Slinton 7989702Slinton if( p->in.name[0] == '\0' ){ 7999702Slinton printf( CONFMT, p->tn.lval); 8009702Slinton return( 0 ); 8019702Slinton } 8029702Slinton else if( p->tn.lval == 0 ) { 8039702Slinton #ifndef FLEXNAMES 8049702Slinton printf( "$%.8s", p->in.name ); 8059702Slinton #else 8069702Slinton printf( "$%s", p->in.name ); 8079702Slinton #endif 8089702Slinton return( 1 ); 8099702Slinton } 8109702Slinton else { 8119702Slinton printf( "$(" ); 8129702Slinton printf( CONFMT, p->tn.lval ); 8139702Slinton printf( "+" ); 8149702Slinton #ifndef FLEXNAMES 8159702Slinton printf( "%.8s)", p->in.name ); 8169702Slinton #else 8179702Slinton printf( "%s)", p->in.name ); 8189702Slinton #endif 8199702Slinton return(1); 8209702Slinton } 8219702Slinton } 8229702Slinton */ 8239702Slinton 8249702Slinton genscall( p, cookie ) register NODE *p; { 8259702Slinton /* structure valued call */ 8269702Slinton return( gencall( p, cookie ) ); 8279702Slinton } 8289702Slinton 8299702Slinton /* tbl */ 8309702Slinton int gc_numbytes; 8319702Slinton /* tbl */ 8329702Slinton 8339702Slinton gencall( p, cookie ) register NODE *p; { 8349702Slinton /* generate the call given by p */ 83516418Sralph register NODE *p1; 8369702Slinton register temp, temp1; 8379702Slinton register m; 8389702Slinton 8399702Slinton if( p->in.right ) temp = argsize( p->in.right ); 8409702Slinton else temp = 0; 8419702Slinton 8429702Slinton if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ 8439702Slinton /* set aside room for structure return */ 8449702Slinton 8459702Slinton if( p->stn.stsize > temp ) temp1 = p->stn.stsize; 8469702Slinton else temp1 = temp; 8479702Slinton } 8489702Slinton 8499702Slinton if( temp > maxargs ) maxargs = temp; 8509702Slinton SETOFF(temp1,4); 8519702Slinton 8529702Slinton if( p->in.right ){ /* make temp node, put offset in, and generate args */ 85316418Sralph genargs( p->in.right ); 8549702Slinton } 8559702Slinton 8569702Slinton p1 = p->in.left; 8579702Slinton if( p1->in.op != ICON ){ 8589702Slinton if( p1->in.op != REG ){ 8599702Slinton if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ 8609702Slinton if( p1->in.op != NAME ){ 8619702Slinton order( p1, INAREG ); 8629702Slinton } 8639702Slinton } 8649702Slinton } 8659702Slinton } 8669702Slinton 8679702Slinton /* 8689702Slinton if( p1->in.op == REG && p->tn.rval == R5 ){ 8699702Slinton cerror( "call register overwrite" ); 8709702Slinton } 8719702Slinton */ 8729702Slinton /* tbl 8739702Slinton setup gc_numbytes so reference to ZC works */ 8749702Slinton 8759702Slinton gc_numbytes = temp&(0x3ff); 8769702Slinton /* tbl */ 8779702Slinton 8789702Slinton p->in.op = UNARY CALL; 8799702Slinton m = match( p, INTAREG|INTBREG ); 8809702Slinton 8819702Slinton /* compensate for deficiency in 'ret' instruction ... wah,kre */ 8829702Slinton /* (plus in assignment to gc_numbytes above, for neatness only) */ 8839702Slinton if (temp >= 1024) 8849702Slinton printf(" addl2 $%d,sp\n", (temp&(~0x3ff))); 8859702Slinton 8869702Slinton /* tbl 8879702Slinton switch( temp ) { 8889702Slinton case 0: 8899702Slinton break; 8909702Slinton case 2: 8919702Slinton printf( " tst (sp)+\n" ); 8929702Slinton break; 8939702Slinton case 4: 8949702Slinton printf( " cmp (sp)+,(sp)+\n" ); 8959702Slinton break; 8969702Slinton default: 8979702Slinton printf( " add $%d,sp\n", temp); 8989702Slinton } 8999702Slinton tbl */ 9009702Slinton return(m != MDONE); 9019702Slinton } 9029702Slinton 9039702Slinton /* tbl */ 9049702Slinton char * 9059702Slinton ccbranches[] = { 9069702Slinton " jeql L%d\n", 9079702Slinton " jneq L%d\n", 9089702Slinton " jleq L%d\n", 9099702Slinton " jlss L%d\n", 9109702Slinton " jgeq L%d\n", 9119702Slinton " jgtr L%d\n", 9129702Slinton " jlequ L%d\n", 9139702Slinton " jlssu L%d\n", 9149702Slinton " jgequ L%d\n", 9159702Slinton " jgtru L%d\n", 9169702Slinton }; 9179702Slinton /* tbl */ 9189702Slinton 9199702Slinton cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 9209702Slinton 9219702Slinton /* tbl */ 9229702Slinton if( o == 0 ) printf( " jbr L%d\n", lab ); 9239702Slinton /* tbl */ 9249702Slinton else { 9259702Slinton if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 9269702Slinton printf( ccbranches[o-EQ], lab ); 9279702Slinton } 9289702Slinton } 9299702Slinton 9309702Slinton nextcook( p, cookie ) NODE *p; { 9319702Slinton /* we have failed to match p with cookie; try another */ 9329702Slinton if( cookie == FORREW ) return( 0 ); /* hopeless! */ 9339702Slinton if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 9349702Slinton if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 9359702Slinton return( FORREW ); 9369702Slinton } 9379702Slinton 9389702Slinton lastchance( p, cook ) NODE *p; { 9399702Slinton /* forget it! */ 9409702Slinton return(0); 9419702Slinton } 9429702Slinton 9439702Slinton optim2( p ) register NODE *p; { 9449702Slinton /* do local tree transformations and optimizations */ 9459702Slinton 94616181Sralph register NODE *l, *r; 94716181Sralph int m, ml; 9489702Slinton 9499702Slinton switch( p->in.op ) { 9509702Slinton 9519702Slinton case AND: 9529702Slinton /* commute L and R to eliminate compliments and constants */ 95316181Sralph if( (l = p->in.left)->in.op == ICON && l->in.name[0] == 0 || 95416181Sralph l->in.op == COMPL ) { 9559702Slinton p->in.left = p->in.right; 95616181Sralph p->in.right = l; 9579702Slinton } 9589702Slinton case ASG AND: 9599702Slinton /* change meaning of AND to ~R&L - bic on pdp11 */ 9609702Slinton r = p->in.right; 9619702Slinton if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */ 9629702Slinton r->tn.lval = ~r->tn.lval; 9639702Slinton } 9649702Slinton else if( r->in.op==COMPL ) { /* ~~A => A */ 9659702Slinton r->in.op = FREE; 9669702Slinton p->in.right = r->in.left; 9679702Slinton } 9689702Slinton else { /* insert complement node */ 96916181Sralph p->in.right = l = talloc(); 97016181Sralph l->in.op = COMPL; 97116181Sralph l->in.rall = NOPREF; 97216181Sralph l->in.type = r->in.type; 97316181Sralph l->in.left = r; 97416181Sralph l->in.right = NULL; 9759702Slinton } 9769702Slinton break; 9779702Slinton 97816181Sralph case SCONV: 97916573Sralph #ifdef FORT 98016573Sralph if( p->in.type == FLOAT || p->in.type == DOUBLE || 98116573Sralph (l = p->in.left)->in.type == FLOAT || l->in.type == DOUBLE ) 98216573Sralph break; 98316573Sralph #else 98416181Sralph m = (p->in.type == FLOAT || p->in.type == DOUBLE); 98516181Sralph ml = ((l = p->in.left)->in.type == FLOAT || l->in.type == DOUBLE); 98616181Sralph if( m != ml ) break; 98716573Sralph #endif 98816181Sralph m = p->in.type; 98916181Sralph ml = l->in.type; 99016181Sralph /* meaningful ones are conversion of int to char, int to short, 99116181Sralph and short to char, and unsigned version of them */ 99216181Sralph if( m==CHAR || m==UCHAR ){ 99316181Sralph if( ml!=CHAR && ml!= UCHAR ) 99416181Sralph break; 99516181Sralph } 99616181Sralph else if( m==SHORT || m==USHORT ){ 99716181Sralph if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) 99816181Sralph break; 99916181Sralph } 100016181Sralph 100116181Sralph /* clobber conversion */ 100216181Sralph if( tlen( p ) == tlen( l ) && l->in.op != FLD ) 100316181Sralph l->in.type = p->in.type; 100416181Sralph ncopy( p, l ); 100516181Sralph l->in.op = FREE; 100616181Sralph break; 100716181Sralph 10089702Slinton } 10099702Slinton } 10109702Slinton 10119702Slinton NODE * addroreg(l) 10129702Slinton /* OREG was built in clocal() 10139702Slinton * for an auto or formal parameter 10149702Slinton * now its address is being taken 10159702Slinton * local code must unwind it 10169702Slinton * back to PLUS/MINUS REG ICON 10179702Slinton * according to local conventions 10189702Slinton */ 10199702Slinton { 10209702Slinton cerror("address of OREG taken"); 10219702Slinton } 10229702Slinton 10239702Slinton 10249702Slinton 10259702Slinton # ifndef ONEPASS 10269702Slinton main( argc, argv ) char *argv[]; { 10279702Slinton return( mainp2( argc, argv ) ); 10289702Slinton } 10299702Slinton # endif 10309702Slinton 10319702Slinton 10329702Slinton /* added by jwf */ 10339702Slinton struct functbl { 10349702Slinton int fop; 10359702Slinton TWORD ftype; 10369702Slinton char *func; 10379702Slinton } opfunc[] = { 10389702Slinton DIV, TANY, "udiv", 10399702Slinton MOD, TANY, "urem", 1040*17715Sralph ASG DIV, TANY, "audiv", 1041*17715Sralph ASG MOD, TANY, "aurem", 10429702Slinton 0, 0, 0 }; 10439702Slinton 10449702Slinton hardops(p) register NODE *p; { 10459702Slinton /* change hard to do operators into function calls. */ 10469702Slinton register NODE *q; 10479702Slinton register struct functbl *f; 10489702Slinton register o; 10499702Slinton register TWORD t; 10509702Slinton 10519702Slinton o = p->in.op; 10529702Slinton t = p->in.type; 10539702Slinton if( t!=UNSIGNED && t!=ULONG ) return; 10549702Slinton 10559702Slinton for( f=opfunc; f->fop; f++ ) { 10569702Slinton if( o==f->fop ) goto convert; 10579702Slinton } 10589702Slinton return; 10599702Slinton 10609702Slinton convert: 10619702Slinton if( asgop( o ) ) { 1062*17715Sralph switch( p->in.left->in.op ){ 1063*17715Sralph case REG: 1064*17715Sralph case NAME: 1065*17715Sralph case OREG: 1066*17715Sralph /* change ASG OP to a simple OP */ 1067*17715Sralph q = talloc(); 1068*17715Sralph q->in.op = NOASG p->in.op; 1069*17715Sralph q->in.rall = NOPREF; 1070*17715Sralph q->in.type = p->in.type; 1071*17715Sralph q->in.left = tcopy(p->in.left); 1072*17715Sralph q->in.right = p->in.right; 1073*17715Sralph p->in.op = ASSIGN; 1074*17715Sralph p->in.right = q; 1075*17715Sralph p = q; 1076*17715Sralph f -= 2; /* Note: this depends on the table order */ 1077*17715Sralph break; 10789702Slinton 1079*17715Sralph case UNARY MUL: 1080*17715Sralph /* avoid doing side effects twice */ 1081*17715Sralph q = p->in.left; 1082*17715Sralph p->in.left = q->in.left; 1083*17715Sralph q->in.op = FREE; 1084*17715Sralph break; 1085*17715Sralph 1086*17715Sralph default: 1087*17715Sralph cerror( "hardops: can't compute & LHS" ); 1088*17715Sralph } 1089*17715Sralph 10909702Slinton } 10919702Slinton 10929702Slinton /* build comma op for args to function */ 10939702Slinton q = talloc(); 10949702Slinton q->in.op = CM; 10959702Slinton q->in.rall = NOPREF; 10969702Slinton q->in.type = INT; 10979702Slinton q->in.left = p->in.left; 10989702Slinton q->in.right = p->in.right; 10999702Slinton p->in.op = CALL; 11009702Slinton p->in.right = q; 11019702Slinton 11029702Slinton /* put function name in left node of call */ 11039702Slinton p->in.left = q = talloc(); 11049702Slinton q->in.op = ICON; 11059702Slinton q->in.rall = NOPREF; 11069702Slinton q->in.type = INCREF( FTN + p->in.type ); 11079702Slinton #ifndef FLEXNAMES 11089702Slinton strcpy( q->in.name, f->func ); 11099702Slinton #else 11109702Slinton q->in.name = f->func; 11119702Slinton #endif 11129702Slinton q->tn.lval = 0; 11139702Slinton q->tn.rval = 0; 11149702Slinton 11159702Slinton } 11169702Slinton 11179702Slinton myreader(p) register NODE *p; { 11189702Slinton walkf( p, hardops ); /* convert ops to function calls */ 11199702Slinton canon( p ); /* expands r-vals for fileds */ 11209702Slinton walkf( p, optim2 ); 11219702Slinton /* jwf toff = 0; /* stack offset swindle */ 11229702Slinton } 11239702Slinton 11249702Slinton 1125