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