117742Sralph # ifndef lint 2*19933Smckusick static char *sccsid ="@(#)local2.c 1.10 (Berkeley) 05/03/85"; 317742Sralph # endif 417742Sralph 518556Sralph # include "pass2.h" 69702Slinton # include "ctype.h" 79702Slinton # ifdef FORT 89702Slinton int ftlab1, ftlab2; 99702Slinton # endif 109702Slinton /* a lot of the machine dependent parts of the second pass */ 119702Slinton 129702Slinton # define BITMASK(n) ((1L<<n)-1) 139702Slinton 149702Slinton where(c){ 159702Slinton fprintf( stderr, "%s, line %d: ", filename, lineno ); 169702Slinton } 179702Slinton 189702Slinton lineid( l, fn ) char *fn; { 199702Slinton /* identify line l and file fn */ 209702Slinton printf( "# line %d, file %s\n", l, fn ); 219702Slinton } 229702Slinton 239702Slinton 249702Slinton eobl2(){ 259702Slinton OFFSZ spoff; /* offset from stack pointer */ 269702Slinton #ifdef FORT 279702Slinton spoff = maxoff; 289702Slinton if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 299702Slinton spoff /= SZCHAR; 309702Slinton SETOFF(spoff,4); 319702Slinton #ifndef FLEXNAMES 329702Slinton printf( " .set .F%d,%ld\n", ftnno, spoff ); 339702Slinton #else 349702Slinton /* SHOULD BE L%d ... ftnno but must change pc/f77 */ 359702Slinton printf( " .set LF%d,%ld\n", ftnno, spoff ); 369702Slinton #endif 379702Slinton #else 389702Slinton extern int ftlab1, ftlab2; 399702Slinton 409702Slinton spoff = maxoff; 419702Slinton if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 429702Slinton spoff /= SZCHAR; 439702Slinton SETOFF(spoff,4); 449702Slinton printf( "L%d:\n", ftlab1); 459702Slinton if( spoff!=0 ) 469702Slinton if( spoff < 64 ) 479702Slinton printf( " subl2 $%ld,sp\n", spoff); 489702Slinton else 499702Slinton printf( " movab -%ld(sp),sp\n", spoff); 509702Slinton printf( " jbr L%d\n", ftlab2); 519702Slinton #endif 529702Slinton maxargs = -1; 539702Slinton } 549702Slinton 559702Slinton struct hoptab { int opmask; char * opstring; } ioptab[] = { 569702Slinton 579702Slinton ASG PLUS, "add", 589702Slinton ASG MINUS, "sub", 599702Slinton ASG MUL, "mul", 609702Slinton ASG DIV, "div", 619702Slinton ASG OR, "bis", 629702Slinton ASG ER, "xor", 639702Slinton ASG AND, "bic", 649702Slinton PLUS, "add", 659702Slinton MINUS, "sub", 669702Slinton MUL, "mul", 679702Slinton DIV, "div", 689702Slinton OR, "bis", 699702Slinton ER, "xor", 709702Slinton AND, "bic", 719702Slinton -1, "" }; 729702Slinton 739702Slinton hopcode( f, o ){ 749702Slinton /* output the appropriate string from the above table */ 759702Slinton 769702Slinton register struct hoptab *q; 779702Slinton 789702Slinton for( q = ioptab; q->opmask>=0; ++q ){ 799702Slinton if( q->opmask == o ){ 809702Slinton printf( "%s", q->opstring ); 819702Slinton /* tbl 829702Slinton if( f == 'F' ) printf( "e" ); 839702Slinton else if( f == 'D' ) printf( "d" ); 849702Slinton tbl */ 859702Slinton /* tbl */ 869702Slinton switch( f ) { 879702Slinton case 'L': 889702Slinton case 'W': 899702Slinton case 'B': 909702Slinton case 'D': 919702Slinton case 'F': 929702Slinton printf("%c", tolower(f)); 939702Slinton break; 949702Slinton 959702Slinton } 969702Slinton /* tbl */ 979702Slinton return; 989702Slinton } 999702Slinton } 1009702Slinton cerror( "no hoptab for %s", opst[o] ); 1019702Slinton } 1029702Slinton 1039702Slinton char * 1049702Slinton rnames[] = { /* keyed to register number tokens */ 1059702Slinton 1069702Slinton "r0", "r1", 1079702Slinton "r2", "r3", "r4", "r5", 1089702Slinton "r6", "r7", "r8", "r9", "r10", "r11", 1099702Slinton "ap", "fp", "sp", "pc", 1109702Slinton 1119702Slinton }; 1129702Slinton 1139702Slinton int rstatus[] = { 1149702Slinton SAREG|STAREG, SAREG|STAREG, 1159702Slinton SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, 1169702Slinton SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, 1179702Slinton SAREG, SAREG, SAREG, SAREG, 1189702Slinton 1199702Slinton }; 1209702Slinton 1219702Slinton tlen(p) NODE *p; 1229702Slinton { 1239702Slinton switch(p->in.type) { 1249702Slinton case CHAR: 1259702Slinton case UCHAR: 1269702Slinton return(1); 1279702Slinton 1289702Slinton case SHORT: 1299702Slinton case USHORT: 1309702Slinton return(2); 1319702Slinton 1329702Slinton case DOUBLE: 1339702Slinton return(8); 1349702Slinton 1359702Slinton default: 1369702Slinton return(4); 1379702Slinton } 1389702Slinton } 1399702Slinton 1409702Slinton mixtypes(p, q) NODE *p, *q; 1419702Slinton { 14216181Sralph register TWORD tp, tq; 1439702Slinton 1449702Slinton tp = p->in.type; 1459702Slinton tq = q->in.type; 1469702Slinton 1479702Slinton return( (tp==FLOAT || tp==DOUBLE) != 1489702Slinton (tq==FLOAT || tq==DOUBLE) ); 1499702Slinton } 1509702Slinton 1519702Slinton prtype(n) NODE *n; 1529702Slinton { 1539702Slinton switch (n->in.type) 1549702Slinton { 1559702Slinton case DOUBLE: 1569702Slinton printf("d"); 1579702Slinton return; 1589702Slinton 1599702Slinton case FLOAT: 1609702Slinton printf("f"); 1619702Slinton return; 1629702Slinton 1639702Slinton case LONG: 1649702Slinton case ULONG: 1659702Slinton case INT: 1669702Slinton case UNSIGNED: 1679702Slinton printf("l"); 1689702Slinton return; 1699702Slinton 1709702Slinton case SHORT: 1719702Slinton case USHORT: 1729702Slinton printf("w"); 1739702Slinton return; 1749702Slinton 1759702Slinton case CHAR: 1769702Slinton case UCHAR: 1779702Slinton printf("b"); 1789702Slinton return; 1799702Slinton 1809702Slinton default: 1819702Slinton if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type"); 1829702Slinton else { 1839702Slinton printf("l"); 1849702Slinton return; 1859702Slinton } 1869702Slinton } 1879702Slinton } 1889702Slinton 1899702Slinton zzzcode( p, c ) register NODE *p; { 1909702Slinton register m; 1919702Slinton CONSZ val; 1929702Slinton switch( c ){ 1939702Slinton 1949702Slinton case 'N': /* logical ops, turned into 0-1 */ 1959702Slinton /* use register given by register 1 */ 1969702Slinton cbgen( 0, m=getlab(), 'I' ); 1979702Slinton deflab( p->bn.label ); 1989702Slinton printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] ); 1999702Slinton deflab( m ); 2009702Slinton return; 2019702Slinton 2029702Slinton case 'I': 2039702Slinton case 'P': 2049702Slinton cbgen( p->in.op, p->bn.label, c ); 2059702Slinton return; 2069702Slinton 2079702Slinton case 'A': 2089702Slinton { 2099702Slinton register NODE *l, *r; 2109702Slinton 2119702Slinton if (xdebug) eprint(p, 0, &val, &val); 2129702Slinton r = getlr(p, 'R'); 21316181Sralph if (p->in.op == ASSIGN) 21416181Sralph l = getlr(p, 'L'); 21517208Sralph else if (p->in.op == SCONV) { 2169702Slinton l = resc; 21717742Sralph #if defined(FORT) || defined(SPRECC) 21816181Sralph l->in.type = r->in.type; 21916181Sralph #else 22016181Sralph l->in.type = r->in.type==FLOAT ? DOUBLE : r->in.type; 22116181Sralph #endif 22216181Sralph r = getlr(p, 'L'); 22316181Sralph } 22417208Sralph else { /* OPLTYPE */ 22516181Sralph l = resc; 22617742Sralph #if defined(FORT) || defined(SPRECC) 22716181Sralph l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? r->in.type : INT); 22816181Sralph #else 2299702Slinton l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); 23016181Sralph #endif 2319702Slinton } 2329702Slinton if (r->in.op == ICON) 23317208Sralph if (r->in.name[0] == '\0') { 23417208Sralph if (r->tn.lval == 0) { 2359702Slinton printf("clr"); 2369702Slinton prtype(l); 2379702Slinton printf(" "); 2389702Slinton adrput(l); 2399702Slinton return; 2409702Slinton } 24117208Sralph if (r->tn.lval < 0 && r->tn.lval >= -63) { 2429702Slinton printf("mneg"); 2439702Slinton prtype(l); 2449702Slinton r->tn.lval = -r->tn.lval; 2459702Slinton goto ops; 2469702Slinton } 24717208Sralph if (r->tn.lval < 0) 24817208Sralph r->in.type = r->tn.lval >= -128 ? CHAR 2499702Slinton : (r->tn.lval >= -32768 ? SHORT 25017208Sralph : INT); 25117208Sralph else if (l->in.type == FLOAT || 25217208Sralph l->in.type == DOUBLE) 25317208Sralph r->in.type = r->tn.lval <= 63 ? INT 25417208Sralph : (r->tn.lval <= 127 ? CHAR 25517208Sralph : (r->tn.lval <= 32767 ? SHORT 25617208Sralph : INT)); 25717208Sralph else 25817208Sralph r->in.type = r->tn.lval <= 63 ? INT 25917208Sralph : (r->tn.lval <= 127 ? CHAR 2609702Slinton : (r->tn.lval <= 255 ? UCHAR 2619702Slinton : (r->tn.lval <= 32767 ? SHORT 2629702Slinton : (r->tn.lval <= 65535 ? USHORT 26317208Sralph : INT)))); 2649702Slinton } 26517208Sralph else { 26616181Sralph printf("moval"); 26716181Sralph printf(" "); 26816181Sralph acon(r); 26916181Sralph printf(","); 27016181Sralph adrput(l); 27116181Sralph return; 27216181Sralph } 2739702Slinton 27417208Sralph if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) { 27517208Sralph if (tlen(l) < tlen(r) && !mixtypes(l,r)) { 27616181Sralph if (ISUNSIGNED(l->in.type)) 27716181Sralph printf("movz"); 2789702Slinton else 2799702Slinton printf("cvt"); 28016181Sralph prtype(l); 28116181Sralph printf("l"); 28216181Sralph goto ops; 2839702Slinton } 2849702Slinton else 28516181Sralph l->in.type = INT; 2869702Slinton } 28717208Sralph if (!mixtypes(l,r)) { 28817208Sralph if (tlen(l) == tlen(r)) { 2899702Slinton printf("mov"); 29017742Sralph #ifdef FORT 29117742Sralph if (Oflag) 29217742Sralph prtype(l); 29317742Sralph else { 29417742Sralph if (l->in.type == DOUBLE) 29517742Sralph printf("q"); 29617742Sralph else if(l->in.type == FLOAT) 29717742Sralph printf("l"); 29817742Sralph else 29917742Sralph prtype(l); 30017742Sralph } 30117742Sralph #else 3029702Slinton prtype(l); 30317742Sralph #endif FORT 3049702Slinton goto ops; 3059702Slinton } 3069702Slinton else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) 3079702Slinton printf("movz"); 3089702Slinton else 3099702Slinton printf("cvt"); 3109702Slinton } 3119702Slinton else 3129702Slinton printf("cvt"); 3139702Slinton prtype(r); 3149702Slinton prtype(l); 3159702Slinton ops: 3169702Slinton printf(" "); 3179702Slinton adrput(r); 3189702Slinton printf(","); 3199702Slinton adrput(l); 3209702Slinton return; 3219702Slinton } 3229702Slinton 3239702Slinton case 'B': /* get oreg value in temp register for left shift */ 3249702Slinton { 3259702Slinton register NODE *r; 3269702Slinton if (xdebug) eprint(p, 0, &val, &val); 3279702Slinton r = p->in.right; 3289702Slinton if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) 3299702Slinton printf("movl"); 3309702Slinton else { 3319702Slinton printf("cvt"); 3329702Slinton prtype(r); 3339702Slinton printf("l"); 3349702Slinton } 3359702Slinton return; 3369702Slinton } 3379702Slinton 3389702Slinton case 'C': /* num words pushed on arg stack */ 3399702Slinton { 3409702Slinton extern int gc_numbytes; 3419702Slinton extern int xdebug; 3429702Slinton 3439702Slinton if (xdebug) printf("->%d<-",gc_numbytes); 3449702Slinton 3459702Slinton printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); 3469702Slinton return; 3479702Slinton } 3489702Slinton 3499702Slinton case 'D': /* INCR and DECR */ 3509702Slinton zzzcode(p->in.left, 'A'); 3519702Slinton printf("\n "); 3529702Slinton 3539702Slinton case 'E': /* INCR and DECR, FOREFF */ 3549702Slinton if (p->in.right->tn.lval == 1) 3559702Slinton { 3569702Slinton printf("%s", (p->in.op == INCR ? "inc" : "dec") ); 3579702Slinton prtype(p->in.left); 3589702Slinton printf(" "); 3599702Slinton adrput(p->in.left); 3609702Slinton return; 3619702Slinton } 3629702Slinton printf("%s", (p->in.op == INCR ? "add" : "sub") ); 3639702Slinton prtype(p->in.left); 3649702Slinton printf("2 "); 3659702Slinton adrput(p->in.right); 3669702Slinton printf(","); 3679702Slinton adrput(p->in.left); 3689702Slinton return; 3699702Slinton 3709702Slinton case 'F': /* register type of right operand */ 3719702Slinton { 3729702Slinton register NODE *n; 3739702Slinton extern int xdebug; 3749702Slinton register int ty; 3759702Slinton 3769702Slinton n = getlr( p, 'R' ); 3779702Slinton ty = n->in.type; 3789702Slinton 3799702Slinton if (xdebug) printf("->%d<-", ty); 3809702Slinton 3819702Slinton if ( ty==DOUBLE) printf("d"); 3829702Slinton else if ( ty==FLOAT ) printf("f"); 3839702Slinton else printf("l"); 3849702Slinton return; 3859702Slinton } 3869702Slinton 3879702Slinton case 'L': /* type of left operand */ 3889702Slinton case 'R': /* type of right operand */ 3899702Slinton { 3909702Slinton register NODE *n; 3919702Slinton extern int xdebug; 3929702Slinton 39316181Sralph n = getlr( p, c ); 3949702Slinton if (xdebug) printf("->%d<-", n->in.type); 3959702Slinton 3969702Slinton prtype(n); 3979702Slinton return; 3989702Slinton } 3999702Slinton 4009702Slinton case 'Z': /* complement mask for bit instr */ 4019702Slinton printf("$%ld", ~p->in.right->tn.lval); 4029702Slinton return; 4039702Slinton 4049702Slinton case 'U': /* 32 - n, for unsigned right shifts */ 4059702Slinton printf("$%d", 32 - p->in.right->tn.lval ); 4069702Slinton return; 4079702Slinton 4089702Slinton case 'T': /* rounded structure length for arguments */ 4099702Slinton { 4109702Slinton int size; 4119702Slinton 4129702Slinton size = p->stn.stsize; 4139702Slinton SETOFF( size, 4); 4149702Slinton printf("$%d", size); 4159702Slinton return; 4169702Slinton } 4179702Slinton 4189702Slinton case 'S': /* structure assignment */ 4199702Slinton { 4209702Slinton register NODE *l, *r; 4219702Slinton register size; 4229702Slinton 4239702Slinton if( p->in.op == STASG ){ 4249702Slinton l = p->in.left; 4259702Slinton r = p->in.right; 4269702Slinton 4279702Slinton } 4289702Slinton else if( p->in.op == STARG ){ /* store an arg into a temporary */ 4299702Slinton r = p->in.left; 4309702Slinton } 4319702Slinton else cerror( "STASG bad" ); 4329702Slinton 4339702Slinton if( r->in.op == ICON ) r->in.op = NAME; 4349702Slinton else if( r->in.op == REG ) r->in.op = OREG; 4359702Slinton else if( r->in.op != OREG ) cerror( "STASG-r" ); 4369702Slinton 4379702Slinton size = p->stn.stsize; 4389702Slinton 4399702Slinton if( size <= 0 || size > 65535 ) 4409702Slinton cerror("structure size <0=0 or >65535"); 4419702Slinton 4429702Slinton switch(size) { 4439702Slinton case 1: 4449702Slinton printf(" movb "); 4459702Slinton break; 4469702Slinton case 2: 4479702Slinton printf(" movw "); 4489702Slinton break; 4499702Slinton case 4: 4509702Slinton printf(" movl "); 4519702Slinton break; 4529702Slinton case 8: 4539702Slinton printf(" movq "); 4549702Slinton break; 4559702Slinton default: 4569702Slinton printf(" movc3 $%d,", size); 4579702Slinton break; 4589702Slinton } 4599702Slinton adrput(r); 46016418Sralph if( p->in.op == STASG ){ 46116418Sralph printf(","); 46216418Sralph adrput(l); 46316418Sralph printf("\n"); 46416418Sralph } 46516418Sralph else 46616418Sralph printf(",(sp)\n"); 4679702Slinton 4689702Slinton if( r->in.op == NAME ) r->in.op = ICON; 4699702Slinton else if( r->in.op == OREG ) r->in.op = REG; 4709702Slinton 4719702Slinton } 4729702Slinton break; 4739702Slinton 4749702Slinton default: 4759702Slinton cerror( "illegal zzzcode" ); 4769702Slinton } 4779702Slinton } 4789702Slinton 47917742Sralph rmove( rt, rs, t ) TWORD t; { 4809702Slinton printf( " %s %s,%s\n", 48117742Sralph #ifdef FORT 48217742Sralph !Oflag ? (t==DOUBLE ? "movq" : "movl") : 48317742Sralph #endif 4849702Slinton (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), 4859702Slinton rnames[rs], rnames[rt] ); 4869702Slinton } 4879702Slinton 4889702Slinton struct respref 4899702Slinton respref[] = { 4909702Slinton INTAREG|INTBREG, INTAREG|INTBREG, 4919702Slinton INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, 4929702Slinton INTEMP, INTEMP, 4939702Slinton FORARG, FORARG, 4949702Slinton INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 4959702Slinton 0, 0 }; 4969702Slinton 4979702Slinton setregs(){ /* set up temporary registers */ 4989702Slinton fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ 4999702Slinton ; 5009702Slinton } 5019702Slinton 50217742Sralph szty(t) TWORD t; { /* size, in registers, needed to hold thing of type t */ 50317742Sralph #if defined(FORT) || defined(SPRECC) 50416181Sralph return( (t==DOUBLE) ? 2 : 1 ); 50516181Sralph #else 5069702Slinton return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); 50716181Sralph #endif 5089702Slinton } 5099702Slinton 5109702Slinton rewfld( p ) NODE *p; { 5119702Slinton return(1); 5129702Slinton } 5139702Slinton 5149702Slinton callreg(p) NODE *p; { 5159702Slinton return( R0 ); 5169702Slinton } 5179702Slinton 5189702Slinton base( p ) register NODE *p; { 5199702Slinton register int o = p->in.op; 5209702Slinton 5219702Slinton if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ 5229702Slinton if( o==REG ) return( p->tn.rval ); 5239702Slinton if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) 5249702Slinton return( p->in.left->tn.rval ); 5259702Slinton if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5269702Slinton return( p->tn.rval + 0200*1 ); 5279702Slinton if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); 5289702Slinton if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); 5299702Slinton if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG 5309702Slinton && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 5319702Slinton return( p->in.left->in.left->tn.rval + 0200*(1+2) ); 5329702Slinton return( -1 ); 5339702Slinton } 5349702Slinton 5359702Slinton offset( p, tyl ) register NODE *p; int tyl; { 5369702Slinton 5379702Slinton if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); 5389702Slinton if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && 5399702Slinton (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') 5409702Slinton && (1<<p->in.right->tn.lval)==tyl)) 5419702Slinton return( p->in.left->tn.rval ); 5429702Slinton return( -1 ); 5439702Slinton } 5449702Slinton 5459702Slinton makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { 5469702Slinton register NODE *t; 5479702Slinton register int i; 5489702Slinton NODE *f; 5499702Slinton 5509702Slinton p->in.op = OREG; 5519702Slinton f = p->in.left; /* have to free this subtree later */ 5529702Slinton 5539702Slinton /* init base */ 5549702Slinton switch (q->in.op) { 5559702Slinton case ICON: 5569702Slinton case REG: 5579702Slinton case OREG: 5589702Slinton t = q; 5599702Slinton break; 5609702Slinton 5619702Slinton case MINUS: 5629702Slinton q->in.right->tn.lval = -q->in.right->tn.lval; 5639702Slinton case PLUS: 5649702Slinton t = q->in.right; 5659702Slinton break; 5669702Slinton 5679702Slinton case INCR: 5689702Slinton case ASG MINUS: 5699702Slinton t = q->in.left; 5709702Slinton break; 5719702Slinton 5729702Slinton case UNARY MUL: 5739702Slinton t = q->in.left->in.left; 5749702Slinton break; 5759702Slinton 5769702Slinton default: 5779702Slinton cerror("illegal makeor2"); 5789702Slinton } 5799702Slinton 5809702Slinton p->tn.lval = t->tn.lval; 5819702Slinton #ifndef FLEXNAMES 5829702Slinton for(i=0; i<NCHNAM; ++i) 5839702Slinton p->in.name[i] = t->in.name[i]; 5849702Slinton #else 5859702Slinton p->in.name = t->in.name; 5869702Slinton #endif 5879702Slinton 5889702Slinton /* init offset */ 5899702Slinton p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); 5909702Slinton 5919702Slinton tfree(f); 5929702Slinton return; 5939702Slinton } 5949702Slinton 5959702Slinton canaddr( p ) NODE *p; { 5969702Slinton register int o = p->in.op; 5979702Slinton 5989702Slinton if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); 5999702Slinton return(0); 6009702Slinton } 6019702Slinton 6029702Slinton shltype( o, p ) register NODE *p; { 6039702Slinton return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); 6049702Slinton } 6059702Slinton 6069702Slinton flshape( p ) register NODE *p; { 6079702Slinton return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || 6089702Slinton (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); 6099702Slinton } 6109702Slinton 6119702Slinton shtemp( p ) register NODE *p; { 6129702Slinton if( p->in.op == STARG ) p = p->in.left; 6139702Slinton return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); 6149702Slinton } 6159702Slinton 6169702Slinton shumul( p ) register NODE *p; { 6179702Slinton register o; 6189702Slinton extern int xdebug; 6199702Slinton 6209702Slinton if (xdebug) { 6219702Slinton printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); 6229702Slinton printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); 6239702Slinton } 6249702Slinton 6259702Slinton 6269702Slinton o = p->in.op; 6279702Slinton if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); 6289702Slinton 6299702Slinton if( ( o == INCR || o == ASG MINUS ) && 6309702Slinton ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && 6319702Slinton p->in.right->in.name[0] == '\0' ) 6329702Slinton { 63317659Sralph switch (p->in.type) 6349702Slinton { 6359702Slinton case CHAR|PTR: 6369702Slinton case UCHAR|PTR: 6379702Slinton o = 1; 6389702Slinton break; 6399702Slinton 6409702Slinton case SHORT|PTR: 6419702Slinton case USHORT|PTR: 6429702Slinton o = 2; 6439702Slinton break; 6449702Slinton 6459702Slinton case INT|PTR: 6469702Slinton case UNSIGNED|PTR: 6479702Slinton case LONG|PTR: 6489702Slinton case ULONG|PTR: 6499702Slinton case FLOAT|PTR: 6509702Slinton o = 4; 6519702Slinton break; 6529702Slinton 6539702Slinton case DOUBLE|PTR: 6549702Slinton o = 8; 6559702Slinton break; 6569702Slinton 6579702Slinton default: 65817742Sralph if ( ISPTR(p->in.type) && 65917742Sralph ISPTR(DECREF(p->in.type)) ) { 6609702Slinton o = 4; 6619702Slinton break; 6629702Slinton } 6639702Slinton else return(0); 6649702Slinton } 6659702Slinton return( p->in.right->tn.lval == o ? STARREG : 0); 6669702Slinton } 6679702Slinton 6689702Slinton return( 0 ); 6699702Slinton } 6709702Slinton 6719702Slinton adrcon( val ) CONSZ val; { 6729702Slinton printf( "$" ); 6739702Slinton printf( CONFMT, val ); 6749702Slinton } 6759702Slinton 6769702Slinton conput( p ) register NODE *p; { 6779702Slinton switch( p->in.op ){ 6789702Slinton 6799702Slinton case ICON: 6809702Slinton acon( p ); 6819702Slinton return; 6829702Slinton 6839702Slinton case REG: 6849702Slinton printf( "%s", rnames[p->tn.rval] ); 6859702Slinton return; 6869702Slinton 6879702Slinton default: 6889702Slinton cerror( "illegal conput" ); 6899702Slinton } 6909702Slinton } 6919702Slinton 6929702Slinton insput( p ) register NODE *p; { 6939702Slinton cerror( "insput" ); 6949702Slinton } 6959702Slinton 6969702Slinton upput( p ) register NODE *p; { 6979702Slinton cerror( "upput" ); 6989702Slinton } 6999702Slinton 7009702Slinton adrput( p ) register NODE *p; { 7019702Slinton register int r; 7029702Slinton /* output an address, with offsets, from p */ 7039702Slinton 7049702Slinton if( p->in.op == FLD ){ 7059702Slinton p = p->in.left; 7069702Slinton } 7079702Slinton switch( p->in.op ){ 7089702Slinton 7099702Slinton case NAME: 7109702Slinton acon( p ); 7119702Slinton return; 7129702Slinton 7139702Slinton case ICON: 7149702Slinton /* addressable value of the constant */ 7159702Slinton printf( "$" ); 7169702Slinton acon( p ); 7179702Slinton return; 7189702Slinton 7199702Slinton case REG: 7209702Slinton printf( "%s", rnames[p->tn.rval] ); 7219702Slinton return; 7229702Slinton 7239702Slinton case OREG: 7249702Slinton r = p->tn.rval; 7259702Slinton if( R2TEST(r) ){ /* double indexing */ 7269702Slinton register int flags; 7279702Slinton 7289702Slinton flags = R2UPK3(r); 7299702Slinton if( flags & 1 ) printf("*"); 7309702Slinton if( flags & 4 ) printf("-"); 7319702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); 7329702Slinton if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); 7339702Slinton if( flags & 2 ) printf("+"); 7349702Slinton printf( "[%s]", rnames[R2UPK2(r)] ); 7359702Slinton return; 7369702Slinton } 7379702Slinton if( r == AP ){ /* in the argument region */ 7389702Slinton if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); 7399702Slinton printf( CONFMT, p->tn.lval ); 7409702Slinton printf( "(ap)" ); 7419702Slinton return; 7429702Slinton } 7439702Slinton if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); 7449702Slinton printf( "(%s)", rnames[p->tn.rval] ); 7459702Slinton return; 7469702Slinton 7479702Slinton case UNARY MUL: 7489702Slinton /* STARNM or STARREG found */ 7499702Slinton if( tshape(p, STARNM) ) { 7509702Slinton printf( "*" ); 7519702Slinton adrput( p->in.left); 7529702Slinton } 7539702Slinton else { /* STARREG - really auto inc or dec */ 7549702Slinton register NODE *q; 7559702Slinton 7569702Slinton /* tbl 7579702Slinton p = p->in.left; 7589702Slinton p->in.left->in.op = OREG; 7599702Slinton if( p->in.op == INCR ) { 7609702Slinton adrput( p->in.left ); 7619702Slinton printf( "+" ); 7629702Slinton } 7639702Slinton else { 7649702Slinton printf( "-" ); 7659702Slinton adrput( p->in.left ); 7669702Slinton } 7679702Slinton tbl */ 76817659Sralph q = p->in.left; 76917742Sralph if( q->in.right->tn.lval != tlen(p) ) 77017742Sralph cerror("adrput: bad auto-increment/decrement"); 77117659Sralph printf("%s(%s)%s", (q->in.op==INCR ? "" : "-"), 77217659Sralph rnames[q->in.left->tn.rval], 77317659Sralph (q->in.op==INCR ? "+" : "") ); 7749702Slinton p->in.op = OREG; 77517659Sralph p->tn.rval = q->in.left->tn.rval; 77617659Sralph p->tn.lval = (q->in.op == INCR ? -q->in.right->tn.lval : 0); 7779702Slinton #ifndef FLEXNAMES 7789702Slinton p->in.name[0] = '\0'; 7799702Slinton #else 7809702Slinton p->in.name = ""; 7819702Slinton #endif 7829702Slinton tfree(q); 7839702Slinton } 7849702Slinton return; 7859702Slinton 7869702Slinton default: 7879702Slinton cerror( "illegal address" ); 7889702Slinton return; 7899702Slinton 7909702Slinton } 7919702Slinton 7929702Slinton } 7939702Slinton 7949702Slinton acon( p ) register NODE *p; { /* print out a constant */ 7959702Slinton 7969702Slinton if( p->in.name[0] == '\0' ){ 7979702Slinton printf( CONFMT, p->tn.lval); 7989702Slinton } 7999702Slinton else if( p->tn.lval == 0 ) { 8009702Slinton #ifndef FLEXNAMES 8019702Slinton printf( "%.8s", p->in.name ); 8029702Slinton #else 8039702Slinton printf( "%s", p->in.name ); 8049702Slinton #endif 8059702Slinton } 8069702Slinton else { 8079702Slinton #ifndef FLEXNAMES 8089702Slinton printf( "%.8s+", p->in.name ); 8099702Slinton #else 8109702Slinton printf( "%s+", p->in.name ); 8119702Slinton #endif 8129702Slinton printf( CONFMT, p->tn.lval ); 8139702Slinton } 8149702Slinton } 8159702Slinton 8169702Slinton /* 8179702Slinton aacon( p ) register NODE *p; { /* print out a constant */ 8189702Slinton /* 8199702Slinton 8209702Slinton if( p->in.name[0] == '\0' ){ 8219702Slinton printf( CONFMT, p->tn.lval); 8229702Slinton return( 0 ); 8239702Slinton } 8249702Slinton else if( p->tn.lval == 0 ) { 8259702Slinton #ifndef FLEXNAMES 8269702Slinton printf( "$%.8s", p->in.name ); 8279702Slinton #else 8289702Slinton printf( "$%s", p->in.name ); 8299702Slinton #endif 8309702Slinton return( 1 ); 8319702Slinton } 8329702Slinton else { 8339702Slinton printf( "$(" ); 8349702Slinton printf( CONFMT, p->tn.lval ); 8359702Slinton printf( "+" ); 8369702Slinton #ifndef FLEXNAMES 8379702Slinton printf( "%.8s)", p->in.name ); 8389702Slinton #else 8399702Slinton printf( "%s)", p->in.name ); 8409702Slinton #endif 8419702Slinton return(1); 8429702Slinton } 8439702Slinton } 8449702Slinton */ 8459702Slinton 8469702Slinton genscall( p, cookie ) register NODE *p; { 8479702Slinton /* structure valued call */ 8489702Slinton return( gencall( p, cookie ) ); 8499702Slinton } 8509702Slinton 8519702Slinton /* tbl */ 8529702Slinton int gc_numbytes; 8539702Slinton /* tbl */ 8549702Slinton 8559702Slinton gencall( p, cookie ) register NODE *p; { 8569702Slinton /* generate the call given by p */ 85716418Sralph register NODE *p1; 8589702Slinton register temp, temp1; 8599702Slinton register m; 8609702Slinton 8619702Slinton if( p->in.right ) temp = argsize( p->in.right ); 8629702Slinton else temp = 0; 8639702Slinton 8649702Slinton if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ 8659702Slinton /* set aside room for structure return */ 8669702Slinton 8679702Slinton if( p->stn.stsize > temp ) temp1 = p->stn.stsize; 8689702Slinton else temp1 = temp; 8699702Slinton } 8709702Slinton 8719702Slinton if( temp > maxargs ) maxargs = temp; 8729702Slinton SETOFF(temp1,4); 8739702Slinton 8749702Slinton if( p->in.right ){ /* make temp node, put offset in, and generate args */ 87516418Sralph genargs( p->in.right ); 8769702Slinton } 8779702Slinton 8789702Slinton p1 = p->in.left; 8799702Slinton if( p1->in.op != ICON ){ 8809702Slinton if( p1->in.op != REG ){ 8819702Slinton if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ 8829702Slinton if( p1->in.op != NAME ){ 8839702Slinton order( p1, INAREG ); 8849702Slinton } 8859702Slinton } 8869702Slinton } 8879702Slinton } 8889702Slinton 8899702Slinton /* 8909702Slinton if( p1->in.op == REG && p->tn.rval == R5 ){ 8919702Slinton cerror( "call register overwrite" ); 8929702Slinton } 8939702Slinton */ 8949702Slinton /* tbl 8959702Slinton setup gc_numbytes so reference to ZC works */ 8969702Slinton 8979702Slinton gc_numbytes = temp&(0x3ff); 8989702Slinton /* tbl */ 8999702Slinton 9009702Slinton p->in.op = UNARY CALL; 9019702Slinton m = match( p, INTAREG|INTBREG ); 9029702Slinton 9039702Slinton /* compensate for deficiency in 'ret' instruction ... wah,kre */ 9049702Slinton /* (plus in assignment to gc_numbytes above, for neatness only) */ 9059702Slinton if (temp >= 1024) 9069702Slinton printf(" addl2 $%d,sp\n", (temp&(~0x3ff))); 9079702Slinton 9089702Slinton /* tbl 9099702Slinton switch( temp ) { 9109702Slinton case 0: 9119702Slinton break; 9129702Slinton case 2: 9139702Slinton printf( " tst (sp)+\n" ); 9149702Slinton break; 9159702Slinton case 4: 9169702Slinton printf( " cmp (sp)+,(sp)+\n" ); 9179702Slinton break; 9189702Slinton default: 9199702Slinton printf( " add $%d,sp\n", temp); 9209702Slinton } 9219702Slinton tbl */ 9229702Slinton return(m != MDONE); 9239702Slinton } 9249702Slinton 9259702Slinton /* tbl */ 9269702Slinton char * 9279702Slinton ccbranches[] = { 9289702Slinton " jeql L%d\n", 9299702Slinton " jneq L%d\n", 9309702Slinton " jleq L%d\n", 9319702Slinton " jlss L%d\n", 9329702Slinton " jgeq L%d\n", 9339702Slinton " jgtr L%d\n", 9349702Slinton " jlequ L%d\n", 9359702Slinton " jlssu L%d\n", 9369702Slinton " jgequ L%d\n", 9379702Slinton " jgtru L%d\n", 9389702Slinton }; 9399702Slinton /* tbl */ 9409702Slinton 9419702Slinton cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 9429702Slinton 9439702Slinton /* tbl */ 9449702Slinton if( o == 0 ) printf( " jbr L%d\n", lab ); 9459702Slinton /* tbl */ 9469702Slinton else { 9479702Slinton if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 9489702Slinton printf( ccbranches[o-EQ], lab ); 9499702Slinton } 9509702Slinton } 9519702Slinton 9529702Slinton nextcook( p, cookie ) NODE *p; { 9539702Slinton /* we have failed to match p with cookie; try another */ 9549702Slinton if( cookie == FORREW ) return( 0 ); /* hopeless! */ 9559702Slinton if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 9569702Slinton if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 9579702Slinton return( FORREW ); 9589702Slinton } 9599702Slinton 9609702Slinton lastchance( p, cook ) NODE *p; { 9619702Slinton /* forget it! */ 9629702Slinton return(0); 9639702Slinton } 9649702Slinton 9659702Slinton optim2( p ) register NODE *p; { 9669702Slinton /* do local tree transformations and optimizations */ 9679702Slinton 96816181Sralph register NODE *l, *r; 96916181Sralph int m, ml; 9709702Slinton 9719702Slinton switch( p->in.op ) { 9729702Slinton 9739702Slinton case AND: 974*19933Smckusick /* commute L and R to eliminate complements and constants */ 97516181Sralph if( (l = p->in.left)->in.op == ICON && l->in.name[0] == 0 || 97616181Sralph l->in.op == COMPL ) { 9779702Slinton p->in.left = p->in.right; 97816181Sralph p->in.right = l; 9799702Slinton } 9809702Slinton case ASG AND: 9819702Slinton /* change meaning of AND to ~R&L - bic on pdp11 */ 9829702Slinton r = p->in.right; 983*19933Smckusick if( r->in.op==ICON && r->in.name[0]==0 ) { /* complement constant */ 9849702Slinton r->tn.lval = ~r->tn.lval; 9859702Slinton } 9869702Slinton else if( r->in.op==COMPL ) { /* ~~A => A */ 9879702Slinton r->in.op = FREE; 9889702Slinton p->in.right = r->in.left; 9899702Slinton } 9909702Slinton else { /* insert complement node */ 99116181Sralph p->in.right = l = talloc(); 99216181Sralph l->in.op = COMPL; 99316181Sralph l->in.rall = NOPREF; 99416181Sralph l->in.type = r->in.type; 99516181Sralph l->in.left = r; 99616181Sralph l->in.right = NULL; 9979702Slinton } 9989702Slinton break; 9999702Slinton 100016181Sralph case SCONV: 1001*19933Smckusick l = p->in.left; 100217742Sralph #if defined(FORT) || defined(SPRECC) 100316573Sralph if( p->in.type == FLOAT || p->in.type == DOUBLE || 1004*19933Smckusick l->in.type == FLOAT || l->in.type == DOUBLE ) 1005*19933Smckusick return; 100616573Sralph #else 1007*19933Smckusick if( mixtypes(p, l) ) return; 100816573Sralph #endif 1009*19933Smckusick /* Only trust it to get it right if the size is the same */ 1010*19933Smckusick if( tlen(p) != tlen(l) ) 1011*19933Smckusick return; 101216181Sralph 101316181Sralph /* clobber conversion */ 1014*19933Smckusick if( l->in.op != FLD ) 101516181Sralph l->in.type = p->in.type; 101616181Sralph ncopy( p, l ); 101716181Sralph l->in.op = FREE; 1018*19933Smckusick 101916181Sralph break; 102016181Sralph 10219702Slinton } 10229702Slinton } 10239702Slinton 102417742Sralph NODE * addroreg(l) NODE *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"); 103417742Sralph /*NOTREACHED*/ 10359702Slinton } 10369702Slinton 10379702Slinton 10389702Slinton 10399702Slinton # ifndef ONEPASS 10409702Slinton main( argc, argv ) char *argv[]; { 10419702Slinton return( mainp2( argc, argv ) ); 10429702Slinton } 10439702Slinton # endif 10449702Slinton 10459702Slinton 10469702Slinton /* added by jwf */ 10479702Slinton struct functbl { 10489702Slinton int fop; 10499702Slinton TWORD ftype; 10509702Slinton char *func; 10519702Slinton } opfunc[] = { 10529702Slinton DIV, TANY, "udiv", 10539702Slinton MOD, TANY, "urem", 105417715Sralph ASG DIV, TANY, "audiv", 105517715Sralph ASG MOD, TANY, "aurem", 10569702Slinton 0, 0, 0 }; 10579702Slinton 10589702Slinton hardops(p) register NODE *p; { 10599702Slinton /* change hard to do operators into function calls. */ 10609702Slinton register NODE *q; 10619702Slinton register struct functbl *f; 10629702Slinton register o; 106317742Sralph NODE *old,*temp; 10649702Slinton 10659702Slinton o = p->in.op; 106617742Sralph if( ! (optype(o)==BITYPE && 106717742Sralph (ISUNSIGNED(p->in.left->in.type) || 106817742Sralph ISUNSIGNED(p->in.right->in.type))) ) 106917742Sralph return; 10709702Slinton 10719702Slinton for( f=opfunc; f->fop; f++ ) { 10729702Slinton if( o==f->fop ) goto convert; 10739702Slinton } 10749702Slinton return; 10759702Slinton 10769702Slinton convert: 10779702Slinton if( asgop( o ) ) { 107817742Sralph old = NIL; 107917715Sralph switch( p->in.left->in.op ){ 108017742Sralph case FLD: 108117742Sralph q = p->in.left->in.left; 108217742Sralph /* 108317742Sralph * rewrite (lval.fld /= rval); as 108417742Sralph * ((*temp).fld = udiv((*(temp = &lval)).fld,rval)); 108517742Sralph * else the compiler will evaluate lval twice. 108617742Sralph */ 108717742Sralph if( q->in.op == UNARY MUL ){ 108817742Sralph /* first allocate a temp storage */ 108917742Sralph temp = talloc(); 109017742Sralph temp->in.op = OREG; 109117742Sralph temp->tn.rval = TMPREG; 109217742Sralph temp->tn.lval = BITOOR(freetemp(1)); 109317742Sralph temp->in.type = INCREF(p->in.type); 109417742Sralph #ifdef FLEXNAMES 109517742Sralph temp->in.name = ""; 109617742Sralph #else 109717742Sralph temp->in.name[0] = '\0'; 109817742Sralph #endif 109917742Sralph old = q->in.left; 110017742Sralph q->in.left = temp; 110117742Sralph } 110217742Sralph /* fall thru ... */ 110317742Sralph 110417715Sralph case REG: 110517715Sralph case NAME: 110617715Sralph case OREG: 110717715Sralph /* change ASG OP to a simple OP */ 110817715Sralph q = talloc(); 110917715Sralph q->in.op = NOASG p->in.op; 111017715Sralph q->in.rall = NOPREF; 111117715Sralph q->in.type = p->in.type; 111217715Sralph q->in.left = tcopy(p->in.left); 111317715Sralph q->in.right = p->in.right; 111417715Sralph p->in.op = ASSIGN; 111517715Sralph p->in.right = q; 111617715Sralph p = q; 111717715Sralph f -= 2; /* Note: this depends on the table order */ 111817742Sralph /* on the right side only - replace *temp with 111917742Sralph *(temp = &lval), build the assignment node */ 112017742Sralph if( old ){ 112117742Sralph temp = q->in.left->in.left; /* the "*" node */ 112217742Sralph q = talloc(); 112317742Sralph q->in.op = ASSIGN; 112417742Sralph q->in.left = temp->in.left; 112517742Sralph q->in.right = old; 112617742Sralph q->in.type = old->in.type; 112717742Sralph #ifdef FLEXNAMES 112817742Sralph q->in.name = ""; 112917742Sralph #else 113017742Sralph q->in.name[0] = '\0'; 113117742Sralph #endif 113217742Sralph temp->in.left = q; 113317742Sralph } 113417715Sralph break; 11359702Slinton 113617715Sralph case UNARY MUL: 113717715Sralph /* avoid doing side effects twice */ 113817715Sralph q = p->in.left; 113917715Sralph p->in.left = q->in.left; 114017715Sralph q->in.op = FREE; 114117715Sralph break; 114217715Sralph 114317715Sralph default: 114417715Sralph cerror( "hardops: can't compute & LHS" ); 114517715Sralph } 114617742Sralph } 114717715Sralph 11489702Slinton /* build comma op for args to function */ 11499702Slinton q = talloc(); 11509702Slinton q->in.op = CM; 11519702Slinton q->in.rall = NOPREF; 11529702Slinton q->in.type = INT; 11539702Slinton q->in.left = p->in.left; 11549702Slinton q->in.right = p->in.right; 11559702Slinton p->in.op = CALL; 11569702Slinton p->in.right = q; 11579702Slinton 11589702Slinton /* put function name in left node of call */ 11599702Slinton p->in.left = q = talloc(); 11609702Slinton q->in.op = ICON; 11619702Slinton q->in.rall = NOPREF; 11629702Slinton q->in.type = INCREF( FTN + p->in.type ); 11639702Slinton #ifndef FLEXNAMES 11649702Slinton strcpy( q->in.name, f->func ); 11659702Slinton #else 11669702Slinton q->in.name = f->func; 11679702Slinton #endif 11689702Slinton q->tn.lval = 0; 11699702Slinton q->tn.rval = 0; 11709702Slinton 11719702Slinton } 11729702Slinton 117317742Sralph zappost(p) NODE *p; { 117417742Sralph /* look for ++ and -- operators and remove them */ 117517742Sralph 117617742Sralph register o, ty; 117717742Sralph register NODE *q; 117817742Sralph o = p->in.op; 117917742Sralph ty = optype( o ); 118017742Sralph 118117742Sralph switch( o ){ 118217742Sralph 118317742Sralph case INCR: 118417742Sralph case DECR: 118517742Sralph q = p->in.left; 118617742Sralph p->in.right->in.op = FREE; /* zap constant */ 118717742Sralph ncopy( p, q ); 118817742Sralph q->in.op = FREE; 118917742Sralph return; 119017742Sralph 119117742Sralph } 119217742Sralph 119317742Sralph if( ty == BITYPE ) zappost( p->in.right ); 119417742Sralph if( ty != LTYPE ) zappost( p->in.left ); 119517742Sralph } 119617742Sralph 119717742Sralph fixpre(p) NODE *p; { 119817742Sralph 119917742Sralph register o, ty; 120017742Sralph o = p->in.op; 120117742Sralph ty = optype( o ); 120217742Sralph 120317742Sralph switch( o ){ 120417742Sralph 120517742Sralph case ASG PLUS: 120617742Sralph p->in.op = PLUS; 120717742Sralph break; 120817742Sralph case ASG MINUS: 120917742Sralph p->in.op = MINUS; 121017742Sralph break; 121117742Sralph } 121217742Sralph 121317742Sralph if( ty == BITYPE ) fixpre( p->in.right ); 121417742Sralph if( ty != LTYPE ) fixpre( p->in.left ); 121517742Sralph } 121617742Sralph 12179702Slinton myreader(p) register NODE *p; { 121817742Sralph canon( p ); /* expands r-vals for fields */ 12199702Slinton walkf( p, hardops ); /* convert ops to function calls */ 12209702Slinton walkf( p, optim2 ); 12219702Slinton /* jwf toff = 0; /* stack offset swindle */ 12229702Slinton } 1223