xref: /netbsd/external/bsd/pcc/dist/pcc/arch/pdp10/local2.c (revision 6935091c)
1*6935091cSplunky /*	Id: local2.c,v 1.106 2015/01/04 19:17:23 ragge Exp 	*/
2*6935091cSplunky /*	$NetBSD: local2.c,v 1.1.1.5 2016/02/09 20:28:26 plunky Exp $	*/
36e0bca22Sgmcgarry /*
46e0bca22Sgmcgarry  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
56e0bca22Sgmcgarry  * All rights reserved.
66e0bca22Sgmcgarry  *
76e0bca22Sgmcgarry  * Redistribution and use in source and binary forms, with or without
86e0bca22Sgmcgarry  * modification, are permitted provided that the following conditions
96e0bca22Sgmcgarry  * are met:
106e0bca22Sgmcgarry  * 1. Redistributions of source code must retain the above copyright
116e0bca22Sgmcgarry  *    notice, this list of conditions and the following disclaimer.
126e0bca22Sgmcgarry  * 2. Redistributions in binary form must reproduce the above copyright
136e0bca22Sgmcgarry  *    notice, this list of conditions and the following disclaimer in the
146e0bca22Sgmcgarry  *    documentation and/or other materials provided with the distribution.
156e0bca22Sgmcgarry  * 3. The name of the author may not be used to endorse or promote products
166e0bca22Sgmcgarry  *    derived from this software without specific prior written permission
176e0bca22Sgmcgarry  *
186e0bca22Sgmcgarry  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
196e0bca22Sgmcgarry  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206e0bca22Sgmcgarry  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
216e0bca22Sgmcgarry  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
226e0bca22Sgmcgarry  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
236e0bca22Sgmcgarry  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246e0bca22Sgmcgarry  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256e0bca22Sgmcgarry  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266e0bca22Sgmcgarry  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
276e0bca22Sgmcgarry  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286e0bca22Sgmcgarry  */
296e0bca22Sgmcgarry 
306e0bca22Sgmcgarry 
316e0bca22Sgmcgarry # include "pass2.h"
326e0bca22Sgmcgarry # include <ctype.h>
336e0bca22Sgmcgarry 
346e0bca22Sgmcgarry void acon(FILE *, NODE *p);
356e0bca22Sgmcgarry int argsize(NODE *p);
366e0bca22Sgmcgarry void genargs(NODE *p);
376e0bca22Sgmcgarry 
386e0bca22Sgmcgarry static int offlab;
396e0bca22Sgmcgarry int offarg;
406e0bca22Sgmcgarry static int addto;
416e0bca22Sgmcgarry static int regoff[16];
426e0bca22Sgmcgarry 
436e0bca22Sgmcgarry void
deflab(int label)446e0bca22Sgmcgarry deflab(int label)
456e0bca22Sgmcgarry {
466e0bca22Sgmcgarry 	printf(LABFMT ":\n", label);
476e0bca22Sgmcgarry }
486e0bca22Sgmcgarry 
496e0bca22Sgmcgarry void
prologue(struct interpass_prolog * ipp)506e0bca22Sgmcgarry prologue(struct interpass_prolog *ipp)
516e0bca22Sgmcgarry {
526e0bca22Sgmcgarry 	int i, j;
536e0bca22Sgmcgarry 
546e0bca22Sgmcgarry 	if (ipp->ipp_vis)
556e0bca22Sgmcgarry 		printf("	.globl %s\n", ipp->ipp_name);
566e0bca22Sgmcgarry 	printf("%s:\n", ipp->ipp_name);
576e0bca22Sgmcgarry 	addto = p2maxautooff;
586e0bca22Sgmcgarry 	if (addto >= AUTOINIT/SZCHAR)
596e0bca22Sgmcgarry 		addto -= AUTOINIT/SZCHAR;
606e0bca22Sgmcgarry 	addto /= SZINT/SZCHAR;	/* use words here */
616e0bca22Sgmcgarry 	printf("	push %s,%s\n",rnames[STKREG], rnames[FPREG]);
626e0bca22Sgmcgarry 	printf("	move %s,%s\n", rnames[FPREG],rnames[STKREG]);
636e0bca22Sgmcgarry 
64c4627bc7Sgmcgarry 	for (i = ipp->ipp_regs[0], j = 0; i ; i >>= 1, j++) {
656e0bca22Sgmcgarry 		if (i & 1)
666e0bca22Sgmcgarry 			regoff[j] = addto++;
676e0bca22Sgmcgarry 	}
686e0bca22Sgmcgarry 	if (addto)
696e0bca22Sgmcgarry 		printf("	addi %s,0%o\n", rnames[STKREG], addto);
70c4627bc7Sgmcgarry 
71c4627bc7Sgmcgarry 	for (i = ipp->ipp_regs[0], j = 0; i ; i >>= 1, j++) {
726e0bca22Sgmcgarry 		if (i & 1)
736e0bca22Sgmcgarry 			printf("	movem %s,%d(%s)\n",
746e0bca22Sgmcgarry 			    rnames[j], regoff[j], rnames[STKREG]);
756e0bca22Sgmcgarry 	}
766e0bca22Sgmcgarry }
776e0bca22Sgmcgarry 
786e0bca22Sgmcgarry void
eoftn(struct interpass_prolog * ipp)796e0bca22Sgmcgarry eoftn(struct interpass_prolog *ipp)
806e0bca22Sgmcgarry {
816e0bca22Sgmcgarry 	int i, j;
826e0bca22Sgmcgarry 
836e0bca22Sgmcgarry 	if (ipp->ipp_ip.ip_lbl == 0)
846e0bca22Sgmcgarry 		return; /* no code needs to be generated */
85c4627bc7Sgmcgarry 	for (i = ipp->ipp_regs[0], j = 0; i ; i >>= 1, j++) {
866e0bca22Sgmcgarry 		if (i & 1)
876e0bca22Sgmcgarry 			printf("	move %s,%d(%s)\n",
886e0bca22Sgmcgarry 			    rnames[j], regoff[j], rnames[STKREG]);
896e0bca22Sgmcgarry 	}
906e0bca22Sgmcgarry 	printf("	move %s,%s\n", rnames[STKREG], rnames[FPREG]);
916e0bca22Sgmcgarry 	printf("	pop %s,%s\n", rnames[STKREG], rnames[FPREG]);
926e0bca22Sgmcgarry 	printf("	popj %s,\n", rnames[STKREG]);
936e0bca22Sgmcgarry }
946e0bca22Sgmcgarry 
956e0bca22Sgmcgarry #if 0
966e0bca22Sgmcgarry void
976e0bca22Sgmcgarry prologue(int regs, int autos)
986e0bca22Sgmcgarry {
996e0bca22Sgmcgarry 	int i, addto;
1006e0bca22Sgmcgarry 
101c4627bc7Sgmcgarry 	offlab = getlab2();
1026e0bca22Sgmcgarry 	if (regs < 0 || autos < 0) {
1036e0bca22Sgmcgarry 		/*
1046e0bca22Sgmcgarry 		 * non-optimized code, jump to epilogue for code generation.
1056e0bca22Sgmcgarry 		 */
106c4627bc7Sgmcgarry 		ftlab1 = getlab2();
107c4627bc7Sgmcgarry 		ftlab2 = getlab2();
1086e0bca22Sgmcgarry 		printf("	jrst L%d\n", ftlab1);
1096e0bca22Sgmcgarry 		printf("L%d:\n", ftlab2);
1106e0bca22Sgmcgarry 	} else {
1116e0bca22Sgmcgarry 		/*
1126e0bca22Sgmcgarry 		 * We here know what register to save and how much to
1136e0bca22Sgmcgarry 		 * add to the stack.
1146e0bca22Sgmcgarry 		 */
1156e0bca22Sgmcgarry 		autos = autos + (SZINT-1);
1166e0bca22Sgmcgarry 		addto = (autos - AUTOINIT)/SZINT + (MAXRVAR-regs);
1176e0bca22Sgmcgarry 		if (addto || gflag) {
1186e0bca22Sgmcgarry 			printf("	push %s,%s\n",rnames[017], rnames[016]);
1196e0bca22Sgmcgarry 			printf("	move %s,%s\n", rnames[016],rnames[017]);
1206e0bca22Sgmcgarry 			for (i = regs; i < MAXRVAR; i++) {
1216e0bca22Sgmcgarry 				int db = ((i+1) < MAXRVAR);
1226e0bca22Sgmcgarry 				printf("	%smovem %s,0%o(%s)\n",
1236e0bca22Sgmcgarry 				    db ? "d" : "",
1246e0bca22Sgmcgarry 				    rnames[i+1], i+1-regs, rnames[016]);
1256e0bca22Sgmcgarry 				if (db)
1266e0bca22Sgmcgarry 					i++;
1276e0bca22Sgmcgarry 			}
1286e0bca22Sgmcgarry 			if (addto)
1296e0bca22Sgmcgarry 				printf("	addi %s,0%o\n", rnames[017], addto);
1306e0bca22Sgmcgarry 		} else
1316e0bca22Sgmcgarry 			offarg = 1;
1326e0bca22Sgmcgarry 	}
1336e0bca22Sgmcgarry }
1346e0bca22Sgmcgarry 
1356e0bca22Sgmcgarry /*
1366e0bca22Sgmcgarry  * End of block.
1376e0bca22Sgmcgarry  */
1386e0bca22Sgmcgarry void
1396e0bca22Sgmcgarry eoftn(int regs, int autos, int retlab)
1406e0bca22Sgmcgarry {
1416e0bca22Sgmcgarry 	register OFFSZ spoff;	/* offset from stack pointer */
1426e0bca22Sgmcgarry 	int i;
1436e0bca22Sgmcgarry 
1446e0bca22Sgmcgarry 	spoff = autos + (SZINT-1);
1456e0bca22Sgmcgarry 	if (spoff >= AUTOINIT)
1466e0bca22Sgmcgarry 		spoff -= AUTOINIT;
1476e0bca22Sgmcgarry 	spoff /= SZINT;
1486e0bca22Sgmcgarry 	/* return from function code */
1496e0bca22Sgmcgarry 	printf("L%d:\n", retlab);
1506e0bca22Sgmcgarry 	if (gflag || isoptim == 0 || autos != AUTOINIT || regs != MAXRVAR) {
1516e0bca22Sgmcgarry 		for (i = regs; i < MAXRVAR; i++) {
1526e0bca22Sgmcgarry 			int db = ((i+1) < MAXRVAR);
1536e0bca22Sgmcgarry 			printf("	%smove %s,0%o(%s)\n", db ? "d" : "",
1546e0bca22Sgmcgarry 			    rnames[i+1], i+1-regs, rnames[016]);
1556e0bca22Sgmcgarry 			if (db)
1566e0bca22Sgmcgarry 				i++;
1576e0bca22Sgmcgarry 		}
1586e0bca22Sgmcgarry 		printf("	move %s,%s\n", rnames[017], rnames[016]);
1596e0bca22Sgmcgarry 		printf("	pop %s,%s\n", rnames[017], rnames[016]);
1606e0bca22Sgmcgarry 	}
1616e0bca22Sgmcgarry 	printf("	popj %s,\n", rnames[017]);
1626e0bca22Sgmcgarry 
1636e0bca22Sgmcgarry 	/* Prolog code */
1646e0bca22Sgmcgarry 	if (isoptim == 0) {
1656e0bca22Sgmcgarry 		printf("L%d:\n", ftlab1);
1666e0bca22Sgmcgarry 		printf("	push %s,%s\n", rnames[017], rnames[016]);
1676e0bca22Sgmcgarry 		printf("	move %s,%s\n", rnames[016], rnames[017]);
1686e0bca22Sgmcgarry 		for (i = regs; i < MAXRVAR; i++) {
1696e0bca22Sgmcgarry 			int db = ((i+1) < MAXRVAR);
1706e0bca22Sgmcgarry 			printf("	%smovem %s,0%o(%s)\n", db ? "d" : "",
1716e0bca22Sgmcgarry 			    rnames[i+1], i+1-regs, rnames[016]);
1726e0bca22Sgmcgarry 			spoff++;
1736e0bca22Sgmcgarry 			if (db)
1746e0bca22Sgmcgarry 				i++, spoff++;
1756e0bca22Sgmcgarry 		}
1766e0bca22Sgmcgarry 		if (spoff)
1776e0bca22Sgmcgarry 			printf("	addi %s,0%llo\n", rnames[017], spoff);
1786e0bca22Sgmcgarry 		printf("	jrst L%d\n", ftlab2);
1796e0bca22Sgmcgarry 	}
1806e0bca22Sgmcgarry 	printf("	.set " LABFMT ",0%o\n", offlab, MAXRVAR-regs);
1816e0bca22Sgmcgarry 	offarg = isoptim = 0;
1826e0bca22Sgmcgarry }
1836e0bca22Sgmcgarry #endif
1846e0bca22Sgmcgarry 
1856e0bca22Sgmcgarry /*
1866e0bca22Sgmcgarry  * add/sub/...
1876e0bca22Sgmcgarry  *
1886e0bca22Sgmcgarry  * Param given:
1896e0bca22Sgmcgarry  *	R - Register
1906e0bca22Sgmcgarry  *	M - Memory
1916e0bca22Sgmcgarry  *	C - Constant
1926e0bca22Sgmcgarry  */
1936e0bca22Sgmcgarry void
hopcode(int f,int o)1946e0bca22Sgmcgarry hopcode(int f, int o)
1956e0bca22Sgmcgarry {
1966e0bca22Sgmcgarry 	cerror("hopcode: f %d %d", f, o);
1976e0bca22Sgmcgarry }
1986e0bca22Sgmcgarry 
1996e0bca22Sgmcgarry char *
2006e0bca22Sgmcgarry rnames[] = {  /* keyed to register number tokens */
2016e0bca22Sgmcgarry 	"%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7",
2026e0bca22Sgmcgarry 	"%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
2036e0bca22Sgmcgarry 	"%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7",
2046e0bca22Sgmcgarry 	"%10", "%11", "%12", "%13", "%14", "%15",
2056e0bca22Sgmcgarry };
2066e0bca22Sgmcgarry 
2076e0bca22Sgmcgarry int
tlen(p)2086e0bca22Sgmcgarry tlen(p) NODE *p;
2096e0bca22Sgmcgarry {
2106e0bca22Sgmcgarry 	switch(p->n_type) {
2116e0bca22Sgmcgarry 		case CHAR:
2126e0bca22Sgmcgarry 		case UCHAR:
2136e0bca22Sgmcgarry 			return(1);
2146e0bca22Sgmcgarry 
2156e0bca22Sgmcgarry 		case SHORT:
2166e0bca22Sgmcgarry 		case USHORT:
2176e0bca22Sgmcgarry 			return(SZSHORT/SZCHAR);
2186e0bca22Sgmcgarry 
2196e0bca22Sgmcgarry 		case DOUBLE:
2206e0bca22Sgmcgarry 			return(SZDOUBLE/SZCHAR);
2216e0bca22Sgmcgarry 
2226e0bca22Sgmcgarry 		case INT:
2236e0bca22Sgmcgarry 		case UNSIGNED:
2246e0bca22Sgmcgarry 		case LONG:
2256e0bca22Sgmcgarry 		case ULONG:
2266e0bca22Sgmcgarry 			return(SZINT/SZCHAR);
2276e0bca22Sgmcgarry 
2286e0bca22Sgmcgarry 		case LONGLONG:
2296e0bca22Sgmcgarry 		case ULONGLONG:
2306e0bca22Sgmcgarry 			return SZLONGLONG/SZCHAR;
2316e0bca22Sgmcgarry 
2326e0bca22Sgmcgarry 		default:
2336e0bca22Sgmcgarry 			if (!ISPTR(p->n_type))
2346e0bca22Sgmcgarry 				cerror("tlen type %d not pointer");
2356e0bca22Sgmcgarry 			return SZPOINT(0)/SZCHAR;
2366e0bca22Sgmcgarry 		}
2376e0bca22Sgmcgarry }
2386e0bca22Sgmcgarry 
2396e0bca22Sgmcgarry static char *
2406e0bca22Sgmcgarry binskip[] = {
2416e0bca22Sgmcgarry 	"e",	/* jumpe */
2426e0bca22Sgmcgarry 	"n",	/* jumpn */
2436e0bca22Sgmcgarry 	"le",	/* jumple */
2446e0bca22Sgmcgarry 	"l",	/* jumpl */
2456e0bca22Sgmcgarry 	"ge",	/* jumpge */
2466e0bca22Sgmcgarry 	"g",	/* jumpg */
2476e0bca22Sgmcgarry };
2486e0bca22Sgmcgarry 
2496e0bca22Sgmcgarry /*
2506e0bca22Sgmcgarry  * Extract the higher 36 bits from a longlong.
2516e0bca22Sgmcgarry  */
2526e0bca22Sgmcgarry static CONSZ
gethval(CONSZ lval)2536e0bca22Sgmcgarry gethval(CONSZ lval)
2546e0bca22Sgmcgarry {
2556e0bca22Sgmcgarry 	CONSZ hval = (lval >> 35) & 03777777777LL;
2566e0bca22Sgmcgarry 
2576e0bca22Sgmcgarry 	if ((hval & 03000000000LL) == 03000000000LL) {
2586e0bca22Sgmcgarry 		hval |= 0777000000000LL;
2596e0bca22Sgmcgarry 	} else if ((hval & 03000000000LL) == 02000000000LL) {
2606e0bca22Sgmcgarry 		hval &= 01777777777LL;
2616e0bca22Sgmcgarry 		hval |= 0400000000000LL;
2626e0bca22Sgmcgarry 	}
2636e0bca22Sgmcgarry 	return hval;
2646e0bca22Sgmcgarry }
2656e0bca22Sgmcgarry 
2666e0bca22Sgmcgarry /*
2676e0bca22Sgmcgarry  * Do a binary comparision, and jump accordingly.
2686e0bca22Sgmcgarry  */
2696e0bca22Sgmcgarry static void
twocomp(NODE * p)2706e0bca22Sgmcgarry twocomp(NODE *p)
2716e0bca22Sgmcgarry {
2726e0bca22Sgmcgarry 	int o = p->n_op;
2736e0bca22Sgmcgarry 	extern int negrel[];
2746e0bca22Sgmcgarry 	int isscon = 0, iscon = p->n_right->n_op == ICON;
2756e0bca22Sgmcgarry 
2766e0bca22Sgmcgarry 	if (o < EQ || o > GT)
2776e0bca22Sgmcgarry 		cerror("bad binary conditional branch: %s", opst[o]);
2786e0bca22Sgmcgarry 
2796e0bca22Sgmcgarry 	if (iscon && p->n_right->n_name[0] != 0) {
2806e0bca22Sgmcgarry 		printf("	cam%s ", binskip[negrel[o-EQ]-EQ]);
2816e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
2826e0bca22Sgmcgarry 		putchar(',');
2836e0bca22Sgmcgarry 		printf("[ .long ");
2846e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
2856e0bca22Sgmcgarry 		putchar(']');
2866e0bca22Sgmcgarry 		printf("\n	jrst L%d\n", p->n_label);
2876e0bca22Sgmcgarry 		return;
2886e0bca22Sgmcgarry 	}
2896e0bca22Sgmcgarry 	if (iscon)
2906e0bca22Sgmcgarry 		isscon = p->n_right->n_lval >= 0 &&
2916e0bca22Sgmcgarry 		    p->n_right->n_lval < 01000000;
2926e0bca22Sgmcgarry 
2936e0bca22Sgmcgarry 	printf("	ca%c%s ", iscon && isscon ? 'i' : 'm',
2946e0bca22Sgmcgarry 	    binskip[negrel[o-EQ]-EQ]);
2956e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'L'));
2966e0bca22Sgmcgarry 	putchar(',');
2976e0bca22Sgmcgarry 	if (iscon && (isscon == 0)) {
2986e0bca22Sgmcgarry 		printf("[ .long ");
2996e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
3006e0bca22Sgmcgarry 		putchar(']');
3016e0bca22Sgmcgarry 	} else
3026e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
3036e0bca22Sgmcgarry 	printf("\n	jrst L%d\n", p->n_label);
3046e0bca22Sgmcgarry }
3056e0bca22Sgmcgarry 
3066e0bca22Sgmcgarry /*
3076e0bca22Sgmcgarry  * Compare byte/word pointers.
3086e0bca22Sgmcgarry  * XXX - do not work for highest bit set in address
3096e0bca22Sgmcgarry  */
3106e0bca22Sgmcgarry static void
ptrcomp(NODE * p)3116e0bca22Sgmcgarry ptrcomp(NODE *p)
3126e0bca22Sgmcgarry {
3136e0bca22Sgmcgarry 	printf("	rot "); adrput(stdout, getlr(p, 'L')); printf(",6\n");
3146e0bca22Sgmcgarry 	printf("	rot "); adrput(stdout, getlr(p, 'R')); printf(",6\n");
3156e0bca22Sgmcgarry 	twocomp(p);
3166e0bca22Sgmcgarry }
3176e0bca22Sgmcgarry 
3186e0bca22Sgmcgarry /*
3196e0bca22Sgmcgarry  * Do a binary comparision of two long long, and jump accordingly.
3206e0bca22Sgmcgarry  * XXX - can optimize for constants.
3216e0bca22Sgmcgarry  */
3226e0bca22Sgmcgarry static void
twollcomp(NODE * p)3236e0bca22Sgmcgarry twollcomp(NODE *p)
3246e0bca22Sgmcgarry {
3256e0bca22Sgmcgarry 	int o = p->n_op;
3266e0bca22Sgmcgarry 	int iscon = p->n_right->n_op == ICON;
3276e0bca22Sgmcgarry 	int m = 0; /* XXX gcc */
3286e0bca22Sgmcgarry 
3296e0bca22Sgmcgarry 	if (o < EQ || o > GT)
3306e0bca22Sgmcgarry 		cerror("bad long long conditional branch: %s", opst[o]);
3316e0bca22Sgmcgarry 
3326e0bca22Sgmcgarry 	/* Special strategy for equal/not equal */
3336e0bca22Sgmcgarry 	if (o == EQ || o == NE) {
3346e0bca22Sgmcgarry 		if (o == EQ)
335c4627bc7Sgmcgarry 			m = getlab2();
3366e0bca22Sgmcgarry 		printf("	came ");
3376e0bca22Sgmcgarry 		upput(getlr(p, 'L'), SZLONG);
3386e0bca22Sgmcgarry 		putchar(',');
3396e0bca22Sgmcgarry 		if (iscon)
3406e0bca22Sgmcgarry 			printf("[ .long ");
3416e0bca22Sgmcgarry 		upput(getlr(p, 'R'), SZLONG);
3426e0bca22Sgmcgarry 		if (iscon)
3436e0bca22Sgmcgarry 			putchar(']');
3446e0bca22Sgmcgarry 		printf("\n	jrst L%d\n", o == EQ ? m : p->n_label);
3456e0bca22Sgmcgarry 		printf("	cam%c ", o == EQ ? 'n' : 'e');
3466e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
3476e0bca22Sgmcgarry 		putchar(',');
3486e0bca22Sgmcgarry 		if (iscon)
3496e0bca22Sgmcgarry 			printf("[ .long ");
3506e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
3516e0bca22Sgmcgarry 		if (iscon)
3526e0bca22Sgmcgarry 			putchar(']');
3536e0bca22Sgmcgarry 		printf("\n	jrst L%d\n", p->n_label);
3546e0bca22Sgmcgarry 		if (o == EQ)
3556e0bca22Sgmcgarry 			printf("L%d:\n", m);
3566e0bca22Sgmcgarry 		return;
3576e0bca22Sgmcgarry 	}
3586e0bca22Sgmcgarry 	/* First test highword */
3596e0bca22Sgmcgarry 	printf("	cam%ce ", o == GT || o == GE ? 'l' : 'g');
3606e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'L'));
3616e0bca22Sgmcgarry 	putchar(',');
3626e0bca22Sgmcgarry 	if (iscon)
3636e0bca22Sgmcgarry 		printf("[ .long ");
3646e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'R'));
3656e0bca22Sgmcgarry 	if (iscon)
3666e0bca22Sgmcgarry 		putchar(']');
3676e0bca22Sgmcgarry 	printf("\n	jrst L%d\n", p->n_label);
3686e0bca22Sgmcgarry 
3696e0bca22Sgmcgarry 	/* Test equality */
3706e0bca22Sgmcgarry 	printf("	came ");
3716e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'L'));
3726e0bca22Sgmcgarry 	putchar(',');
3736e0bca22Sgmcgarry 	if (iscon)
3746e0bca22Sgmcgarry 		printf("[ .long ");
3756e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'R'));
3766e0bca22Sgmcgarry 	if (iscon)
3776e0bca22Sgmcgarry 		putchar(']');
378c4627bc7Sgmcgarry 	printf("\n	jrst L%d\n", m = getlab2());
3796e0bca22Sgmcgarry 
3806e0bca22Sgmcgarry 	/* Test lowword. Only works with pdp10 format for longlongs */
3816e0bca22Sgmcgarry 	printf("	cam%c%c ", o == GT || o == GE ? 'l' : 'g',
3826e0bca22Sgmcgarry 	    o == LT || o == GT ? 'e' : ' ');
3836e0bca22Sgmcgarry 	upput(getlr(p, 'L'), SZLONG);
3846e0bca22Sgmcgarry 	putchar(',');
3856e0bca22Sgmcgarry 	if (iscon)
3866e0bca22Sgmcgarry 		printf("[ .long ");
3876e0bca22Sgmcgarry 	upput(getlr(p, 'R'), SZLONG);
3886e0bca22Sgmcgarry 	if (iscon)
3896e0bca22Sgmcgarry 		putchar(']');
3906e0bca22Sgmcgarry 	printf("\n	jrst L%d\n", p->n_label);
3916e0bca22Sgmcgarry 	printf("L%d:\n", m);
3926e0bca22Sgmcgarry }
3936e0bca22Sgmcgarry 
3946e0bca22Sgmcgarry /*
3956e0bca22Sgmcgarry  * Print the correct instruction for constants.
3966e0bca22Sgmcgarry  */
3976e0bca22Sgmcgarry static void
constput(NODE * p)3986e0bca22Sgmcgarry constput(NODE *p)
3996e0bca22Sgmcgarry {
4006e0bca22Sgmcgarry 	CONSZ val = p->n_right->n_lval;
4016e0bca22Sgmcgarry 	int reg = p->n_left->n_rval;
4026e0bca22Sgmcgarry 
4036e0bca22Sgmcgarry 	/* Only numeric constant */
4046e0bca22Sgmcgarry 	if (p->n_right->n_name[0] == '\0') {
4056e0bca22Sgmcgarry 		if (val == 0) {
4066e0bca22Sgmcgarry 			printf("movei %s,0", rnames[reg]);
4076e0bca22Sgmcgarry 		} else if ((val & 0777777000000LL) == 0) {
4086e0bca22Sgmcgarry 			printf("movei %s,0%llo", rnames[reg], val);
4096e0bca22Sgmcgarry 		} else if ((val & 0777777) == 0) {
4106e0bca22Sgmcgarry 			printf("hrlzi %s,0%llo", rnames[reg], val >> 18);
4116e0bca22Sgmcgarry 		} else {
4126e0bca22Sgmcgarry 			printf("move %s,[ .long 0%llo]", rnames[reg],
4136e0bca22Sgmcgarry 			    szty(p->n_right->n_type) > 1 ? val :
4146e0bca22Sgmcgarry 			    val & 0777777777777LL);
4156e0bca22Sgmcgarry 		}
4166e0bca22Sgmcgarry 		/* Can have more tests here, hrloi etc */
4176e0bca22Sgmcgarry 		return;
4186e0bca22Sgmcgarry 	} else {
4196e0bca22Sgmcgarry 		printf("xmovei %s,%s", rnames[reg], p->n_right->n_name);
4206e0bca22Sgmcgarry 		if (val)
4216e0bca22Sgmcgarry 			printf("+" CONFMT, val);
4226e0bca22Sgmcgarry 	}
4236e0bca22Sgmcgarry }
4246e0bca22Sgmcgarry 
4256e0bca22Sgmcgarry /*
4266e0bca22Sgmcgarry  * Return true if the constant can be bundled in an instruction (immediate).
4276e0bca22Sgmcgarry  */
4286e0bca22Sgmcgarry static int
oneinstr(NODE * p)4296e0bca22Sgmcgarry oneinstr(NODE *p)
4306e0bca22Sgmcgarry {
4316e0bca22Sgmcgarry 	if (p->n_name[0] != '\0')
4326e0bca22Sgmcgarry 		return 0;
4336e0bca22Sgmcgarry 	if ((p->n_lval & 0777777000000ULL) != 0)
4346e0bca22Sgmcgarry 		return 0;
4356e0bca22Sgmcgarry 	return 1;
4366e0bca22Sgmcgarry }
4376e0bca22Sgmcgarry 
4386e0bca22Sgmcgarry /*
4396e0bca22Sgmcgarry  * Emit a halfword or byte instruction, from OREG to REG.
4406e0bca22Sgmcgarry  * Sign extension must also be done here.
4416e0bca22Sgmcgarry  */
4426e0bca22Sgmcgarry static void
emitshort(NODE * p)4436e0bca22Sgmcgarry emitshort(NODE *p)
4446e0bca22Sgmcgarry {
4456e0bca22Sgmcgarry 	CONSZ off = p->n_lval;
4466e0bca22Sgmcgarry 	TWORD type = p->n_type;
4476e0bca22Sgmcgarry 	int reg = p->n_rval;
4486e0bca22Sgmcgarry 	int issigned = !ISUNSIGNED(type);
4496e0bca22Sgmcgarry 	int ischar = type == CHAR || type == UCHAR;
4506e0bca22Sgmcgarry 	int reg1 = getlr(p, '1')->n_rval;
4516e0bca22Sgmcgarry 
4526e0bca22Sgmcgarry 	if (off < 0) { /* argument, use move instead */
4536e0bca22Sgmcgarry 		printf("	move ");
4546e0bca22Sgmcgarry 	} else if (off == 0 && p->n_name[0] == 0) {
4556e0bca22Sgmcgarry 		printf("	ldb %s,%s\n", rnames[reg1], rnames[reg]);
4566e0bca22Sgmcgarry 		/* XXX must sign extend here even if not necessary */
4576e0bca22Sgmcgarry 		switch (type) {
4586e0bca22Sgmcgarry 		case CHAR:
4596e0bca22Sgmcgarry 			printf("	lsh %s,033\n", rnames[reg1]);
4606e0bca22Sgmcgarry 			printf("	ash %s,-033\n", rnames[reg1]);
4616e0bca22Sgmcgarry 			break;
4626e0bca22Sgmcgarry 		case SHORT:
4636e0bca22Sgmcgarry 			printf("	hrre %s,%s\n",
4646e0bca22Sgmcgarry 			    rnames[reg1], rnames[reg1]);
4656e0bca22Sgmcgarry 			break;
4666e0bca22Sgmcgarry 		}
4676e0bca22Sgmcgarry 		return;
4686e0bca22Sgmcgarry 	} else if (ischar) {
4696e0bca22Sgmcgarry 		if (off >= 0700000000000LL && p->n_name[0] != '\0') {
4706e0bca22Sgmcgarry 			cerror("emitsh");
4716e0bca22Sgmcgarry 			/* reg contains index integer */
4726e0bca22Sgmcgarry //			if (!istreg(reg))
4736e0bca22Sgmcgarry //				cerror("emitshort !istreg");
4746e0bca22Sgmcgarry 			printf("	adjbp %s,[ .long 0%llo+%s ]\n",
4756e0bca22Sgmcgarry 			    rnames[reg], off, p->n_name);
4766e0bca22Sgmcgarry 			printf("	ldb ");
4776e0bca22Sgmcgarry 			adrput(stdout, getlr(p, '1'));
4786e0bca22Sgmcgarry 			printf(",%s\n", rnames[reg]);
4796e0bca22Sgmcgarry 			goto signe;
4806e0bca22Sgmcgarry 		}
4816e0bca22Sgmcgarry 		printf("	ldb ");
4826e0bca22Sgmcgarry 		adrput(stdout, getlr(p, '1'));
4836e0bca22Sgmcgarry 		if (off)
4846e0bca22Sgmcgarry 			printf(",[ .long 0%02o11%02o%06o ]\n",
4856e0bca22Sgmcgarry 			    (int)(27-(9*(off&3))), reg, (int)off/4);
4866e0bca22Sgmcgarry 		else
4876e0bca22Sgmcgarry 			printf(",%s\n", rnames[reg]);
4886e0bca22Sgmcgarry signe:		if (issigned) {
4896e0bca22Sgmcgarry 			printf("	lsh ");
4906e0bca22Sgmcgarry 			adrput(stdout, getlr(p, '1'));
4916e0bca22Sgmcgarry 			printf(",033\n	ash ");
4926e0bca22Sgmcgarry 			adrput(stdout, getlr(p, '1'));
4936e0bca22Sgmcgarry 			printf(",-033\n");
4946e0bca22Sgmcgarry 		}
4956e0bca22Sgmcgarry 		return;
4966e0bca22Sgmcgarry 	} else {
4976e0bca22Sgmcgarry 		printf("	h%cr%c ", off & 1 ? 'r' : 'l',
4986e0bca22Sgmcgarry 		    issigned ? 'e' : 'z');
4996e0bca22Sgmcgarry 	}
5006e0bca22Sgmcgarry 	p->n_lval /= (ischar ? 4 : 2);
5016e0bca22Sgmcgarry 	adrput(stdout, getlr(p, '1'));
5026e0bca22Sgmcgarry 	putchar(',');
5036e0bca22Sgmcgarry 	adrput(stdout, getlr(p, 'L'));
5046e0bca22Sgmcgarry 	putchar('\n');
5056e0bca22Sgmcgarry }
5066e0bca22Sgmcgarry 
5076e0bca22Sgmcgarry /*
5086e0bca22Sgmcgarry  * Store a short from a register. Destination is a OREG.
5096e0bca22Sgmcgarry  */
5106e0bca22Sgmcgarry static void
storeshort(NODE * p)5116e0bca22Sgmcgarry storeshort(NODE *p)
5126e0bca22Sgmcgarry {
5136e0bca22Sgmcgarry 	NODE *l = p->n_left;
5146e0bca22Sgmcgarry 	CONSZ off = l->n_lval;
5156e0bca22Sgmcgarry 	int reg = l->n_rval;
5166e0bca22Sgmcgarry 	int ischar = BTYPE(p->n_type) == CHAR || BTYPE(p->n_type) == UCHAR;
5176e0bca22Sgmcgarry 
5186e0bca22Sgmcgarry 	if (l->n_op == NAME) {
5196e0bca22Sgmcgarry 		if (ischar) {
5206e0bca22Sgmcgarry 			printf("	dpb ");
5216e0bca22Sgmcgarry 			adrput(stdout, getlr(p, 'R'));
5226e0bca22Sgmcgarry 			printf(",[ .long 0%02o%010o+%s ]\n",
5236e0bca22Sgmcgarry 			    070+((int)off&3), (int)(off/4), l->n_name);
5246e0bca22Sgmcgarry 			return;
5256e0bca22Sgmcgarry 		}
5266e0bca22Sgmcgarry 		printf("	hr%cm ", off & 1 ? 'r' : 'l');
5276e0bca22Sgmcgarry 		l->n_lval /= 2;
5286e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
5296e0bca22Sgmcgarry 		putchar(',');
5306e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
5316e0bca22Sgmcgarry 		putchar('\n');
5326e0bca22Sgmcgarry 		return;
5336e0bca22Sgmcgarry 	}
5346e0bca22Sgmcgarry 
5356e0bca22Sgmcgarry 	if (off || reg == FPREG) { /* Can emit halfword instructions */
5366e0bca22Sgmcgarry 		if (off < 0) { /* argument, use move instead */
5376e0bca22Sgmcgarry 			printf("	movem ");
5386e0bca22Sgmcgarry 		} else if (ischar) {
5396e0bca22Sgmcgarry 			printf("	dpb ");
5406e0bca22Sgmcgarry 			adrput(stdout, getlr(p, '1'));
5416e0bca22Sgmcgarry 			printf(",[ .long 0%02o11%02o%06o ]\n",
5426e0bca22Sgmcgarry 			    (int)(27-(9*(off&3))), reg, (int)off/4);
5436e0bca22Sgmcgarry 			return;
5446e0bca22Sgmcgarry 		} else {
5456e0bca22Sgmcgarry 			printf("	hr%cm ", off & 1 ? 'r' : 'l');
5466e0bca22Sgmcgarry 		}
5476e0bca22Sgmcgarry 		l->n_lval /= 2;
5486e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
5496e0bca22Sgmcgarry 		putchar(',');
5506e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
5516e0bca22Sgmcgarry 	} else {
5526e0bca22Sgmcgarry 		printf("	dpb ");
5536e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'R'));
5546e0bca22Sgmcgarry 		putchar(',');
5556e0bca22Sgmcgarry 		l = getlr(p, 'L');
5566e0bca22Sgmcgarry 		l->n_op = REG;
5576e0bca22Sgmcgarry 		adrput(stdout, l);
5586e0bca22Sgmcgarry 		l->n_op = OREG;
5596e0bca22Sgmcgarry 	}
5606e0bca22Sgmcgarry 	putchar('\n');
5616e0bca22Sgmcgarry }
5626e0bca22Sgmcgarry 
5636e0bca22Sgmcgarry /*
5646e0bca22Sgmcgarry  * Multiply a register with a constant.
5656e0bca22Sgmcgarry  */
5666e0bca22Sgmcgarry static void
imuli(NODE * p)5676e0bca22Sgmcgarry imuli(NODE *p)
5686e0bca22Sgmcgarry {
5696e0bca22Sgmcgarry 	NODE *r = p->n_right;
5706e0bca22Sgmcgarry 
5716e0bca22Sgmcgarry 	if (r->n_lval >= 0 && r->n_lval <= 0777777) {
5726e0bca22Sgmcgarry 		printf("	imuli ");
5736e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
5746e0bca22Sgmcgarry 		printf(",0%llo\n", r->n_lval);
5756e0bca22Sgmcgarry 	} else {
5766e0bca22Sgmcgarry 		printf("	imul ");
5776e0bca22Sgmcgarry 		adrput(stdout, getlr(p, 'L'));
5786e0bca22Sgmcgarry 		printf(",[ .long 0%llo ]\n", r->n_lval & 0777777777777LL);
5796e0bca22Sgmcgarry 	}
5806e0bca22Sgmcgarry }
5816e0bca22Sgmcgarry 
5826e0bca22Sgmcgarry /*
5836e0bca22Sgmcgarry  * Divide a register with a constant.
5846e0bca22Sgmcgarry  */
5856e0bca22Sgmcgarry static void
idivi(NODE * p)5866e0bca22Sgmcgarry idivi(NODE *p)
5876e0bca22Sgmcgarry {
5886e0bca22Sgmcgarry 	NODE *r = p->n_right;
5896e0bca22Sgmcgarry 
5906e0bca22Sgmcgarry 	if (r->n_lval >= 0 && r->n_lval <= 0777777) {
5916e0bca22Sgmcgarry 		printf("	idivi ");
5926e0bca22Sgmcgarry 		adrput(stdout, getlr(p, '1'));
5936e0bca22Sgmcgarry 		printf(",0%llo\n", r->n_lval);
5946e0bca22Sgmcgarry 	} else {
5956e0bca22Sgmcgarry 		printf("	idiv ");
5966e0bca22Sgmcgarry 		adrput(stdout, getlr(p, '1'));
5976e0bca22Sgmcgarry 		printf(",[ .long 0%llo ]\n", r->n_lval & 0777777777777LL);
5986e0bca22Sgmcgarry 	}
5996e0bca22Sgmcgarry }
6006e0bca22Sgmcgarry 
6016e0bca22Sgmcgarry /*
6026e0bca22Sgmcgarry  * move a constant into a register.
6036e0bca22Sgmcgarry  */
6046e0bca22Sgmcgarry static void
xmovei(NODE * p)6056e0bca22Sgmcgarry xmovei(NODE *p)
6066e0bca22Sgmcgarry {
6076e0bca22Sgmcgarry 	/*
6086e0bca22Sgmcgarry 	 * Trick: If this is an unnamed constant, just move it directly,
6096e0bca22Sgmcgarry 	 * otherwise use xmovei to get section number.
6106e0bca22Sgmcgarry 	 */
6116e0bca22Sgmcgarry 	if (p->n_name[0] == '\0' || p->n_lval > 0777777) {
6126e0bca22Sgmcgarry 		printf("	");
6136e0bca22Sgmcgarry 		zzzcode(p, 'D');
6146e0bca22Sgmcgarry 		putchar(' ');
6156e0bca22Sgmcgarry 		adrput(stdout, getlr(p, '1'));
6166e0bca22Sgmcgarry 		putchar(',');
6176e0bca22Sgmcgarry 		zzzcode(p, 'E');
6186e0bca22Sgmcgarry 	} else {
6196e0bca22Sgmcgarry 		printf("	xmovei ");
6206e0bca22Sgmcgarry 		adrput(stdout, getlr(p, '1'));
6216e0bca22Sgmcgarry 		printf(",%s", p->n_name);
6226e0bca22Sgmcgarry 		if (p->n_lval != 0)
6236e0bca22Sgmcgarry 			printf("+0%llo", p->n_lval);
6246e0bca22Sgmcgarry 	}
6256e0bca22Sgmcgarry 	putchar('\n');
6266e0bca22Sgmcgarry }
6276e0bca22Sgmcgarry 
6286e0bca22Sgmcgarry static void
printcon(NODE * p)6296e0bca22Sgmcgarry printcon(NODE *p)
6306e0bca22Sgmcgarry {
6316e0bca22Sgmcgarry 	CONSZ cz;
6326e0bca22Sgmcgarry 
6336e0bca22Sgmcgarry 	p = p->n_left;
6346e0bca22Sgmcgarry 	if (p->n_lval >= 0700000000000LL) {
6356e0bca22Sgmcgarry 		/* converted to pointer in clocal() */
636370d6aa0Splunky 		conput(stdout, p);
6376e0bca22Sgmcgarry 		return;
6386e0bca22Sgmcgarry 	}
6396e0bca22Sgmcgarry 	if (p->n_lval == 0 && p->n_name[0] == '\0') {
6406e0bca22Sgmcgarry 		putchar('0');
6416e0bca22Sgmcgarry 		return;
6426e0bca22Sgmcgarry 	}
6436e0bca22Sgmcgarry 	if (BTYPE(p->n_type) == CHAR || BTYPE(p->n_type) == UCHAR)
6446e0bca22Sgmcgarry 		cz = (p->n_lval/4) | ((p->n_lval & 3) << 30);
6456e0bca22Sgmcgarry 	else
6466e0bca22Sgmcgarry 		cz = (p->n_lval/2) | (((p->n_lval & 1) + 5) << 30);
6476e0bca22Sgmcgarry 	cz |= 0700000000000LL;
6486e0bca22Sgmcgarry 	printf("0%llo", cz);
6496e0bca22Sgmcgarry 	if (p->n_name[0] != '\0')
6506e0bca22Sgmcgarry 		printf("+%s", p->n_name);
6516e0bca22Sgmcgarry }
6526e0bca22Sgmcgarry 
6536e0bca22Sgmcgarry static void
putcond(NODE * p)6546e0bca22Sgmcgarry putcond(NODE *p)
6556e0bca22Sgmcgarry {
6566e0bca22Sgmcgarry 	char *c = 0; /* XXX gcc */
6576e0bca22Sgmcgarry 
6586e0bca22Sgmcgarry 	switch (p->n_op) {
6596e0bca22Sgmcgarry 	case EQ: c = "e"; break;
6606e0bca22Sgmcgarry 	case NE: c = "n"; break;
6616e0bca22Sgmcgarry 	case LE: c = "le"; break;
6626e0bca22Sgmcgarry 	case LT: c = "l"; break;
6636e0bca22Sgmcgarry 	case GT: c = "g"; break;
6646e0bca22Sgmcgarry 	case GE: c = "ge"; break;
6656e0bca22Sgmcgarry 	default:
6666e0bca22Sgmcgarry 		cerror("putcond");
6676e0bca22Sgmcgarry 	}
6686e0bca22Sgmcgarry 	printf("%s", c);
6696e0bca22Sgmcgarry }
6706e0bca22Sgmcgarry 
6716e0bca22Sgmcgarry void
zzzcode(NODE * p,int c)6726e0bca22Sgmcgarry zzzcode(NODE *p, int c)
6736e0bca22Sgmcgarry {
6746e0bca22Sgmcgarry 	NODE *l;
6756e0bca22Sgmcgarry 	CONSZ hval;
6766e0bca22Sgmcgarry 
6776e0bca22Sgmcgarry 	switch (c) {
6786e0bca22Sgmcgarry 	case 'A': /* ildb right arg */
6796e0bca22Sgmcgarry 		adrput(stdout, p->n_left->n_left);
6806e0bca22Sgmcgarry 		break;
6816e0bca22Sgmcgarry 
6826e0bca22Sgmcgarry 	case 'B': /* remove from stack after subroutine call */
6836e0bca22Sgmcgarry 		if (p->n_qual)
6846e0bca22Sgmcgarry 			printf("	subi %%17,0%o\n", p->n_qual);
6856e0bca22Sgmcgarry 		break;
6866e0bca22Sgmcgarry 
6876e0bca22Sgmcgarry 	case 'C':
6886e0bca22Sgmcgarry 		constput(p);
6896e0bca22Sgmcgarry 		break;
6906e0bca22Sgmcgarry 
6916e0bca22Sgmcgarry 	case 'D': /* Find out which type of const load insn to use */
6926e0bca22Sgmcgarry 		if (p->n_op != ICON)
6936e0bca22Sgmcgarry 			cerror("zzzcode not ICON");
6946e0bca22Sgmcgarry 		if (p->n_name[0] == '\0') {
6956e0bca22Sgmcgarry 			if ((p->n_lval <= 0777777) && (p->n_lval > 0))
6966e0bca22Sgmcgarry 				printf("movei");
6976e0bca22Sgmcgarry 			else if ((p->n_lval & 0777777) == 0)
6986e0bca22Sgmcgarry 				printf("hrlzi");
6996e0bca22Sgmcgarry 			else
7006e0bca22Sgmcgarry 				printf("move");
7016e0bca22Sgmcgarry 		} else
7026e0bca22Sgmcgarry 			printf("move");
7036e0bca22Sgmcgarry 		break;
7046e0bca22Sgmcgarry 
7056e0bca22Sgmcgarry 	case 'E': /* Print correct constant expression */
7066e0bca22Sgmcgarry 		if (p->n_name[0] == '\0') {
7076e0bca22Sgmcgarry 			if ((p->n_lval <= 0777777) && (p->n_lval > 0)){
7086e0bca22Sgmcgarry 				printf("0%llo", p->n_lval);
7096e0bca22Sgmcgarry 			} else if ((p->n_lval & 0777777) == 0) {
7106e0bca22Sgmcgarry 				printf("0%llo", p->n_lval >> 18);
7116e0bca22Sgmcgarry 			} else {
7126e0bca22Sgmcgarry 				if (p->n_lval < 0)
7136e0bca22Sgmcgarry 					printf("[ .long -0%llo]", -p->n_lval);
7146e0bca22Sgmcgarry 				else
7156e0bca22Sgmcgarry 					printf("[ .long 0%llo]", p->n_lval);
7166e0bca22Sgmcgarry 			}
7176e0bca22Sgmcgarry 		} else {
7186e0bca22Sgmcgarry 			if (p->n_lval == 0)
7196e0bca22Sgmcgarry 				printf("[ .long %s]", p->n_name);
7206e0bca22Sgmcgarry 			else
7216e0bca22Sgmcgarry 				printf("[ .long %s+0%llo]",
7226e0bca22Sgmcgarry 				    p->n_name, p->n_lval);
7236e0bca22Sgmcgarry 		}
7246e0bca22Sgmcgarry 		break;
7256e0bca22Sgmcgarry 
7266e0bca22Sgmcgarry 	case 'G': /* structure argument */
727*6935091cSplunky 		printf("	addl %%17,0%o\n",
728*6935091cSplunky 		    attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0)/(SZINT/SZCHAR));
7296e0bca22Sgmcgarry 		printf("	foo...\n");
7306e0bca22Sgmcgarry 		break;
7316e0bca22Sgmcgarry 
7326e0bca22Sgmcgarry 	case 'P':
7336e0bca22Sgmcgarry 		p = getlr(p, 'R');
7346e0bca22Sgmcgarry 		/* FALLTHROUGH */
7356e0bca22Sgmcgarry 	case 'O':
7366e0bca22Sgmcgarry 		/*
7376e0bca22Sgmcgarry 		 * Print long long expression.
7386e0bca22Sgmcgarry 		 */
7396e0bca22Sgmcgarry 		hval = gethval(p->n_lval);
7406e0bca22Sgmcgarry 		printf("[ .long 0%llo,0%llo", hval,
7416e0bca22Sgmcgarry 		    (p->n_lval & 0377777777777LL) | (hval & 0400000000000LL));
7426e0bca22Sgmcgarry 		if (p->n_name[0] != '\0')
7436e0bca22Sgmcgarry 			printf("+%s", p->n_name);
7446e0bca22Sgmcgarry 		printf(" ]");
7456e0bca22Sgmcgarry 		break;
7466e0bca22Sgmcgarry 
7476e0bca22Sgmcgarry 	case 'F': /* Print an "opsimp" instruction based on its const type */
7486e0bca22Sgmcgarry 		hopcode(oneinstr(p->n_right) ? 'C' : 'R', p->n_op);
7496e0bca22Sgmcgarry 		break;
7506e0bca22Sgmcgarry 
7516e0bca22Sgmcgarry 	case 'H': /* Print a small constant */
7526e0bca22Sgmcgarry 		p = p->n_right;
7536e0bca22Sgmcgarry 		printf("0%llo", p->n_lval & 0777777);
7546e0bca22Sgmcgarry 		break;
7556e0bca22Sgmcgarry 
7566e0bca22Sgmcgarry 	case 'Q': /* two-param long long comparisions */
7576e0bca22Sgmcgarry 		twollcomp(p);
7586e0bca22Sgmcgarry 		break;
7596e0bca22Sgmcgarry 
7606e0bca22Sgmcgarry 	case 'R': /* two-param conditionals */
7616e0bca22Sgmcgarry 		twocomp(p);
7626e0bca22Sgmcgarry 		break;
7636e0bca22Sgmcgarry 
7646e0bca22Sgmcgarry 	case 'U':
7656e0bca22Sgmcgarry 		emitshort(p);
7666e0bca22Sgmcgarry 		break;
7676e0bca22Sgmcgarry 
7686e0bca22Sgmcgarry 	case 'V':
7696e0bca22Sgmcgarry 		storeshort(p);
7706e0bca22Sgmcgarry 		break;
7716e0bca22Sgmcgarry 
7726e0bca22Sgmcgarry 	case 'Z':
7736e0bca22Sgmcgarry 		ptrcomp(p);
7746e0bca22Sgmcgarry 		break;
7756e0bca22Sgmcgarry 
7766e0bca22Sgmcgarry 	case 'a':
7776e0bca22Sgmcgarry 		imuli(p);
7786e0bca22Sgmcgarry 		break;
7796e0bca22Sgmcgarry 
7806e0bca22Sgmcgarry 	case 'b':
7816e0bca22Sgmcgarry 		idivi(p);
7826e0bca22Sgmcgarry 		break;
7836e0bca22Sgmcgarry 
7846e0bca22Sgmcgarry 	case 'c':
7856e0bca22Sgmcgarry 		xmovei(p);
7866e0bca22Sgmcgarry 		break;
7876e0bca22Sgmcgarry 
7886e0bca22Sgmcgarry 	case 'd':
7896e0bca22Sgmcgarry 		printcon(p);
7906e0bca22Sgmcgarry 		break;
7916e0bca22Sgmcgarry 
7926e0bca22Sgmcgarry 	case 'e':
7936e0bca22Sgmcgarry 		putcond(p);
7946e0bca22Sgmcgarry 		break;
7956e0bca22Sgmcgarry 
7966e0bca22Sgmcgarry 	case 'g':
7976e0bca22Sgmcgarry 		if (p->n_right->n_op != OREG || p->n_right->n_lval != 0)
7986e0bca22Sgmcgarry 			comperr("bad Zg oreg");
7996e0bca22Sgmcgarry 		printf("%s", rnames[p->n_right->n_rval]);
8006e0bca22Sgmcgarry 		break;
8016e0bca22Sgmcgarry 
8026e0bca22Sgmcgarry #if 0
8036e0bca22Sgmcgarry 	case '1': /* double upput */
8046e0bca22Sgmcgarry 		p = getlr(p, '1');
8056e0bca22Sgmcgarry 		p->n_rval += 2;
8066e0bca22Sgmcgarry 		adrput(stdout, p);
8076e0bca22Sgmcgarry 		p->n_rval -= 2;
8086e0bca22Sgmcgarry 		break;
8096e0bca22Sgmcgarry #endif
8106e0bca22Sgmcgarry 
8116e0bca22Sgmcgarry 	case 'i': /* Write instruction for short load from name */
8126e0bca22Sgmcgarry 		l = getlr(p, 'L');
8136e0bca22Sgmcgarry 		printf("	h%cr%c %s,%s+" CONFMT "\n",
8146e0bca22Sgmcgarry 		    l->n_lval & 1 ? 'r' : 'l',
8156e0bca22Sgmcgarry 		    ISUNSIGNED(p->n_type) ? 'z' : 'e',
8166e0bca22Sgmcgarry 		    rnames[getlr(p, '1')->n_rval],
8176e0bca22Sgmcgarry 		    l->n_name, l->n_lval >> 1);
8186e0bca22Sgmcgarry 		break;
8196e0bca22Sgmcgarry 
8206e0bca22Sgmcgarry 	default:
8216e0bca22Sgmcgarry 		cerror("zzzcode %c", c);
8226e0bca22Sgmcgarry 	}
8236e0bca22Sgmcgarry }
8246e0bca22Sgmcgarry 
8256e0bca22Sgmcgarry /* set up temporary registers */
8266e0bca22Sgmcgarry void
setregs(void)827370d6aa0Splunky setregs(void)
8286e0bca22Sgmcgarry {
8296e0bca22Sgmcgarry 	fregs = 7;	/* 7 free regs on PDP10 (1-7) */
8306e0bca22Sgmcgarry }
8316e0bca22Sgmcgarry 
8326e0bca22Sgmcgarry /*ARGSUSED*/
8336e0bca22Sgmcgarry int
rewfld(NODE * p)8346e0bca22Sgmcgarry rewfld(NODE *p)
8356e0bca22Sgmcgarry {
8366e0bca22Sgmcgarry 	return(1);
8376e0bca22Sgmcgarry }
8386e0bca22Sgmcgarry 
8396e0bca22Sgmcgarry int
fldexpand(NODE * p,int cookie,char ** cp)8406e0bca22Sgmcgarry fldexpand(NODE *p, int cookie, char **cp)
8416e0bca22Sgmcgarry {
8426e0bca22Sgmcgarry 	return 0;
8436e0bca22Sgmcgarry }
8446e0bca22Sgmcgarry 
8456e0bca22Sgmcgarry int
flshape(NODE * p)8466e0bca22Sgmcgarry flshape(NODE *p)
8476e0bca22Sgmcgarry {
8486e0bca22Sgmcgarry 	register int o = p->n_op;
8496e0bca22Sgmcgarry 
8506e0bca22Sgmcgarry 	return (o == REG || o == NAME || o == ICON ||
8516e0bca22Sgmcgarry 		(o == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)));
8526e0bca22Sgmcgarry }
8536e0bca22Sgmcgarry 
8546e0bca22Sgmcgarry /* INTEMP shapes must not contain any temporary registers */
8556e0bca22Sgmcgarry int
shtemp(NODE * p)8566e0bca22Sgmcgarry shtemp(NODE *p)
8576e0bca22Sgmcgarry {
8586e0bca22Sgmcgarry 	return(0);
8596e0bca22Sgmcgarry }
8606e0bca22Sgmcgarry 
8616e0bca22Sgmcgarry int
shumul(NODE * p,int order)862c4627bc7Sgmcgarry shumul(NODE *p, int order)
8636e0bca22Sgmcgarry {
8646e0bca22Sgmcgarry 	register int o;
8656e0bca22Sgmcgarry 
8666e0bca22Sgmcgarry 	if (x2debug) {
8676e0bca22Sgmcgarry 		int val;
8686e0bca22Sgmcgarry 		printf("shumul(%p)\n", p);
8696e0bca22Sgmcgarry 		eprint(p, 0, &val, &val);
8706e0bca22Sgmcgarry 	}
8716e0bca22Sgmcgarry 
8726e0bca22Sgmcgarry 	o = p->n_op;
8736e0bca22Sgmcgarry #if 0
8746e0bca22Sgmcgarry 	if (o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON)
8756e0bca22Sgmcgarry 		return(STARNM);
8766e0bca22Sgmcgarry #endif
8776e0bca22Sgmcgarry 
8786e0bca22Sgmcgarry #if 0
8796e0bca22Sgmcgarry 	if ((o == INCR) &&
8806e0bca22Sgmcgarry 	    (p->n_left->n_op == REG && p->n_right->n_op == ICON) &&
8816e0bca22Sgmcgarry 	    p->n_right->n_name[0] == '\0') {
8826e0bca22Sgmcgarry 		switch (p->n_type) {
8836e0bca22Sgmcgarry 			case CHAR|PTR:
8846e0bca22Sgmcgarry 			case UCHAR|PTR:
8856e0bca22Sgmcgarry 				o = 1;
8866e0bca22Sgmcgarry 				break;
8876e0bca22Sgmcgarry 
8886e0bca22Sgmcgarry 			case SHORT|PTR:
8896e0bca22Sgmcgarry 			case USHORT|PTR:
8906e0bca22Sgmcgarry 				o = 2;
8916e0bca22Sgmcgarry 				break;
8926e0bca22Sgmcgarry 
8936e0bca22Sgmcgarry 			case INT|PTR:
8946e0bca22Sgmcgarry 			case UNSIGNED|PTR:
8956e0bca22Sgmcgarry 			case LONG|PTR:
8966e0bca22Sgmcgarry 			case ULONG|PTR:
8976e0bca22Sgmcgarry 			case FLOAT|PTR:
8986e0bca22Sgmcgarry 				o = 4;
8996e0bca22Sgmcgarry 				break;
9006e0bca22Sgmcgarry 
9016e0bca22Sgmcgarry 			case DOUBLE|PTR:
9026e0bca22Sgmcgarry 			case LONGLONG|PTR:
9036e0bca22Sgmcgarry 			case ULONGLONG|PTR:
9046e0bca22Sgmcgarry 				o = 8;
9056e0bca22Sgmcgarry 				break;
9066e0bca22Sgmcgarry 
9076e0bca22Sgmcgarry 			default:
9086e0bca22Sgmcgarry 				if (ISPTR(p->n_type) &&
9096e0bca22Sgmcgarry 				     ISPTR(DECREF(p->n_type))) {
9106e0bca22Sgmcgarry 					o = 4;
9116e0bca22Sgmcgarry 					break;
9126e0bca22Sgmcgarry 				} else
9136e0bca22Sgmcgarry 					return(0);
9146e0bca22Sgmcgarry 		}
9156e0bca22Sgmcgarry 		return( 0);
9166e0bca22Sgmcgarry 	}
9176e0bca22Sgmcgarry #endif
918c4627bc7Sgmcgarry 	return( SRNOPE );
9196e0bca22Sgmcgarry }
9206e0bca22Sgmcgarry 
9216e0bca22Sgmcgarry void
adrcon(CONSZ val)9226e0bca22Sgmcgarry adrcon(CONSZ val)
9236e0bca22Sgmcgarry {
9246e0bca22Sgmcgarry 	cerror("adrcon: val %llo\n", val);
9256e0bca22Sgmcgarry }
9266e0bca22Sgmcgarry 
9276e0bca22Sgmcgarry void
conput(FILE * fp,NODE * p)9286e0bca22Sgmcgarry conput(FILE *fp, NODE *p)
9296e0bca22Sgmcgarry {
9306e0bca22Sgmcgarry 	switch (p->n_op) {
9316e0bca22Sgmcgarry 	case ICON:
9326e0bca22Sgmcgarry 		if (p->n_lval != 0) {
933370d6aa0Splunky 			acon(fp, p);
9346e0bca22Sgmcgarry 			if (p->n_name[0] != '\0')
935370d6aa0Splunky 				fputc('+', fp);
9366e0bca22Sgmcgarry 		}
9376e0bca22Sgmcgarry 		if (p->n_name[0] != '\0')
938370d6aa0Splunky 			fprintf(fp, "%s", p->n_name);
9396e0bca22Sgmcgarry 		if (p->n_name[0] == '\0' && p->n_lval == 0)
940370d6aa0Splunky 			fputc('0', fp);
9416e0bca22Sgmcgarry 		return;
9426e0bca22Sgmcgarry 
9436e0bca22Sgmcgarry 	case REG:
944370d6aa0Splunky 		fprintf(fp, "%s", rnames[p->n_rval]);
9456e0bca22Sgmcgarry 		return;
9466e0bca22Sgmcgarry 
9476e0bca22Sgmcgarry 	default:
9486e0bca22Sgmcgarry 		cerror("illegal conput");
9496e0bca22Sgmcgarry 	}
9506e0bca22Sgmcgarry }
9516e0bca22Sgmcgarry 
9526e0bca22Sgmcgarry /*ARGSUSED*/
9536e0bca22Sgmcgarry void
insput(NODE * p)9546e0bca22Sgmcgarry insput(NODE *p)
9556e0bca22Sgmcgarry {
9566e0bca22Sgmcgarry 	cerror("insput");
9576e0bca22Sgmcgarry }
9586e0bca22Sgmcgarry 
9596e0bca22Sgmcgarry /*
9606e0bca22Sgmcgarry  * Write out the upper address, like the upper register of a 2-register
9616e0bca22Sgmcgarry  * reference, or the next memory location.
9626e0bca22Sgmcgarry  */
9636e0bca22Sgmcgarry void
upput(NODE * p,int size)9646e0bca22Sgmcgarry upput(NODE *p, int size)
9656e0bca22Sgmcgarry {
9666e0bca22Sgmcgarry 
9676e0bca22Sgmcgarry 	size /= SZLONG;
9686e0bca22Sgmcgarry 	switch (p->n_op) {
9696e0bca22Sgmcgarry 	case REG:
970370d6aa0Splunky 		printf("%s", rnames[p->n_rval + size]);
9716e0bca22Sgmcgarry 		break;
9726e0bca22Sgmcgarry 
9736e0bca22Sgmcgarry 	case NAME:
9746e0bca22Sgmcgarry 	case OREG:
9756e0bca22Sgmcgarry 		p->n_lval += size;
9766e0bca22Sgmcgarry 		adrput(stdout, p);
9776e0bca22Sgmcgarry 		p->n_lval -= size;
9786e0bca22Sgmcgarry 		break;
9796e0bca22Sgmcgarry 	case ICON:
9806e0bca22Sgmcgarry 		printf(CONFMT, p->n_lval >> (36 * size));
9816e0bca22Sgmcgarry 		break;
9826e0bca22Sgmcgarry 	default:
9836e0bca22Sgmcgarry 		cerror("upput bad op %d size %d", p->n_op, size);
9846e0bca22Sgmcgarry 	}
9856e0bca22Sgmcgarry }
9866e0bca22Sgmcgarry 
9876e0bca22Sgmcgarry void
adrput(FILE * fp,NODE * p)9886e0bca22Sgmcgarry adrput(FILE *fp, NODE *p)
9896e0bca22Sgmcgarry {
9906e0bca22Sgmcgarry 	int r;
9916e0bca22Sgmcgarry 	/* output an address, with offsets, from p */
9926e0bca22Sgmcgarry 
9936e0bca22Sgmcgarry 	if (p->n_op == FLD)
9946e0bca22Sgmcgarry 		p = p->n_left;
9956e0bca22Sgmcgarry 
9966e0bca22Sgmcgarry 	switch (p->n_op) {
9976e0bca22Sgmcgarry 
9986e0bca22Sgmcgarry 	case NAME:
9996e0bca22Sgmcgarry 		if (p->n_name[0] != '\0')
10006e0bca22Sgmcgarry 			fputs(p->n_name, fp);
10016e0bca22Sgmcgarry 		if (p->n_lval != 0)
10026e0bca22Sgmcgarry 			fprintf(fp, "+" CONFMT, p->n_lval & 0777777777777LL);
10036e0bca22Sgmcgarry 		return;
10046e0bca22Sgmcgarry 
10056e0bca22Sgmcgarry 	case OREG:
10066e0bca22Sgmcgarry 		r = p->n_rval;
10076e0bca22Sgmcgarry #if 0
10086e0bca22Sgmcgarry 		if (R2TEST(r)) { /* double indexing */
10096e0bca22Sgmcgarry 			register int flags;
10106e0bca22Sgmcgarry 
10116e0bca22Sgmcgarry 			flags = R2UPK3(r);
10126e0bca22Sgmcgarry 			if (flags & 1)
10136e0bca22Sgmcgarry 				putc('*', fp);
10146e0bca22Sgmcgarry 			if (flags & 4)
10156e0bca22Sgmcgarry 				putc('-', fp);
10166e0bca22Sgmcgarry 			if (p->n_lval != 0 || p->n_name[0] != '\0')
10176e0bca22Sgmcgarry 				acon(p);
10186e0bca22Sgmcgarry 			if (R2UPK1(r) != 100)
10196e0bca22Sgmcgarry 				printf("(%s)", rnames[R2UPK1(r)]);
10206e0bca22Sgmcgarry 			if (flags & 2)
10216e0bca22Sgmcgarry 				putchar('+');
10226e0bca22Sgmcgarry 			printf("[%s]", rnames[R2UPK2(r)]);
10236e0bca22Sgmcgarry 			return;
10246e0bca22Sgmcgarry 		}
10256e0bca22Sgmcgarry #endif
10266e0bca22Sgmcgarry 		if (R2TEST(r))
10276e0bca22Sgmcgarry 			cerror("adrput: unwanted double indexing: r %o", r);
10286e0bca22Sgmcgarry 		if (p->n_rval != FPREG && p->n_lval < 0 && p->n_name[0]) {
10296e0bca22Sgmcgarry 			fprintf(fp, "%s", p->n_name);
10306e0bca22Sgmcgarry 			acon(fp, p);
10316e0bca22Sgmcgarry 			fprintf(fp, "(%s)", rnames[p->n_rval]);
10326e0bca22Sgmcgarry 			return;
10336e0bca22Sgmcgarry 		}
10346e0bca22Sgmcgarry 		if (p->n_lval < 0 && p->n_rval == FPREG && offarg) {
10356e0bca22Sgmcgarry 			p->n_lval -= offarg-2; acon(fp, p); p->n_lval += offarg-2;
10366e0bca22Sgmcgarry 		} else if (p->n_lval != 0)
10376e0bca22Sgmcgarry 			acon(fp, p);
10386e0bca22Sgmcgarry 		if (p->n_name[0] != '\0')
10396e0bca22Sgmcgarry 			fprintf(fp, "%s%s", p->n_lval ? "+" : "", p->n_name);
10406e0bca22Sgmcgarry 		if (p->n_lval > 0 && p->n_rval == FPREG && offlab)
10416e0bca22Sgmcgarry 			fprintf(fp, "+" LABFMT, offlab);
10426e0bca22Sgmcgarry 		if (p->n_lval < 0 && p->n_rval == FPREG && offarg)
10436e0bca22Sgmcgarry 			fprintf(fp, "(017)");
10446e0bca22Sgmcgarry 		else
10456e0bca22Sgmcgarry 			fprintf(fp, "(%s)", rnames[p->n_rval]);
10466e0bca22Sgmcgarry 		return;
10476e0bca22Sgmcgarry 	case ICON:
10486e0bca22Sgmcgarry 		/* addressable value of the constant */
10496e0bca22Sgmcgarry 		if (p->n_lval > 0) {
10506e0bca22Sgmcgarry 			acon(fp, p);
10516e0bca22Sgmcgarry 			if (p->n_name[0] != '\0')
10526e0bca22Sgmcgarry 				putc('+', fp);
10536e0bca22Sgmcgarry 		}
10546e0bca22Sgmcgarry 		if (p->n_name[0] != '\0')
10556e0bca22Sgmcgarry 			fprintf(fp, "%s", p->n_name);
10566e0bca22Sgmcgarry 		if (p->n_lval < 0)
10576e0bca22Sgmcgarry 			acon(fp, p);
10586e0bca22Sgmcgarry 		if (p->n_name[0] == '\0' && p->n_lval == 0)
10596e0bca22Sgmcgarry 			putc('0', fp);
10606e0bca22Sgmcgarry 		return;
10616e0bca22Sgmcgarry 
10626e0bca22Sgmcgarry 	case REG:
10636e0bca22Sgmcgarry 		fputs(rnames[p->n_rval], fp);
10646e0bca22Sgmcgarry 		return;
10656e0bca22Sgmcgarry 
10666e0bca22Sgmcgarry 	default:
10676e0bca22Sgmcgarry 		cerror("illegal address, op %d", p->n_op);
10686e0bca22Sgmcgarry 		return;
10696e0bca22Sgmcgarry 
10706e0bca22Sgmcgarry 	}
10716e0bca22Sgmcgarry }
10726e0bca22Sgmcgarry 
10736e0bca22Sgmcgarry /*
10746e0bca22Sgmcgarry  * print out a constant
10756e0bca22Sgmcgarry  */
10766e0bca22Sgmcgarry void
acon(FILE * fp,NODE * p)10776e0bca22Sgmcgarry acon(FILE *fp, NODE *p)
10786e0bca22Sgmcgarry {
10796e0bca22Sgmcgarry 	if (p->n_lval < 0 && p->n_lval > -0777777777777ULL)
10806e0bca22Sgmcgarry 		fprintf(fp, "-" CONFMT, -p->n_lval);
10816e0bca22Sgmcgarry 	else
10826e0bca22Sgmcgarry 		fprintf(fp, CONFMT, p->n_lval);
10836e0bca22Sgmcgarry }
10846e0bca22Sgmcgarry 
10856e0bca22Sgmcgarry /*   printf conditional and unconditional branches */
10866e0bca22Sgmcgarry void
cbgen(int o,int lab)10876e0bca22Sgmcgarry cbgen(int o,int lab)
10886e0bca22Sgmcgarry {
10896e0bca22Sgmcgarry }
10906e0bca22Sgmcgarry 
10916e0bca22Sgmcgarry /*
10926e0bca22Sgmcgarry  * Do some local optimizations that must be done after optim is called.
10936e0bca22Sgmcgarry  */
10946e0bca22Sgmcgarry static void
optim2(NODE * p,void * arg)1095c4627bc7Sgmcgarry optim2(NODE *p, void *arg)
10966e0bca22Sgmcgarry {
10976e0bca22Sgmcgarry 	int op = p->n_op;
10986e0bca22Sgmcgarry 	int m, ml;
10996e0bca22Sgmcgarry 	NODE *l;
11006e0bca22Sgmcgarry 
11016e0bca22Sgmcgarry 	/* Remove redundant PCONV's */
11026e0bca22Sgmcgarry 	if (op == PCONV) {
11036e0bca22Sgmcgarry 		l = p->n_left;
11046e0bca22Sgmcgarry 		m = BTYPE(p->n_type);
11056e0bca22Sgmcgarry 		ml = BTYPE(l->n_type);
11066e0bca22Sgmcgarry 		if ((m == INT || m == LONG || m == LONGLONG || m == FLOAT ||
11076e0bca22Sgmcgarry 		    m == DOUBLE || m == STRTY || m == UNIONTY ||
11086e0bca22Sgmcgarry 		    m == UNSIGNED || m == ULONG || m == ULONGLONG) &&
11096e0bca22Sgmcgarry 		    (ml == INT || ml == LONG || ml == LONGLONG || ml == FLOAT ||
11106e0bca22Sgmcgarry 		    ml == DOUBLE || ml == STRTY || ml == UNIONTY ||
11116e0bca22Sgmcgarry 		    ml == UNSIGNED || ml == ULONG ||
11126e0bca22Sgmcgarry 		    ml == ULONGLONG) && ISPTR(l->n_type)) {
11136e0bca22Sgmcgarry 			*p = *l;
11146e0bca22Sgmcgarry 			nfree(l);
11156e0bca22Sgmcgarry 			op = p->n_op;
11166e0bca22Sgmcgarry 		} else
11176e0bca22Sgmcgarry 		if (ISPTR(DECREF(p->n_type)) &&
11186e0bca22Sgmcgarry 		    (l->n_type == INCREF(STRTY))) {
11196e0bca22Sgmcgarry 			*p = *l;
11206e0bca22Sgmcgarry 			nfree(l);
11216e0bca22Sgmcgarry 			op = p->n_op;
11226e0bca22Sgmcgarry 		} else
11236e0bca22Sgmcgarry 		if (ISPTR(DECREF(l->n_type)) &&
11246e0bca22Sgmcgarry 		    (p->n_type == INCREF(INT) ||
11256e0bca22Sgmcgarry 		    p->n_type == INCREF(STRTY) ||
11266e0bca22Sgmcgarry 		    p->n_type == INCREF(UNSIGNED))) {
11276e0bca22Sgmcgarry 			*p = *l;
11286e0bca22Sgmcgarry 			nfree(l);
11296e0bca22Sgmcgarry 			op = p->n_op;
11306e0bca22Sgmcgarry 		}
11316e0bca22Sgmcgarry 
11326e0bca22Sgmcgarry 	}
11336e0bca22Sgmcgarry 	/* Add constands, similar to the one in optim() */
11346e0bca22Sgmcgarry 	if (op == PLUS && p->n_right->n_op == ICON) {
11356e0bca22Sgmcgarry 		l = p->n_left;
11366e0bca22Sgmcgarry 		if (l->n_op == PLUS && l->n_right->n_op == ICON &&
11376e0bca22Sgmcgarry 		    (p->n_right->n_name[0] == '\0' ||
11386e0bca22Sgmcgarry 		     l->n_right->n_name[0] == '\0')) {
11396e0bca22Sgmcgarry 			l->n_right->n_lval += p->n_right->n_lval;
11406e0bca22Sgmcgarry 			if (l->n_right->n_name[0] == '\0')
11416e0bca22Sgmcgarry 				l->n_right->n_name = p->n_right->n_name;
11426e0bca22Sgmcgarry 			nfree(p->n_right);
11436e0bca22Sgmcgarry 			*p = *l;
11446e0bca22Sgmcgarry 			nfree(l);
11456e0bca22Sgmcgarry 		}
11466e0bca22Sgmcgarry 	}
11476e0bca22Sgmcgarry 
11486e0bca22Sgmcgarry 	/* Convert "PTR undef" (void *) to "PTR uchar" */
11496e0bca22Sgmcgarry 	/* XXX - should be done in MI code */
11506e0bca22Sgmcgarry 	if (BTYPE(p->n_type) == VOID)
11516e0bca22Sgmcgarry 		p->n_type = (p->n_type & ~BTMASK) | UCHAR;
11526e0bca22Sgmcgarry 	if (op == ICON) {
11536e0bca22Sgmcgarry 		if ((p->n_type == (PTR|CHAR) || p->n_type == (PTR|UCHAR))
11546e0bca22Sgmcgarry 		    && p->n_lval == 0 && p->n_name[0] != '\0')
11556e0bca22Sgmcgarry 			p->n_lval = 0700000000000LL;
11566e0bca22Sgmcgarry 		if ((p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT))
11576e0bca22Sgmcgarry 		    && p->n_lval == 0 && p->n_name[0] != '\0')
11586e0bca22Sgmcgarry 			p->n_lval = 0750000000000LL;
11596e0bca22Sgmcgarry 	}
11606e0bca22Sgmcgarry 	if (op == MINUS) {
11616e0bca22Sgmcgarry 		if ((p->n_left->n_type == (PTR|CHAR) ||
11626e0bca22Sgmcgarry 		    p->n_left->n_type == (PTR|UCHAR)) &&
11636e0bca22Sgmcgarry 		    (p->n_right->n_type == (PTR|CHAR) ||
11646e0bca22Sgmcgarry 		    p->n_right->n_type == (PTR|UCHAR))) {
11656e0bca22Sgmcgarry 			l = talloc();
11666e0bca22Sgmcgarry 			l->n_op = SCONV;
11676e0bca22Sgmcgarry 			l->n_type = INT;
11686e0bca22Sgmcgarry 			l->n_left = p->n_right;
11696e0bca22Sgmcgarry 			p->n_right = l;
11706e0bca22Sgmcgarry 			l = talloc();
11716e0bca22Sgmcgarry 			l->n_op = SCONV;
11726e0bca22Sgmcgarry 			l->n_type = INT;
11736e0bca22Sgmcgarry 			l->n_left = p->n_left;
11746e0bca22Sgmcgarry 			p->n_left = l;
11756e0bca22Sgmcgarry 		}
11766e0bca22Sgmcgarry 	}
11776e0bca22Sgmcgarry }
11786e0bca22Sgmcgarry 
11796e0bca22Sgmcgarry void
myreader(struct interpass * ipole)11806e0bca22Sgmcgarry myreader(struct interpass *ipole)
11816e0bca22Sgmcgarry {
11826e0bca22Sgmcgarry 	struct interpass *ip;
11836e0bca22Sgmcgarry 
11846e0bca22Sgmcgarry 	DLIST_FOREACH(ip, ipole, qelem) {
11856e0bca22Sgmcgarry 		if (ip->type != IP_NODE)
11866e0bca22Sgmcgarry 			continue;
1187c4627bc7Sgmcgarry 		walkf(ip->ip_node, optim2, 0);
11886e0bca22Sgmcgarry 	}
11896e0bca22Sgmcgarry 
11906e0bca22Sgmcgarry 	if (x2debug) {
11916e0bca22Sgmcgarry 		printf("myreader final tree:\n");
11926e0bca22Sgmcgarry 		printip(ipole);
11936e0bca22Sgmcgarry 	}
11946e0bca22Sgmcgarry }
11956e0bca22Sgmcgarry 
11966e0bca22Sgmcgarry /*
11976e0bca22Sgmcgarry  * Remove some PCONVs after OREGs are created.
11986e0bca22Sgmcgarry  */
11996e0bca22Sgmcgarry static void
pconv2(NODE * p,void * arg)1200c4627bc7Sgmcgarry pconv2(NODE *p, void *arg)
12016e0bca22Sgmcgarry {
12026e0bca22Sgmcgarry 	NODE *q;
12036e0bca22Sgmcgarry 
12046e0bca22Sgmcgarry 	if (p->n_op == PLUS) {
12056e0bca22Sgmcgarry 		if (p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT)) {
12066e0bca22Sgmcgarry 			if (p->n_right->n_op != ICON)
12076e0bca22Sgmcgarry 				return;
12086e0bca22Sgmcgarry 			if (p->n_left->n_op != PCONV)
12096e0bca22Sgmcgarry 				return;
12106e0bca22Sgmcgarry 			if (p->n_left->n_left->n_op != OREG)
12116e0bca22Sgmcgarry 				return;
12126e0bca22Sgmcgarry 			q = p->n_left->n_left;
12136e0bca22Sgmcgarry 			nfree(p->n_left);
12146e0bca22Sgmcgarry 			p->n_left = q;
12156e0bca22Sgmcgarry 			/*
12166e0bca22Sgmcgarry 			 * This will be converted to another OREG later.
12176e0bca22Sgmcgarry 			 */
12186e0bca22Sgmcgarry 		}
12196e0bca22Sgmcgarry 	}
12206e0bca22Sgmcgarry }
12216e0bca22Sgmcgarry 
12226e0bca22Sgmcgarry void
mycanon(NODE * p)12236e0bca22Sgmcgarry mycanon(NODE *p)
12246e0bca22Sgmcgarry {
1225c4627bc7Sgmcgarry 	walkf(p, pconv2, 0);
12266e0bca22Sgmcgarry }
12276e0bca22Sgmcgarry 
12286e0bca22Sgmcgarry /*
12296e0bca22Sgmcgarry  * Remove last goto.
12306e0bca22Sgmcgarry  */
12316e0bca22Sgmcgarry void
myoptim(struct interpass * ip)12326e0bca22Sgmcgarry myoptim(struct interpass *ip)
12336e0bca22Sgmcgarry {
12346e0bca22Sgmcgarry }
12356e0bca22Sgmcgarry 
12366e0bca22Sgmcgarry /*
12376e0bca22Sgmcgarry  * Return a class suitable for a specific type.
12386e0bca22Sgmcgarry  */
12396e0bca22Sgmcgarry int
gclass(TWORD t)12406e0bca22Sgmcgarry gclass(TWORD t)
12416e0bca22Sgmcgarry {
12426e0bca22Sgmcgarry 	return (szty(t) == 2 ? CLASSB : CLASSA);
12436e0bca22Sgmcgarry }
12446e0bca22Sgmcgarry 
12456e0bca22Sgmcgarry static int
argsiz(NODE * p)12466e0bca22Sgmcgarry argsiz(NODE *p)
12476e0bca22Sgmcgarry {
12486e0bca22Sgmcgarry 	TWORD t = p->n_type;
12496e0bca22Sgmcgarry 
12506e0bca22Sgmcgarry 	if (t == STRTY || t == UNIONTY)
1251*6935091cSplunky 		return attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0)/(SZINT/SZCHAR);
12526e0bca22Sgmcgarry 	return szty(t);
12536e0bca22Sgmcgarry }
12546e0bca22Sgmcgarry 
12556e0bca22Sgmcgarry /*
12566e0bca22Sgmcgarry  * Calculate argument sizes.
12576e0bca22Sgmcgarry  */
12586e0bca22Sgmcgarry void
lastcall(NODE * p)12596e0bca22Sgmcgarry lastcall(NODE *p)
12606e0bca22Sgmcgarry {
12616e0bca22Sgmcgarry         NODE *op = p;
12626e0bca22Sgmcgarry         int size = 0;
12636e0bca22Sgmcgarry 
12646e0bca22Sgmcgarry         p->n_qual = 0;
12656e0bca22Sgmcgarry         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
12666e0bca22Sgmcgarry                 return;
12676e0bca22Sgmcgarry         for (p = p->n_right; p->n_op == CM; p = p->n_left)
12686e0bca22Sgmcgarry 		if (p->n_right->n_op != ASSIGN)
12696e0bca22Sgmcgarry                 	size += argsiz(p->n_right);
12706e0bca22Sgmcgarry 	if (p->n_op != ASSIGN)
12716e0bca22Sgmcgarry         	size += argsiz(p);
12726e0bca22Sgmcgarry         op->n_qual = size; /* XXX */
12736e0bca22Sgmcgarry }
12746e0bca22Sgmcgarry 
12756e0bca22Sgmcgarry void
rmove(int s,int d,TWORD t)12766e0bca22Sgmcgarry rmove(int s, int d, TWORD t)
12776e0bca22Sgmcgarry {
12786e0bca22Sgmcgarry 	printf("	%smove %s,%s\n",
12796e0bca22Sgmcgarry 	    (s > 017 ? "d" : ""), rnames[d], rnames[s]);
12806e0bca22Sgmcgarry }
12816e0bca22Sgmcgarry 
12826e0bca22Sgmcgarry /*
12836e0bca22Sgmcgarry  * For class c, find worst-case displacement of the number of
12846e0bca22Sgmcgarry  * registers in the array r[] indexed by class.
12856e0bca22Sgmcgarry  */
12866e0bca22Sgmcgarry int
COLORMAP(int c,int * r)12876e0bca22Sgmcgarry COLORMAP(int c, int *r)
12886e0bca22Sgmcgarry {
12896e0bca22Sgmcgarry 	int num;
12906e0bca22Sgmcgarry 
12916e0bca22Sgmcgarry 	switch (c) {
12926e0bca22Sgmcgarry 	case CLASSA:
12936e0bca22Sgmcgarry 		/* there are 13 classa, so min 6 classb are needed to block */
12946e0bca22Sgmcgarry 		num = r[CLASSB] * 2;
12956e0bca22Sgmcgarry 		num += r[CLASSA];
12966e0bca22Sgmcgarry 		return num < 13;
12976e0bca22Sgmcgarry 	case CLASSB:
12986e0bca22Sgmcgarry 		/* 7 classa may block all classb */
12996e0bca22Sgmcgarry 		num = r[CLASSB] + r[CLASSA];
13006e0bca22Sgmcgarry 		return num < 7;
13016e0bca22Sgmcgarry 	}
13026e0bca22Sgmcgarry 	comperr("COLORMAP");
13036e0bca22Sgmcgarry 	return 0; /* XXX gcc */
13046e0bca22Sgmcgarry }
13056e0bca22Sgmcgarry 
13066e0bca22Sgmcgarry /*
13076e0bca22Sgmcgarry  * Target-dependent command-line options.
13086e0bca22Sgmcgarry  */
13096e0bca22Sgmcgarry void
mflags(char * str)13106e0bca22Sgmcgarry mflags(char *str)
13116e0bca22Sgmcgarry {
13126e0bca22Sgmcgarry }
1313370d6aa0Splunky 
13146e0bca22Sgmcgarry /*
13156e0bca22Sgmcgarry  * Do something target-dependent for xasm arguments.
13166e0bca22Sgmcgarry  * Supposed to find target-specific constraints and rewrite them.
13176e0bca22Sgmcgarry  */
13186e0bca22Sgmcgarry int
myxasm(struct interpass * ip,NODE * p)13196e0bca22Sgmcgarry myxasm(struct interpass *ip, NODE *p)
13206e0bca22Sgmcgarry {
13216e0bca22Sgmcgarry 	return 0;
13226e0bca22Sgmcgarry }
1323