xref: /csrg-svn/old/pcc/ccom.vax/local2.c (revision 9702)
1*9702Slinton static char *sccsid ="@(#)local2.c	1.1 (Berkeley) 12/15/82";
2*9702Slinton # include "mfile2"
3*9702Slinton # include "ctype.h"
4*9702Slinton # ifdef FORT
5*9702Slinton int ftlab1, ftlab2;
6*9702Slinton # endif
7*9702Slinton /* a lot of the machine dependent parts of the second pass */
8*9702Slinton 
9*9702Slinton # define BITMASK(n) ((1L<<n)-1)
10*9702Slinton 
11*9702Slinton where(c){
12*9702Slinton 	fprintf( stderr, "%s, line %d: ", filename, lineno );
13*9702Slinton 	}
14*9702Slinton 
15*9702Slinton lineid( l, fn ) char *fn; {
16*9702Slinton 	/* identify line l and file fn */
17*9702Slinton 	printf( "#	line %d, file %s\n", l, fn );
18*9702Slinton 	}
19*9702Slinton 
20*9702Slinton 
21*9702Slinton eobl2(){
22*9702Slinton 	OFFSZ spoff;	/* offset from stack pointer */
23*9702Slinton #ifdef FORT
24*9702Slinton 	spoff = maxoff;
25*9702Slinton 	if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
26*9702Slinton 	spoff /= SZCHAR;
27*9702Slinton 	SETOFF(spoff,4);
28*9702Slinton #ifndef FLEXNAMES
29*9702Slinton 	printf( "	.set	.F%d,%ld\n", ftnno, spoff );
30*9702Slinton #else
31*9702Slinton 	/* SHOULD BE L%d ... ftnno but must change pc/f77 */
32*9702Slinton 	printf( "	.set	LF%d,%ld\n", ftnno, spoff );
33*9702Slinton #endif
34*9702Slinton #else
35*9702Slinton 	extern int ftlab1, ftlab2;
36*9702Slinton 
37*9702Slinton 	spoff = maxoff;
38*9702Slinton 	if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
39*9702Slinton 	spoff /= SZCHAR;
40*9702Slinton 	SETOFF(spoff,4);
41*9702Slinton 	printf( "L%d:\n", ftlab1);
42*9702Slinton 	if( spoff!=0 )
43*9702Slinton 		if( spoff < 64 )
44*9702Slinton 			printf( "	subl2	$%ld,sp\n", spoff);
45*9702Slinton 		else
46*9702Slinton 			printf( "	movab	-%ld(sp),sp\n", spoff);
47*9702Slinton 	printf( "	jbr 	L%d\n", ftlab2);
48*9702Slinton #endif
49*9702Slinton 	maxargs = -1;
50*9702Slinton 	}
51*9702Slinton 
52*9702Slinton struct hoptab { int opmask; char * opstring; } ioptab[] = {
53*9702Slinton 
54*9702Slinton 	ASG PLUS, "add",
55*9702Slinton 	ASG MINUS, "sub",
56*9702Slinton 	ASG MUL, "mul",
57*9702Slinton 	ASG DIV, "div",
58*9702Slinton 	ASG OR, "bis",
59*9702Slinton 	ASG ER,	"xor",
60*9702Slinton 	ASG AND, "bic",
61*9702Slinton 	PLUS,	"add",
62*9702Slinton 	MINUS,	"sub",
63*9702Slinton 	MUL,	"mul",
64*9702Slinton 	DIV,	"div",
65*9702Slinton 	OR,	"bis",
66*9702Slinton 	ER,	"xor",
67*9702Slinton 	AND,	"bic",
68*9702Slinton 	-1, ""    };
69*9702Slinton 
70*9702Slinton hopcode( f, o ){
71*9702Slinton 	/* output the appropriate string from the above table */
72*9702Slinton 
73*9702Slinton 	register struct hoptab *q;
74*9702Slinton 
75*9702Slinton 	for( q = ioptab;  q->opmask>=0; ++q ){
76*9702Slinton 		if( q->opmask == o ){
77*9702Slinton 			printf( "%s", q->opstring );
78*9702Slinton /* tbl
79*9702Slinton 			if( f == 'F' ) printf( "e" );
80*9702Slinton 			else if( f == 'D' ) printf( "d" );
81*9702Slinton    tbl */
82*9702Slinton /* tbl */
83*9702Slinton 			switch( f ) {
84*9702Slinton 				case 'L':
85*9702Slinton 				case 'W':
86*9702Slinton 				case 'B':
87*9702Slinton 				case 'D':
88*9702Slinton 				case 'F':
89*9702Slinton 					printf("%c", tolower(f));
90*9702Slinton 					break;
91*9702Slinton 
92*9702Slinton 				}
93*9702Slinton /* tbl */
94*9702Slinton 			return;
95*9702Slinton 			}
96*9702Slinton 		}
97*9702Slinton 	cerror( "no hoptab for %s", opst[o] );
98*9702Slinton 	}
99*9702Slinton 
100*9702Slinton char *
101*9702Slinton rnames[] = {  /* keyed to register number tokens */
102*9702Slinton 
103*9702Slinton 	"r0", "r1",
104*9702Slinton 	"r2", "r3", "r4", "r5",
105*9702Slinton 	"r6", "r7", "r8", "r9", "r10", "r11",
106*9702Slinton 	"ap", "fp", "sp", "pc",
107*9702Slinton 
108*9702Slinton 	};
109*9702Slinton 
110*9702Slinton int rstatus[] = {
111*9702Slinton 	SAREG|STAREG, SAREG|STAREG,
112*9702Slinton 	SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
113*9702Slinton 	SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
114*9702Slinton 	SAREG, SAREG, SAREG, SAREG,
115*9702Slinton 
116*9702Slinton 	};
117*9702Slinton 
118*9702Slinton tlen(p) NODE *p;
119*9702Slinton {
120*9702Slinton 	switch(p->in.type) {
121*9702Slinton 		case CHAR:
122*9702Slinton 		case UCHAR:
123*9702Slinton 			return(1);
124*9702Slinton 
125*9702Slinton 		case SHORT:
126*9702Slinton 		case USHORT:
127*9702Slinton 			return(2);
128*9702Slinton 
129*9702Slinton 		case DOUBLE:
130*9702Slinton 			return(8);
131*9702Slinton 
132*9702Slinton 		default:
133*9702Slinton 			return(4);
134*9702Slinton 		}
135*9702Slinton }
136*9702Slinton 
137*9702Slinton mixtypes(p, q) NODE *p, *q;
138*9702Slinton {
139*9702Slinton 	register tp, tq;
140*9702Slinton 
141*9702Slinton 	tp = p->in.type;
142*9702Slinton 	tq = q->in.type;
143*9702Slinton 
144*9702Slinton 	return( (tp==FLOAT || tp==DOUBLE) !=
145*9702Slinton 		(tq==FLOAT || tq==DOUBLE) );
146*9702Slinton }
147*9702Slinton 
148*9702Slinton prtype(n) NODE *n;
149*9702Slinton {
150*9702Slinton 	switch (n->in.type)
151*9702Slinton 		{
152*9702Slinton 		case DOUBLE:
153*9702Slinton 			printf("d");
154*9702Slinton 			return;
155*9702Slinton 
156*9702Slinton 		case FLOAT:
157*9702Slinton 			printf("f");
158*9702Slinton 			return;
159*9702Slinton 
160*9702Slinton 		case LONG:
161*9702Slinton 		case ULONG:
162*9702Slinton 		case INT:
163*9702Slinton 		case UNSIGNED:
164*9702Slinton 			printf("l");
165*9702Slinton 			return;
166*9702Slinton 
167*9702Slinton 		case SHORT:
168*9702Slinton 		case USHORT:
169*9702Slinton 			printf("w");
170*9702Slinton 			return;
171*9702Slinton 
172*9702Slinton 		case CHAR:
173*9702Slinton 		case UCHAR:
174*9702Slinton 			printf("b");
175*9702Slinton 			return;
176*9702Slinton 
177*9702Slinton 		default:
178*9702Slinton 			if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type");
179*9702Slinton 			else {
180*9702Slinton 				printf("l");
181*9702Slinton 				return;
182*9702Slinton 				}
183*9702Slinton 		}
184*9702Slinton }
185*9702Slinton 
186*9702Slinton zzzcode( p, c ) register NODE *p; {
187*9702Slinton 	register m;
188*9702Slinton 	CONSZ val;
189*9702Slinton 	switch( c ){
190*9702Slinton 
191*9702Slinton 	case 'N':  /* logical ops, turned into 0-1 */
192*9702Slinton 		/* use register given by register 1 */
193*9702Slinton 		cbgen( 0, m=getlab(), 'I' );
194*9702Slinton 		deflab( p->bn.label );
195*9702Slinton 		printf( "	clrl	%s\n", rnames[getlr( p, '1' )->tn.rval] );
196*9702Slinton 		deflab( m );
197*9702Slinton 		return;
198*9702Slinton 
199*9702Slinton 	case 'I':
200*9702Slinton 	case 'P':
201*9702Slinton 		cbgen( p->in.op, p->bn.label, c );
202*9702Slinton 		return;
203*9702Slinton 
204*9702Slinton 	case 'A':
205*9702Slinton 		{
206*9702Slinton 		register NODE *l, *r;
207*9702Slinton 
208*9702Slinton 		if (xdebug) eprint(p, 0, &val, &val);
209*9702Slinton 		r = getlr(p, 'R');
210*9702Slinton 		if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL)
211*9702Slinton 			{
212*9702Slinton 			l = resc;
213*9702Slinton 			l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT);
214*9702Slinton 			}
215*9702Slinton 		else
216*9702Slinton 			l = getlr(p, 'L');
217*9702Slinton 		if (r->in.op == ICON)
218*9702Slinton 			if(r->in.name[0] == '\0')
219*9702Slinton 				{
220*9702Slinton 				if (r->tn.lval == 0)
221*9702Slinton 					{
222*9702Slinton 					printf("clr");
223*9702Slinton 					prtype(l);
224*9702Slinton 					printf("	");
225*9702Slinton 					adrput(l);
226*9702Slinton 					return;
227*9702Slinton 					}
228*9702Slinton 				if (r->tn.lval < 0 && r->tn.lval >= -63)
229*9702Slinton 					{
230*9702Slinton 					printf("mneg");
231*9702Slinton 					prtype(l);
232*9702Slinton 					r->tn.lval = -r->tn.lval;
233*9702Slinton 					goto ops;
234*9702Slinton 					}
235*9702Slinton 				r->in.type = (r->tn.lval < 0 ?
236*9702Slinton 						(r->tn.lval >= -128 ? CHAR
237*9702Slinton 						: (r->tn.lval >= -32768 ? SHORT
238*9702Slinton 						: INT )) : r->in.type);
239*9702Slinton 				r->in.type = (r->tn.lval >= 0 ?
240*9702Slinton 						(r->tn.lval <= 63 ? INT
241*9702Slinton 						: ( r->tn.lval <= 127 ? CHAR
242*9702Slinton 						: (r->tn.lval <= 255 ? UCHAR
243*9702Slinton 						: (r->tn.lval <= 32767 ? SHORT
244*9702Slinton 						: (r->tn.lval <= 65535 ? USHORT
245*9702Slinton 						: INT ))))) : r->in.type );
246*9702Slinton 				}
247*9702Slinton 				else
248*9702Slinton 					{
249*9702Slinton 					printf("moval");
250*9702Slinton 					printf("	");
251*9702Slinton 					acon(r);
252*9702Slinton 					printf(",");
253*9702Slinton 					adrput(l);
254*9702Slinton 					return;
255*9702Slinton 					}
256*9702Slinton 
257*9702Slinton 		if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE)
258*9702Slinton 			{
259*9702Slinton 			if( tlen(l) < tlen(r) )
260*9702Slinton 				{
261*9702Slinton 				if (!mixtypes(l,r))
262*9702Slinton 					{
263*9702Slinton 					!ISUNSIGNED(l->in.type)?
264*9702Slinton 						printf("cvt"):
265*9702Slinton 						printf("movz");
266*9702Slinton 					prtype(l);
267*9702Slinton 					printf("l");
268*9702Slinton 					goto ops;
269*9702Slinton 					}
270*9702Slinton 				else
271*9702Slinton 					{
272*9702Slinton 					printf("cvt");
273*9702Slinton 					prtype(r);
274*9702Slinton 					prtype(l);
275*9702Slinton 					printf("	");
276*9702Slinton 					adrput(r);
277*9702Slinton 					printf(",");
278*9702Slinton 					adrput(l);
279*9702Slinton 					printf("cvt");
280*9702Slinton 					prtype(l);
281*9702Slinton 					printf("l");
282*9702Slinton 					printf("	");
283*9702Slinton 					adrput(l);
284*9702Slinton 					printf(",");
285*9702Slinton 					adrput(l);
286*9702Slinton 					return;
287*9702Slinton 					}
288*9702Slinton 				}
289*9702Slinton 			else
290*9702Slinton 				{
291*9702Slinton 			l->in.type = INT;
292*9702Slinton 				}
293*9702Slinton 			}
294*9702Slinton 		if (!mixtypes(l,r))
295*9702Slinton 			{
296*9702Slinton 			if (tlen(l) == tlen(r))
297*9702Slinton 				{
298*9702Slinton 				printf("mov");
299*9702Slinton 				prtype(l);
300*9702Slinton 				goto ops;
301*9702Slinton 				}
302*9702Slinton 			else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type))
303*9702Slinton 				{
304*9702Slinton 				printf("movz");
305*9702Slinton 				}
306*9702Slinton 			else
307*9702Slinton 				{
308*9702Slinton 				printf("cvt");
309*9702Slinton 				}
310*9702Slinton 			}
311*9702Slinton 		else
312*9702Slinton 			{
313*9702Slinton 			printf("cvt");
314*9702Slinton 			}
315*9702Slinton 		prtype(r);
316*9702Slinton 		prtype(l);
317*9702Slinton 	ops:
318*9702Slinton 		printf("	");
319*9702Slinton 		adrput(r);
320*9702Slinton 		printf(",");
321*9702Slinton 		adrput(l);
322*9702Slinton 		return;
323*9702Slinton 		}
324*9702Slinton 
325*9702Slinton 	case 'B':	/* get oreg value in temp register for left shift */
326*9702Slinton 		{
327*9702Slinton 		register NODE *r;
328*9702Slinton 		if (xdebug) eprint(p, 0, &val, &val);
329*9702Slinton 		r = p->in.right;
330*9702Slinton 		if( tlen(r) == sizeof(int) && r->in.type != FLOAT )
331*9702Slinton 			printf("movl");
332*9702Slinton 		else {
333*9702Slinton 			printf("cvt");
334*9702Slinton 			prtype(r);
335*9702Slinton 			printf("l");
336*9702Slinton 			}
337*9702Slinton 		return;
338*9702Slinton 		}
339*9702Slinton 
340*9702Slinton 	case 'C':	/* num words pushed on arg stack */
341*9702Slinton 		{
342*9702Slinton 		extern int gc_numbytes;
343*9702Slinton 		extern int xdebug;
344*9702Slinton 
345*9702Slinton 		if (xdebug) printf("->%d<-",gc_numbytes);
346*9702Slinton 
347*9702Slinton 		printf("$%d", gc_numbytes/(SZLONG/SZCHAR) );
348*9702Slinton 		return;
349*9702Slinton 		}
350*9702Slinton 
351*9702Slinton 	case 'D':	/* INCR and DECR */
352*9702Slinton 		zzzcode(p->in.left, 'A');
353*9702Slinton 		printf("\n	");
354*9702Slinton 
355*9702Slinton 	case 'E':	/* INCR and DECR, FOREFF */
356*9702Slinton 		if (p->in.right->tn.lval == 1)
357*9702Slinton 			{
358*9702Slinton 			printf("%s", (p->in.op == INCR ? "inc" : "dec") );
359*9702Slinton 			prtype(p->in.left);
360*9702Slinton 			printf("	");
361*9702Slinton 			adrput(p->in.left);
362*9702Slinton 			return;
363*9702Slinton 			}
364*9702Slinton 		printf("%s", (p->in.op == INCR ? "add" : "sub") );
365*9702Slinton 		prtype(p->in.left);
366*9702Slinton 		printf("2	");
367*9702Slinton 		adrput(p->in.right);
368*9702Slinton 		printf(",");
369*9702Slinton 		adrput(p->in.left);
370*9702Slinton 		return;
371*9702Slinton 
372*9702Slinton 	case 'F':	/* register type of right operand */
373*9702Slinton 		{
374*9702Slinton 		register NODE *n;
375*9702Slinton 		extern int xdebug;
376*9702Slinton 		register int ty;
377*9702Slinton 
378*9702Slinton 		n = getlr( p, 'R' );
379*9702Slinton 		ty = n->in.type;
380*9702Slinton 
381*9702Slinton 		if (xdebug) printf("->%d<-", ty);
382*9702Slinton 
383*9702Slinton 		if ( ty==DOUBLE) printf("d");
384*9702Slinton 		else if ( ty==FLOAT ) printf("f");
385*9702Slinton 		else printf("l");
386*9702Slinton 		return;
387*9702Slinton 		}
388*9702Slinton 
389*9702Slinton 	case 'L':	/* type of left operand */
390*9702Slinton 	case 'R':	/* type of right operand */
391*9702Slinton 		{
392*9702Slinton 		register NODE *n;
393*9702Slinton 		extern int xdebug;
394*9702Slinton 
395*9702Slinton 		n = getlr ( p, c);
396*9702Slinton 		if (xdebug) printf("->%d<-", n->in.type);
397*9702Slinton 
398*9702Slinton 		prtype(n);
399*9702Slinton 		return;
400*9702Slinton 		}
401*9702Slinton 
402*9702Slinton 	case 'Z':	/* complement mask for bit instr */
403*9702Slinton 		printf("$%ld", ~p->in.right->tn.lval);
404*9702Slinton 		return;
405*9702Slinton 
406*9702Slinton 	case 'U':	/* 32 - n, for unsigned right shifts */
407*9702Slinton 		printf("$%d", 32 - p->in.right->tn.lval );
408*9702Slinton 		return;
409*9702Slinton 
410*9702Slinton 	case 'T':	/* rounded structure length for arguments */
411*9702Slinton 		{
412*9702Slinton 		int size;
413*9702Slinton 
414*9702Slinton 		size = p->stn.stsize;
415*9702Slinton 		SETOFF( size, 4);
416*9702Slinton 		printf("$%d", size);
417*9702Slinton 		return;
418*9702Slinton 		}
419*9702Slinton 
420*9702Slinton 	case 'S':  /* structure assignment */
421*9702Slinton 		{
422*9702Slinton 			register NODE *l, *r;
423*9702Slinton 			register size;
424*9702Slinton 
425*9702Slinton 			if( p->in.op == STASG ){
426*9702Slinton 				l = p->in.left;
427*9702Slinton 				r = p->in.right;
428*9702Slinton 
429*9702Slinton 				}
430*9702Slinton 			else if( p->in.op == STARG ){  /* store an arg into a temporary */
431*9702Slinton 				l = getlr( p, '3' );
432*9702Slinton 				r = p->in.left;
433*9702Slinton 				}
434*9702Slinton 			else cerror( "STASG bad" );
435*9702Slinton 
436*9702Slinton 			if( r->in.op == ICON ) r->in.op = NAME;
437*9702Slinton 			else if( r->in.op == REG ) r->in.op = OREG;
438*9702Slinton 			else if( r->in.op != OREG ) cerror( "STASG-r" );
439*9702Slinton 
440*9702Slinton 			size = p->stn.stsize;
441*9702Slinton 
442*9702Slinton 			if( size <= 0 || size > 65535 )
443*9702Slinton 				cerror("structure size <0=0 or >65535");
444*9702Slinton 
445*9702Slinton 			switch(size) {
446*9702Slinton 				case 1:
447*9702Slinton 					printf("	movb	");
448*9702Slinton 					break;
449*9702Slinton 				case 2:
450*9702Slinton 					printf("	movw	");
451*9702Slinton 					break;
452*9702Slinton 				case 4:
453*9702Slinton 					printf("	movl	");
454*9702Slinton 					break;
455*9702Slinton 				case 8:
456*9702Slinton 					printf("	movq	");
457*9702Slinton 					break;
458*9702Slinton 				default:
459*9702Slinton 					printf("	movc3	$%d,", size);
460*9702Slinton 					break;
461*9702Slinton 			}
462*9702Slinton 			adrput(r);
463*9702Slinton 			printf(",");
464*9702Slinton 			adrput(l);
465*9702Slinton 			printf("\n");
466*9702Slinton 
467*9702Slinton 			if( r->in.op == NAME ) r->in.op = ICON;
468*9702Slinton 			else if( r->in.op == OREG ) r->in.op = REG;
469*9702Slinton 
470*9702Slinton 			}
471*9702Slinton 		break;
472*9702Slinton 
473*9702Slinton 	default:
474*9702Slinton 		cerror( "illegal zzzcode" );
475*9702Slinton 		}
476*9702Slinton 	}
477*9702Slinton 
478*9702Slinton rmove( rt, rs, t ){
479*9702Slinton 	printf( "	%s	%s,%s\n",
480*9702Slinton 		(t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
481*9702Slinton 		rnames[rs], rnames[rt] );
482*9702Slinton 	}
483*9702Slinton 
484*9702Slinton struct respref
485*9702Slinton respref[] = {
486*9702Slinton 	INTAREG|INTBREG,	INTAREG|INTBREG,
487*9702Slinton 	INAREG|INBREG,	INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
488*9702Slinton 	INTEMP,	INTEMP,
489*9702Slinton 	FORARG,	FORARG,
490*9702Slinton 	INTEMP,	INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
491*9702Slinton 	0,	0 };
492*9702Slinton 
493*9702Slinton setregs(){ /* set up temporary registers */
494*9702Slinton 	fregs = 6;	/* tbl- 6 free regs on VAX (0-5) */
495*9702Slinton 	;
496*9702Slinton 	}
497*9702Slinton 
498*9702Slinton szty(t){ /* size, in registers, needed to hold thing of type t */
499*9702Slinton 	return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
500*9702Slinton 	}
501*9702Slinton 
502*9702Slinton rewfld( p ) NODE *p; {
503*9702Slinton 	return(1);
504*9702Slinton 	}
505*9702Slinton 
506*9702Slinton callreg(p) NODE *p; {
507*9702Slinton 	return( R0 );
508*9702Slinton 	}
509*9702Slinton 
510*9702Slinton base( p ) register NODE *p; {
511*9702Slinton 	register int o = p->in.op;
512*9702Slinton 
513*9702Slinton 	if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */
514*9702Slinton 	if( o==REG ) return( p->tn.rval );
515*9702Slinton     if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON)
516*9702Slinton 		return( p->in.left->tn.rval );
517*9702Slinton     if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
518*9702Slinton 		return( p->tn.rval + 0200*1 );
519*9702Slinton 	if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 );
520*9702Slinton 	if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 );
521*9702Slinton 	if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG
522*9702Slinton 	  && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
523*9702Slinton 		return( p->in.left->in.left->tn.rval + 0200*(1+2) );
524*9702Slinton 	return( -1 );
525*9702Slinton 	}
526*9702Slinton 
527*9702Slinton offset( p, tyl ) register NODE *p; int tyl; {
528*9702Slinton 
529*9702Slinton 	if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval );
530*9702Slinton 	if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) &&
531*9702Slinton 	      (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0')
532*9702Slinton 	      && (1<<p->in.right->tn.lval)==tyl))
533*9702Slinton 		return( p->in.left->tn.rval );
534*9702Slinton 	return( -1 );
535*9702Slinton 	}
536*9702Slinton 
537*9702Slinton makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
538*9702Slinton 	register NODE *t;
539*9702Slinton 	register int i;
540*9702Slinton 	NODE *f;
541*9702Slinton 
542*9702Slinton 	p->in.op = OREG;
543*9702Slinton 	f = p->in.left; 	/* have to free this subtree later */
544*9702Slinton 
545*9702Slinton 	/* init base */
546*9702Slinton 	switch (q->in.op) {
547*9702Slinton 		case ICON:
548*9702Slinton 		case REG:
549*9702Slinton 		case OREG:
550*9702Slinton 			t = q;
551*9702Slinton 			break;
552*9702Slinton 
553*9702Slinton 		case MINUS:
554*9702Slinton 			q->in.right->tn.lval = -q->in.right->tn.lval;
555*9702Slinton 		case PLUS:
556*9702Slinton 			t = q->in.right;
557*9702Slinton 			break;
558*9702Slinton 
559*9702Slinton 		case INCR:
560*9702Slinton 		case ASG MINUS:
561*9702Slinton 			t = q->in.left;
562*9702Slinton 			break;
563*9702Slinton 
564*9702Slinton 		case UNARY MUL:
565*9702Slinton 			t = q->in.left->in.left;
566*9702Slinton 			break;
567*9702Slinton 
568*9702Slinton 		default:
569*9702Slinton 			cerror("illegal makeor2");
570*9702Slinton 	}
571*9702Slinton 
572*9702Slinton 	p->tn.lval = t->tn.lval;
573*9702Slinton #ifndef FLEXNAMES
574*9702Slinton 	for(i=0; i<NCHNAM; ++i)
575*9702Slinton 		p->in.name[i] = t->in.name[i];
576*9702Slinton #else
577*9702Slinton 	p->in.name = t->in.name;
578*9702Slinton #endif
579*9702Slinton 
580*9702Slinton 	/* init offset */
581*9702Slinton 	p->tn.rval = R2PACK( (b & 0177), o, (b>>7) );
582*9702Slinton 
583*9702Slinton 	tfree(f);
584*9702Slinton 	return;
585*9702Slinton 	}
586*9702Slinton 
587*9702Slinton canaddr( p ) NODE *p; {
588*9702Slinton 	register int o = p->in.op;
589*9702Slinton 
590*9702Slinton 	if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
591*9702Slinton 	return(0);
592*9702Slinton 	}
593*9702Slinton 
594*9702Slinton shltype( o, p ) register NODE *p; {
595*9702Slinton 	return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) );
596*9702Slinton 	}
597*9702Slinton 
598*9702Slinton flshape( p ) register NODE *p; {
599*9702Slinton 	return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON ||
600*9702Slinton 		(p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) );
601*9702Slinton 	}
602*9702Slinton 
603*9702Slinton shtemp( p ) register NODE *p; {
604*9702Slinton 	if( p->in.op == STARG ) p = p->in.left;
605*9702Slinton 	return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) );
606*9702Slinton 	}
607*9702Slinton 
608*9702Slinton shumul( p ) register NODE *p; {
609*9702Slinton 	register o;
610*9702Slinton 	extern int xdebug;
611*9702Slinton 
612*9702Slinton 	if (xdebug) {
613*9702Slinton 		 printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op);
614*9702Slinton 		printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval);
615*9702Slinton 		}
616*9702Slinton 
617*9702Slinton 
618*9702Slinton 	o = p->in.op;
619*9702Slinton 	if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM );
620*9702Slinton 
621*9702Slinton 	if( ( o == INCR || o == ASG MINUS ) &&
622*9702Slinton 	    ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) &&
623*9702Slinton 	    p->in.right->in.name[0] == '\0' )
624*9702Slinton 		{
625*9702Slinton 		switch (p->in.left->in.type)
626*9702Slinton 			{
627*9702Slinton 			case CHAR|PTR:
628*9702Slinton 			case UCHAR|PTR:
629*9702Slinton 				o = 1;
630*9702Slinton 				break;
631*9702Slinton 
632*9702Slinton 			case SHORT|PTR:
633*9702Slinton 			case USHORT|PTR:
634*9702Slinton 				o = 2;
635*9702Slinton 				break;
636*9702Slinton 
637*9702Slinton 			case INT|PTR:
638*9702Slinton 			case UNSIGNED|PTR:
639*9702Slinton 			case LONG|PTR:
640*9702Slinton 			case ULONG|PTR:
641*9702Slinton 			case FLOAT|PTR:
642*9702Slinton 				o = 4;
643*9702Slinton 				break;
644*9702Slinton 
645*9702Slinton 			case DOUBLE|PTR:
646*9702Slinton 				o = 8;
647*9702Slinton 				break;
648*9702Slinton 
649*9702Slinton 			default:
650*9702Slinton 				if ( ISPTR(p->in.left->in.type) ) {
651*9702Slinton 					o = 4;
652*9702Slinton 					break;
653*9702Slinton 					}
654*9702Slinton 				else return(0);
655*9702Slinton 			}
656*9702Slinton 		return( p->in.right->tn.lval == o ? STARREG : 0);
657*9702Slinton 		}
658*9702Slinton 
659*9702Slinton 	return( 0 );
660*9702Slinton 	}
661*9702Slinton 
662*9702Slinton adrcon( val ) CONSZ val; {
663*9702Slinton 	printf( "$" );
664*9702Slinton 	printf( CONFMT, val );
665*9702Slinton 	}
666*9702Slinton 
667*9702Slinton conput( p ) register NODE *p; {
668*9702Slinton 	switch( p->in.op ){
669*9702Slinton 
670*9702Slinton 	case ICON:
671*9702Slinton 		acon( p );
672*9702Slinton 		return;
673*9702Slinton 
674*9702Slinton 	case REG:
675*9702Slinton 		printf( "%s", rnames[p->tn.rval] );
676*9702Slinton 		return;
677*9702Slinton 
678*9702Slinton 	default:
679*9702Slinton 		cerror( "illegal conput" );
680*9702Slinton 		}
681*9702Slinton 	}
682*9702Slinton 
683*9702Slinton insput( p ) register NODE *p; {
684*9702Slinton 	cerror( "insput" );
685*9702Slinton 	}
686*9702Slinton 
687*9702Slinton upput( p ) register NODE *p; {
688*9702Slinton 	cerror( "upput" );
689*9702Slinton 	}
690*9702Slinton 
691*9702Slinton adrput( p ) register NODE *p; {
692*9702Slinton 	register int r;
693*9702Slinton 	/* output an address, with offsets, from p */
694*9702Slinton 
695*9702Slinton 	if( p->in.op == FLD ){
696*9702Slinton 		p = p->in.left;
697*9702Slinton 		}
698*9702Slinton 	switch( p->in.op ){
699*9702Slinton 
700*9702Slinton 	case NAME:
701*9702Slinton 		acon( p );
702*9702Slinton 		return;
703*9702Slinton 
704*9702Slinton 	case ICON:
705*9702Slinton 		/* addressable value of the constant */
706*9702Slinton 		printf( "$" );
707*9702Slinton 		acon( p );
708*9702Slinton 		return;
709*9702Slinton 
710*9702Slinton 	case REG:
711*9702Slinton 		printf( "%s", rnames[p->tn.rval] );
712*9702Slinton 		return;
713*9702Slinton 
714*9702Slinton 	case OREG:
715*9702Slinton 		r = p->tn.rval;
716*9702Slinton 		if( R2TEST(r) ){ /* double indexing */
717*9702Slinton 			register int flags;
718*9702Slinton 
719*9702Slinton 			flags = R2UPK3(r);
720*9702Slinton 			if( flags & 1 ) printf("*");
721*9702Slinton 			if( flags & 4 ) printf("-");
722*9702Slinton 			if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p);
723*9702Slinton 			if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
724*9702Slinton 			if( flags & 2 ) printf("+");
725*9702Slinton 			printf( "[%s]", rnames[R2UPK2(r)] );
726*9702Slinton 			return;
727*9702Slinton 			}
728*9702Slinton 		if( r == AP ){  /* in the argument region */
729*9702Slinton 			if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" );
730*9702Slinton 			printf( CONFMT, p->tn.lval );
731*9702Slinton 			printf( "(ap)" );
732*9702Slinton 			return;
733*9702Slinton 			}
734*9702Slinton 		if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p );
735*9702Slinton 		printf( "(%s)", rnames[p->tn.rval] );
736*9702Slinton 		return;
737*9702Slinton 
738*9702Slinton 	case UNARY MUL:
739*9702Slinton 		/* STARNM or STARREG found */
740*9702Slinton 		if( tshape(p, STARNM) ) {
741*9702Slinton 			printf( "*" );
742*9702Slinton 			adrput( p->in.left);
743*9702Slinton 			}
744*9702Slinton 		else {	/* STARREG - really auto inc or dec */
745*9702Slinton 			register NODE *q;
746*9702Slinton 
747*9702Slinton /* tbl
748*9702Slinton 			p = p->in.left;
749*9702Slinton 			p->in.left->in.op = OREG;
750*9702Slinton 			if( p->in.op == INCR ) {
751*9702Slinton 				adrput( p->in.left );
752*9702Slinton 				printf( "+" );
753*9702Slinton 				}
754*9702Slinton 			else {
755*9702Slinton 				printf( "-" );
756*9702Slinton 				adrput( p->in.left );
757*9702Slinton 				}
758*9702Slinton    tbl */
759*9702Slinton 			printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"),
760*9702Slinton 				rnames[p->in.left->in.left->tn.rval],
761*9702Slinton 				(p->in.left->in.op==INCR ? "+" : "") );
762*9702Slinton 			p->in.op = OREG;
763*9702Slinton 			p->tn.rval = p->in.left->in.left->tn.rval;
764*9702Slinton 			q = p->in.left;
765*9702Slinton 			p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0);
766*9702Slinton #ifndef FLEXNAMES
767*9702Slinton 			p->in.name[0] = '\0';
768*9702Slinton #else
769*9702Slinton 			p->in.name = "";
770*9702Slinton #endif
771*9702Slinton 			tfree(q);
772*9702Slinton 		}
773*9702Slinton 		return;
774*9702Slinton 
775*9702Slinton 	default:
776*9702Slinton 		cerror( "illegal address" );
777*9702Slinton 		return;
778*9702Slinton 
779*9702Slinton 		}
780*9702Slinton 
781*9702Slinton 	}
782*9702Slinton 
783*9702Slinton acon( p ) register NODE *p; { /* print out a constant */
784*9702Slinton 
785*9702Slinton 	if( p->in.name[0] == '\0' ){
786*9702Slinton 		printf( CONFMT, p->tn.lval);
787*9702Slinton 		}
788*9702Slinton 	else if( p->tn.lval == 0 ) {
789*9702Slinton #ifndef FLEXNAMES
790*9702Slinton 		printf( "%.8s", p->in.name );
791*9702Slinton #else
792*9702Slinton 		printf( "%s", p->in.name );
793*9702Slinton #endif
794*9702Slinton 		}
795*9702Slinton 	else {
796*9702Slinton #ifndef FLEXNAMES
797*9702Slinton 		printf( "%.8s+", p->in.name );
798*9702Slinton #else
799*9702Slinton 		printf( "%s+", p->in.name );
800*9702Slinton #endif
801*9702Slinton 		printf( CONFMT, p->tn.lval );
802*9702Slinton 		}
803*9702Slinton 	}
804*9702Slinton 
805*9702Slinton /*
806*9702Slinton aacon( p ) register NODE *p; { /* print out a constant */
807*9702Slinton /*
808*9702Slinton 
809*9702Slinton 	if( p->in.name[0] == '\0' ){
810*9702Slinton 		printf( CONFMT, p->tn.lval);
811*9702Slinton 		return( 0 );
812*9702Slinton 		}
813*9702Slinton 	else if( p->tn.lval == 0 ) {
814*9702Slinton #ifndef FLEXNAMES
815*9702Slinton 		printf( "$%.8s", p->in.name );
816*9702Slinton #else
817*9702Slinton 		printf( "$%s", p->in.name );
818*9702Slinton #endif
819*9702Slinton 		return( 1 );
820*9702Slinton 		}
821*9702Slinton 	else {
822*9702Slinton 		printf( "$(" );
823*9702Slinton 		printf( CONFMT, p->tn.lval );
824*9702Slinton 		printf( "+" );
825*9702Slinton #ifndef FLEXNAMES
826*9702Slinton 		printf( "%.8s)", p->in.name );
827*9702Slinton #else
828*9702Slinton 		printf( "%s)", p->in.name );
829*9702Slinton #endif
830*9702Slinton 		return(1);
831*9702Slinton 		}
832*9702Slinton 	}
833*9702Slinton  */
834*9702Slinton 
835*9702Slinton genscall( p, cookie ) register NODE *p; {
836*9702Slinton 	/* structure valued call */
837*9702Slinton 	return( gencall( p, cookie ) );
838*9702Slinton 	}
839*9702Slinton 
840*9702Slinton /* tbl */
841*9702Slinton int gc_numbytes;
842*9702Slinton /* tbl */
843*9702Slinton 
844*9702Slinton gencall( p, cookie ) register NODE *p; {
845*9702Slinton 	/* generate the call given by p */
846*9702Slinton 	register NODE *p1, *ptemp;
847*9702Slinton 	register temp, temp1;
848*9702Slinton 	register m;
849*9702Slinton 
850*9702Slinton 	if( p->in.right ) temp = argsize( p->in.right );
851*9702Slinton 	else temp = 0;
852*9702Slinton 
853*9702Slinton 	if( p->in.op == STCALL || p->in.op == UNARY STCALL ){
854*9702Slinton 		/* set aside room for structure return */
855*9702Slinton 
856*9702Slinton 		if( p->stn.stsize > temp ) temp1 = p->stn.stsize;
857*9702Slinton 		else temp1 = temp;
858*9702Slinton 		}
859*9702Slinton 
860*9702Slinton 	if( temp > maxargs ) maxargs = temp;
861*9702Slinton 	SETOFF(temp1,4);
862*9702Slinton 
863*9702Slinton 	if( p->in.right ){ /* make temp node, put offset in, and generate args */
864*9702Slinton 		ptemp = talloc();
865*9702Slinton 		ptemp->in.op = OREG;
866*9702Slinton 		ptemp->tn.lval = -1;
867*9702Slinton 		ptemp->tn.rval = SP;
868*9702Slinton #ifndef FLEXNAMES
869*9702Slinton 		ptemp->in.name[0] = '\0';
870*9702Slinton #else
871*9702Slinton 		ptemp->in.name = "";
872*9702Slinton #endif
873*9702Slinton 		ptemp->in.rall = NOPREF;
874*9702Slinton 		ptemp->in.su = 0;
875*9702Slinton 		genargs( p->in.right, ptemp );
876*9702Slinton 		ptemp->in.op = FREE;
877*9702Slinton 		}
878*9702Slinton 
879*9702Slinton 	p1 = p->in.left;
880*9702Slinton 	if( p1->in.op != ICON ){
881*9702Slinton 		if( p1->in.op != REG ){
882*9702Slinton 			if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){
883*9702Slinton 				if( p1->in.op != NAME ){
884*9702Slinton 					order( p1, INAREG );
885*9702Slinton 					}
886*9702Slinton 				}
887*9702Slinton 			}
888*9702Slinton 		}
889*9702Slinton 
890*9702Slinton /*
891*9702Slinton 	if( p1->in.op == REG && p->tn.rval == R5 ){
892*9702Slinton 		cerror( "call register overwrite" );
893*9702Slinton 		}
894*9702Slinton  */
895*9702Slinton /* tbl
896*9702Slinton 	setup gc_numbytes so reference to ZC works */
897*9702Slinton 
898*9702Slinton 	gc_numbytes = temp&(0x3ff);
899*9702Slinton /* tbl */
900*9702Slinton 
901*9702Slinton 	p->in.op = UNARY CALL;
902*9702Slinton 	m = match( p, INTAREG|INTBREG );
903*9702Slinton 
904*9702Slinton 	/* compensate for deficiency in 'ret' instruction ... wah,kre */
905*9702Slinton 	/* (plus in assignment to gc_numbytes above, for neatness only) */
906*9702Slinton 	if (temp >= 1024)
907*9702Slinton 		printf("	addl2	$%d,sp\n", (temp&(~0x3ff)));
908*9702Slinton 
909*9702Slinton /* tbl
910*9702Slinton 	switch( temp ) {
911*9702Slinton 	case 0:
912*9702Slinton 		break;
913*9702Slinton 	case 2:
914*9702Slinton 		printf( "	tst	(sp)+\n" );
915*9702Slinton 		break;
916*9702Slinton 	case 4:
917*9702Slinton 		printf( "	cmp	(sp)+,(sp)+\n" );
918*9702Slinton 		break;
919*9702Slinton 	default:
920*9702Slinton 		printf( "	add	$%d,sp\n", temp);
921*9702Slinton 		}
922*9702Slinton    tbl */
923*9702Slinton 	return(m != MDONE);
924*9702Slinton 	}
925*9702Slinton 
926*9702Slinton /* tbl */
927*9702Slinton char *
928*9702Slinton ccbranches[] = {
929*9702Slinton 	"	jeql	L%d\n",
930*9702Slinton 	"	jneq	L%d\n",
931*9702Slinton 	"	jleq	L%d\n",
932*9702Slinton 	"	jlss	L%d\n",
933*9702Slinton 	"	jgeq	L%d\n",
934*9702Slinton 	"	jgtr	L%d\n",
935*9702Slinton 	"	jlequ	L%d\n",
936*9702Slinton 	"	jlssu	L%d\n",
937*9702Slinton 	"	jgequ	L%d\n",
938*9702Slinton 	"	jgtru	L%d\n",
939*9702Slinton 	};
940*9702Slinton /* tbl */
941*9702Slinton 
942*9702Slinton cbgen( o, lab, mode ) { /*   printf conditional and unconditional branches */
943*9702Slinton 
944*9702Slinton /* tbl */
945*9702Slinton 	if( o == 0 ) printf( "	jbr	L%d\n", lab );
946*9702Slinton /* tbl */
947*9702Slinton 	else {
948*9702Slinton 		if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
949*9702Slinton 		printf( ccbranches[o-EQ], lab );
950*9702Slinton 		}
951*9702Slinton 	}
952*9702Slinton 
953*9702Slinton nextcook( p, cookie ) NODE *p; {
954*9702Slinton 	/* we have failed to match p with cookie; try another */
955*9702Slinton 	if( cookie == FORREW ) return( 0 );  /* hopeless! */
956*9702Slinton 	if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
957*9702Slinton 	if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
958*9702Slinton 	return( FORREW );
959*9702Slinton 	}
960*9702Slinton 
961*9702Slinton lastchance( p, cook ) NODE *p; {
962*9702Slinton 	/* forget it! */
963*9702Slinton 	return(0);
964*9702Slinton 	}
965*9702Slinton 
966*9702Slinton optim2( p ) register NODE *p; {
967*9702Slinton 	/* do local tree transformations and optimizations */
968*9702Slinton 
969*9702Slinton 	register NODE *r;
970*9702Slinton 
971*9702Slinton 	switch( p->in.op ) {
972*9702Slinton 
973*9702Slinton 	case AND:
974*9702Slinton 		/* commute L and R to eliminate compliments and constants */
975*9702Slinton 		if( (p->in.left->in.op==ICON&&p->in.left->in.name[0]==0) || p->in.left->in.op==COMPL ) {
976*9702Slinton 			r = p->in.left;
977*9702Slinton 			p->in.left = p->in.right;
978*9702Slinton 			p->in.right = r;
979*9702Slinton 			}
980*9702Slinton 	case ASG AND:
981*9702Slinton 		/* change meaning of AND to ~R&L - bic on pdp11 */
982*9702Slinton 		r = p->in.right;
983*9702Slinton 		if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */
984*9702Slinton 			r->tn.lval = ~r->tn.lval;
985*9702Slinton 			}
986*9702Slinton 		else if( r->in.op==COMPL ) { /* ~~A => A */
987*9702Slinton 			r->in.op = FREE;
988*9702Slinton 			p->in.right = r->in.left;
989*9702Slinton 			}
990*9702Slinton 		else { /* insert complement node */
991*9702Slinton 			p->in.right = talloc();
992*9702Slinton 			p->in.right->in.op = COMPL;
993*9702Slinton 			p->in.right->in.rall = NOPREF;
994*9702Slinton 			p->in.right->in.type = r->in.type;
995*9702Slinton 			p->in.right->in.left = r;
996*9702Slinton 			p->in.right->in.right = NULL;
997*9702Slinton 			}
998*9702Slinton 		break;
999*9702Slinton 
1000*9702Slinton 		}
1001*9702Slinton 	}
1002*9702Slinton 
1003*9702Slinton NODE * addroreg(l)
1004*9702Slinton 				/* OREG was built in clocal()
1005*9702Slinton 				 * for an auto or formal parameter
1006*9702Slinton 				 * now its address is being taken
1007*9702Slinton 				 * local code must unwind it
1008*9702Slinton 				 * back to PLUS/MINUS REG ICON
1009*9702Slinton 				 * according to local conventions
1010*9702Slinton 				 */
1011*9702Slinton {
1012*9702Slinton 	cerror("address of OREG taken");
1013*9702Slinton }
1014*9702Slinton 
1015*9702Slinton 
1016*9702Slinton 
1017*9702Slinton # ifndef ONEPASS
1018*9702Slinton main( argc, argv ) char *argv[]; {
1019*9702Slinton 	return( mainp2( argc, argv ) );
1020*9702Slinton 	}
1021*9702Slinton # endif
1022*9702Slinton 
1023*9702Slinton 
1024*9702Slinton /* added by jwf */
1025*9702Slinton struct functbl {
1026*9702Slinton 	int fop;
1027*9702Slinton 	TWORD ftype;
1028*9702Slinton 	char *func;
1029*9702Slinton 	} opfunc[] = {
1030*9702Slinton 	DIV,		TANY,	"udiv",
1031*9702Slinton 	MOD,		TANY,	"urem",
1032*9702Slinton 	ASG DIV,	TANY,	"udiv",
1033*9702Slinton 	ASG MOD,	TANY,	"urem",
1034*9702Slinton 	0,	0,	0 };
1035*9702Slinton 
1036*9702Slinton hardops(p)  register NODE *p; {
1037*9702Slinton 	/* change hard to do operators into function calls.  */
1038*9702Slinton 	register NODE *q;
1039*9702Slinton 	register struct functbl *f;
1040*9702Slinton 	register o;
1041*9702Slinton 	register TWORD t;
1042*9702Slinton 
1043*9702Slinton 	o = p->in.op;
1044*9702Slinton 	t = p->in.type;
1045*9702Slinton 	if( t!=UNSIGNED && t!=ULONG ) return;
1046*9702Slinton 
1047*9702Slinton 	for( f=opfunc; f->fop; f++ ) {
1048*9702Slinton 		if( o==f->fop ) goto convert;
1049*9702Slinton 		}
1050*9702Slinton 	return;
1051*9702Slinton 
1052*9702Slinton 	/* need to rewrite tree for ASG OP */
1053*9702Slinton 	/* must change ASG OP to a simple OP */
1054*9702Slinton 	convert:
1055*9702Slinton 	if( asgop( o ) ) {
1056*9702Slinton 		q = talloc();
1057*9702Slinton 		switch( p->in.op ) {
1058*9702Slinton 			case ASG DIV:
1059*9702Slinton 				q->in.op = DIV;
1060*9702Slinton 				break;
1061*9702Slinton 			case ASG MOD:
1062*9702Slinton 				q->in.op = MOD;
1063*9702Slinton 				break;
1064*9702Slinton 		}
1065*9702Slinton 		q->in.rall = NOPREF;
1066*9702Slinton 		q->in.type = p->in.type;
1067*9702Slinton 		q->in.left = tcopy(p->in.left);
1068*9702Slinton 		q->in.right = p->in.right;
1069*9702Slinton 		p->in.op = ASSIGN;
1070*9702Slinton 		p->in.right = q;
1071*9702Slinton 		zappost(q->in.left); /* remove post-INCR(DECR) from new node */
1072*9702Slinton 		fixpre(q->in.left);	/* change pre-INCR(DECR) to +/-	*/
1073*9702Slinton 		p = q;
1074*9702Slinton 
1075*9702Slinton 	}
1076*9702Slinton 
1077*9702Slinton 	/* build comma op for args to function */
1078*9702Slinton 	q = talloc();
1079*9702Slinton 	q->in.op = CM;
1080*9702Slinton 	q->in.rall = NOPREF;
1081*9702Slinton 	q->in.type = INT;
1082*9702Slinton 	q->in.left = p->in.left;
1083*9702Slinton 	q->in.right = p->in.right;
1084*9702Slinton 	p->in.op = CALL;
1085*9702Slinton 	p->in.right = q;
1086*9702Slinton 
1087*9702Slinton 	/* put function name in left node of call */
1088*9702Slinton 	p->in.left = q = talloc();
1089*9702Slinton 	q->in.op = ICON;
1090*9702Slinton 	q->in.rall = NOPREF;
1091*9702Slinton 	q->in.type = INCREF( FTN + p->in.type );
1092*9702Slinton #ifndef FLEXNAMES
1093*9702Slinton 	strcpy( q->in.name, f->func );
1094*9702Slinton #else
1095*9702Slinton 	q->in.name = f->func;
1096*9702Slinton #endif
1097*9702Slinton 	q->tn.lval = 0;
1098*9702Slinton 	q->tn.rval = 0;
1099*9702Slinton 
1100*9702Slinton 	return;
1101*9702Slinton 
1102*9702Slinton 	}
1103*9702Slinton 
1104*9702Slinton zappost(p) NODE *p; {
1105*9702Slinton 	/* look for ++ and -- operators and remove them */
1106*9702Slinton 
1107*9702Slinton 	register o, ty;
1108*9702Slinton 	register NODE *q;
1109*9702Slinton 	o = p->in.op;
1110*9702Slinton 	ty = optype( o );
1111*9702Slinton 
1112*9702Slinton 	switch( o ){
1113*9702Slinton 
1114*9702Slinton 	case INCR:
1115*9702Slinton 	case DECR:
1116*9702Slinton 			q = p->in.left;
1117*9702Slinton 			p->in.right->in.op = FREE;  /* zap constant */
1118*9702Slinton 			ncopy( p, q );
1119*9702Slinton 			q->in.op = FREE;
1120*9702Slinton 			return;
1121*9702Slinton 
1122*9702Slinton 		}
1123*9702Slinton 
1124*9702Slinton 	if( ty == BITYPE ) zappost( p->in.right );
1125*9702Slinton 	if( ty != LTYPE ) zappost( p->in.left );
1126*9702Slinton }
1127*9702Slinton 
1128*9702Slinton fixpre(p) NODE *p; {
1129*9702Slinton 
1130*9702Slinton 	register o, ty;
1131*9702Slinton 	o = p->in.op;
1132*9702Slinton 	ty = optype( o );
1133*9702Slinton 
1134*9702Slinton 	switch( o ){
1135*9702Slinton 
1136*9702Slinton 	case ASG PLUS:
1137*9702Slinton 			p->in.op = PLUS;
1138*9702Slinton 			break;
1139*9702Slinton 	case ASG MINUS:
1140*9702Slinton 			p->in.op = MINUS;
1141*9702Slinton 			break;
1142*9702Slinton 		}
1143*9702Slinton 
1144*9702Slinton 	if( ty == BITYPE ) fixpre( p->in.right );
1145*9702Slinton 	if( ty != LTYPE ) fixpre( p->in.left );
1146*9702Slinton }
1147*9702Slinton 
1148*9702Slinton myreader(p) register NODE *p; {
1149*9702Slinton 	walkf( p, hardops );	/* convert ops to function calls */
1150*9702Slinton 	canon( p );		/* expands r-vals for fileds */
1151*9702Slinton 	walkf( p, optim2 );
1152*9702Slinton 	/* jwf toff = 0;  /* stack offset swindle */
1153*9702Slinton 	}
1154*9702Slinton 
1155*9702Slinton 
1156