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