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