xref: /inferno-os/utils/0c/txt.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "gc.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth void
ginit(void)4*74a4d8c2SCharles.Forsyth ginit(void)
5*74a4d8c2SCharles.Forsyth {
6*74a4d8c2SCharles.Forsyth 	int i;
7*74a4d8c2SCharles.Forsyth 	Type *t;
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth 	thechar = '0';
10*74a4d8c2SCharles.Forsyth 	thestring = "spim";
11*74a4d8c2SCharles.Forsyth 	exregoffset = REGEXT;
12*74a4d8c2SCharles.Forsyth 	exfregoffset = FREGEXT;
13*74a4d8c2SCharles.Forsyth 	listinit();
14*74a4d8c2SCharles.Forsyth 	nstring = 0;
15*74a4d8c2SCharles.Forsyth 	mnstring = 0;
16*74a4d8c2SCharles.Forsyth 	nrathole = 0;
17*74a4d8c2SCharles.Forsyth 	pc = 0;
18*74a4d8c2SCharles.Forsyth 	breakpc = -1;
19*74a4d8c2SCharles.Forsyth 	continpc = -1;
20*74a4d8c2SCharles.Forsyth 	cases = C;
21*74a4d8c2SCharles.Forsyth 	firstp = P;
22*74a4d8c2SCharles.Forsyth 	lastp = P;
23*74a4d8c2SCharles.Forsyth 	tfield = types[TLONG];
24*74a4d8c2SCharles.Forsyth 
25*74a4d8c2SCharles.Forsyth 	zprog.link = P;
26*74a4d8c2SCharles.Forsyth 	zprog.as = AGOK;
27*74a4d8c2SCharles.Forsyth 	zprog.reg = NREG;
28*74a4d8c2SCharles.Forsyth 	zprog.from.type = D_NONE;
29*74a4d8c2SCharles.Forsyth 	zprog.from.name = D_NONE;
30*74a4d8c2SCharles.Forsyth 	zprog.from.reg = NREG;
31*74a4d8c2SCharles.Forsyth 	zprog.to = zprog.from;
32*74a4d8c2SCharles.Forsyth 
33*74a4d8c2SCharles.Forsyth 	regnode.op = OREGISTER;
34*74a4d8c2SCharles.Forsyth 	regnode.class = CEXREG;
35*74a4d8c2SCharles.Forsyth 	regnode.reg = REGTMP;
36*74a4d8c2SCharles.Forsyth 	regnode.complex = 0;
37*74a4d8c2SCharles.Forsyth 	regnode.addable = 11;
38*74a4d8c2SCharles.Forsyth 	regnode.type = types[TLONG];
39*74a4d8c2SCharles.Forsyth 
40*74a4d8c2SCharles.Forsyth 	constnode.op = OCONST;
41*74a4d8c2SCharles.Forsyth 	constnode.class = CXXX;
42*74a4d8c2SCharles.Forsyth 	constnode.complex = 0;
43*74a4d8c2SCharles.Forsyth 	constnode.addable = 20;
44*74a4d8c2SCharles.Forsyth 	constnode.type = types[TLONG];
45*74a4d8c2SCharles.Forsyth 
46*74a4d8c2SCharles.Forsyth 	fconstnode.op = OCONST;
47*74a4d8c2SCharles.Forsyth 	fconstnode.class = CXXX;
48*74a4d8c2SCharles.Forsyth 	fconstnode.complex = 0;
49*74a4d8c2SCharles.Forsyth 	fconstnode.addable = 20;
50*74a4d8c2SCharles.Forsyth 	fconstnode.type = types[TDOUBLE];
51*74a4d8c2SCharles.Forsyth 
52*74a4d8c2SCharles.Forsyth 	nodsafe = new(ONAME, Z, Z);
53*74a4d8c2SCharles.Forsyth 	nodsafe->sym = slookup(".safe");
54*74a4d8c2SCharles.Forsyth 	nodsafe->type = types[TINT];
55*74a4d8c2SCharles.Forsyth 	nodsafe->etype = types[TINT]->etype;
56*74a4d8c2SCharles.Forsyth 	nodsafe->class = CAUTO;
57*74a4d8c2SCharles.Forsyth 	complex(nodsafe);
58*74a4d8c2SCharles.Forsyth 
59*74a4d8c2SCharles.Forsyth 	t = typ(TARRAY, types[TCHAR]);
60*74a4d8c2SCharles.Forsyth 	symrathole = slookup(".rathole");
61*74a4d8c2SCharles.Forsyth 	symrathole->class = CGLOBL;
62*74a4d8c2SCharles.Forsyth 	symrathole->type = t;
63*74a4d8c2SCharles.Forsyth 
64*74a4d8c2SCharles.Forsyth 	nodrat = new(ONAME, Z, Z);
65*74a4d8c2SCharles.Forsyth 	nodrat->sym = symrathole;
66*74a4d8c2SCharles.Forsyth 	nodrat->type = types[TIND];
67*74a4d8c2SCharles.Forsyth 	nodrat->etype = TVOID;
68*74a4d8c2SCharles.Forsyth 	nodrat->class = CGLOBL;
69*74a4d8c2SCharles.Forsyth 	complex(nodrat);
70*74a4d8c2SCharles.Forsyth 	nodrat->type = t;
71*74a4d8c2SCharles.Forsyth 
72*74a4d8c2SCharles.Forsyth 	nodret = new(ONAME, Z, Z);
73*74a4d8c2SCharles.Forsyth 	nodret->sym = slookup(".ret");
74*74a4d8c2SCharles.Forsyth 	nodret->type = types[TIND];
75*74a4d8c2SCharles.Forsyth 	nodret->etype = TIND;
76*74a4d8c2SCharles.Forsyth 	nodret->class = CPARAM;
77*74a4d8c2SCharles.Forsyth 	nodret = new(OIND, nodret, Z);
78*74a4d8c2SCharles.Forsyth 	complex(nodret);
79*74a4d8c2SCharles.Forsyth 
80*74a4d8c2SCharles.Forsyth 	for(i=0; i<nelem(reg); i++) {
81*74a4d8c2SCharles.Forsyth 		reg[i] = 0;
82*74a4d8c2SCharles.Forsyth 		if(i == REGZERO ||
83*74a4d8c2SCharles.Forsyth 		  (i >= NREG && ((i-NREG)&1)))
84*74a4d8c2SCharles.Forsyth 			reg[i] = 1;
85*74a4d8c2SCharles.Forsyth 	}
86*74a4d8c2SCharles.Forsyth }
87*74a4d8c2SCharles.Forsyth 
88*74a4d8c2SCharles.Forsyth void
gclean(void)89*74a4d8c2SCharles.Forsyth gclean(void)
90*74a4d8c2SCharles.Forsyth {
91*74a4d8c2SCharles.Forsyth 	int i;
92*74a4d8c2SCharles.Forsyth 	Sym *s;
93*74a4d8c2SCharles.Forsyth 
94*74a4d8c2SCharles.Forsyth 	for(i=0; i<NREG; i++)
95*74a4d8c2SCharles.Forsyth 		if(i != REGZERO)
96*74a4d8c2SCharles.Forsyth 			if(reg[i])
97*74a4d8c2SCharles.Forsyth 				diag(Z, "reg %d left allocated", i);
98*74a4d8c2SCharles.Forsyth 	for(i=NREG; i<NREG+NREG; i+=2)
99*74a4d8c2SCharles.Forsyth 		if(reg[i])
100*74a4d8c2SCharles.Forsyth 			diag(Z, "freg %d left allocated", i-NREG);
101*74a4d8c2SCharles.Forsyth 	while(mnstring)
102*74a4d8c2SCharles.Forsyth 		outstring("", 1L);
103*74a4d8c2SCharles.Forsyth 	symstring->type->width = nstring;
104*74a4d8c2SCharles.Forsyth 	symrathole->type->width = nrathole;
105*74a4d8c2SCharles.Forsyth 	for(i=0; i<NHASH; i++)
106*74a4d8c2SCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
107*74a4d8c2SCharles.Forsyth 		if(s->type == T)
108*74a4d8c2SCharles.Forsyth 			continue;
109*74a4d8c2SCharles.Forsyth 		if(s->type->width == 0)
110*74a4d8c2SCharles.Forsyth 			continue;
111*74a4d8c2SCharles.Forsyth 		if(s->class != CGLOBL && s->class != CSTATIC)
112*74a4d8c2SCharles.Forsyth 			continue;
113*74a4d8c2SCharles.Forsyth 		if(s->type == types[TENUM])
114*74a4d8c2SCharles.Forsyth 			continue;
115*74a4d8c2SCharles.Forsyth 		gpseudo(AGLOBL, s, nodconst(s->type->width));
116*74a4d8c2SCharles.Forsyth 	}
117*74a4d8c2SCharles.Forsyth 	nextpc();
118*74a4d8c2SCharles.Forsyth 	p->as = AEND;
119*74a4d8c2SCharles.Forsyth 	outcode();
120*74a4d8c2SCharles.Forsyth }
121*74a4d8c2SCharles.Forsyth 
122*74a4d8c2SCharles.Forsyth void
nextpc(void)123*74a4d8c2SCharles.Forsyth nextpc(void)
124*74a4d8c2SCharles.Forsyth {
125*74a4d8c2SCharles.Forsyth 
126*74a4d8c2SCharles.Forsyth 	p = alloc(sizeof(*p));
127*74a4d8c2SCharles.Forsyth 	*p = zprog;
128*74a4d8c2SCharles.Forsyth 	p->lineno = nearln;
129*74a4d8c2SCharles.Forsyth 	pc++;
130*74a4d8c2SCharles.Forsyth 	if(firstp == P) {
131*74a4d8c2SCharles.Forsyth 		firstp = p;
132*74a4d8c2SCharles.Forsyth 		lastp = p;
133*74a4d8c2SCharles.Forsyth 		return;
134*74a4d8c2SCharles.Forsyth 	}
135*74a4d8c2SCharles.Forsyth 	lastp->link = p;
136*74a4d8c2SCharles.Forsyth 	lastp = p;
137*74a4d8c2SCharles.Forsyth }
138*74a4d8c2SCharles.Forsyth 
139*74a4d8c2SCharles.Forsyth void
gargs(Node * n,Node * tn1,Node * tn2)140*74a4d8c2SCharles.Forsyth gargs(Node *n, Node *tn1, Node *tn2)
141*74a4d8c2SCharles.Forsyth {
142*74a4d8c2SCharles.Forsyth 	long regs;
143*74a4d8c2SCharles.Forsyth 	Node fnxargs[20], *fnxp;
144*74a4d8c2SCharles.Forsyth 
145*74a4d8c2SCharles.Forsyth 	regs = cursafe;
146*74a4d8c2SCharles.Forsyth 
147*74a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
148*74a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
149*74a4d8c2SCharles.Forsyth 
150*74a4d8c2SCharles.Forsyth 	curarg = 0;
151*74a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
152*74a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
153*74a4d8c2SCharles.Forsyth 
154*74a4d8c2SCharles.Forsyth 	cursafe = regs;
155*74a4d8c2SCharles.Forsyth }
156*74a4d8c2SCharles.Forsyth 
157*74a4d8c2SCharles.Forsyth void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)158*74a4d8c2SCharles.Forsyth garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
159*74a4d8c2SCharles.Forsyth {
160*74a4d8c2SCharles.Forsyth 	Node nod;
161*74a4d8c2SCharles.Forsyth 
162*74a4d8c2SCharles.Forsyth 	if(n == Z)
163*74a4d8c2SCharles.Forsyth 		return;
164*74a4d8c2SCharles.Forsyth 	if(n->op == OLIST) {
165*74a4d8c2SCharles.Forsyth 		garg1(n->left, tn1, tn2, f, fnxp);
166*74a4d8c2SCharles.Forsyth 		garg1(n->right, tn1, tn2, f, fnxp);
167*74a4d8c2SCharles.Forsyth 		return;
168*74a4d8c2SCharles.Forsyth 	}
169*74a4d8c2SCharles.Forsyth 	if(f == 0) {
170*74a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
171*74a4d8c2SCharles.Forsyth 			regsalloc(*fnxp, n);
172*74a4d8c2SCharles.Forsyth 			nod = znode;
173*74a4d8c2SCharles.Forsyth 			nod.op = OAS;
174*74a4d8c2SCharles.Forsyth 			nod.left = *fnxp;
175*74a4d8c2SCharles.Forsyth 			nod.right = n;
176*74a4d8c2SCharles.Forsyth 			nod.type = n->type;
177*74a4d8c2SCharles.Forsyth 			cgen(&nod, Z);
178*74a4d8c2SCharles.Forsyth 			(*fnxp)++;
179*74a4d8c2SCharles.Forsyth 		}
180*74a4d8c2SCharles.Forsyth 		return;
181*74a4d8c2SCharles.Forsyth 	}
182*74a4d8c2SCharles.Forsyth 	if(typesu[n->type->etype]) {
183*74a4d8c2SCharles.Forsyth 		regaalloc(tn2, n);
184*74a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
185*74a4d8c2SCharles.Forsyth 			sugen(*fnxp, tn2, n->type->width);
186*74a4d8c2SCharles.Forsyth 			(*fnxp)++;
187*74a4d8c2SCharles.Forsyth 		} else
188*74a4d8c2SCharles.Forsyth 			sugen(n, tn2, n->type->width);
189*74a4d8c2SCharles.Forsyth 		return;
190*74a4d8c2SCharles.Forsyth 	}
191*74a4d8c2SCharles.Forsyth 	if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
192*74a4d8c2SCharles.Forsyth 		regaalloc1(tn1, n);
193*74a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
194*74a4d8c2SCharles.Forsyth 			cgen(*fnxp, tn1);
195*74a4d8c2SCharles.Forsyth 			(*fnxp)++;
196*74a4d8c2SCharles.Forsyth 		} else
197*74a4d8c2SCharles.Forsyth 			cgen(n, tn1);
198*74a4d8c2SCharles.Forsyth 		return;
199*74a4d8c2SCharles.Forsyth 	}
200*74a4d8c2SCharles.Forsyth 	if(vconst(n) == 0) {
201*74a4d8c2SCharles.Forsyth 		regaalloc(tn2, n);
202*74a4d8c2SCharles.Forsyth 		gopcode(OAS, n, Z, tn2);
203*74a4d8c2SCharles.Forsyth 		return;
204*74a4d8c2SCharles.Forsyth 	}
205*74a4d8c2SCharles.Forsyth 	regalloc(tn1, n, Z);
206*74a4d8c2SCharles.Forsyth 	if(n->complex >= FNX) {
207*74a4d8c2SCharles.Forsyth 		cgen(*fnxp, tn1);
208*74a4d8c2SCharles.Forsyth 		(*fnxp)++;
209*74a4d8c2SCharles.Forsyth 	} else
210*74a4d8c2SCharles.Forsyth 		cgen(n, tn1);
211*74a4d8c2SCharles.Forsyth 	regaalloc(tn2, n);
212*74a4d8c2SCharles.Forsyth 	gopcode(OAS, tn1, Z, tn2);
213*74a4d8c2SCharles.Forsyth 	regfree(tn1);
214*74a4d8c2SCharles.Forsyth }
215*74a4d8c2SCharles.Forsyth 
216*74a4d8c2SCharles.Forsyth Node*
nodconst(long v)217*74a4d8c2SCharles.Forsyth nodconst(long v)
218*74a4d8c2SCharles.Forsyth {
219*74a4d8c2SCharles.Forsyth 	constnode.vconst = v;
220*74a4d8c2SCharles.Forsyth 	return &constnode;
221*74a4d8c2SCharles.Forsyth }
222*74a4d8c2SCharles.Forsyth 
223*74a4d8c2SCharles.Forsyth Node*
nodfconst(double d)224*74a4d8c2SCharles.Forsyth nodfconst(double d)
225*74a4d8c2SCharles.Forsyth {
226*74a4d8c2SCharles.Forsyth 	fconstnode.fconst = d;
227*74a4d8c2SCharles.Forsyth 	return &fconstnode;
228*74a4d8c2SCharles.Forsyth }
229*74a4d8c2SCharles.Forsyth 
230*74a4d8c2SCharles.Forsyth void
nodreg(Node * n,Node * nn,int reg)231*74a4d8c2SCharles.Forsyth nodreg(Node *n, Node *nn, int reg)
232*74a4d8c2SCharles.Forsyth {
233*74a4d8c2SCharles.Forsyth 	*n = regnode;
234*74a4d8c2SCharles.Forsyth 	n->reg = reg;
235*74a4d8c2SCharles.Forsyth 	n->type = nn->type;
236*74a4d8c2SCharles.Forsyth 	n->lineno = nn->lineno;
237*74a4d8c2SCharles.Forsyth }
238*74a4d8c2SCharles.Forsyth 
239*74a4d8c2SCharles.Forsyth void
regret(Node * n,Node * nn)240*74a4d8c2SCharles.Forsyth regret(Node *n, Node *nn)
241*74a4d8c2SCharles.Forsyth {
242*74a4d8c2SCharles.Forsyth 	int r;
243*74a4d8c2SCharles.Forsyth 
244*74a4d8c2SCharles.Forsyth 	r = REGRET;
245*74a4d8c2SCharles.Forsyth 	if(typefd[nn->type->etype])
246*74a4d8c2SCharles.Forsyth 		r = FREGRET+NREG;
247*74a4d8c2SCharles.Forsyth 	nodreg(n, nn, r);
248*74a4d8c2SCharles.Forsyth 	reg[r]++;
249*74a4d8c2SCharles.Forsyth }
250*74a4d8c2SCharles.Forsyth 
251*74a4d8c2SCharles.Forsyth int
tmpreg(void)252*74a4d8c2SCharles.Forsyth tmpreg(void)
253*74a4d8c2SCharles.Forsyth {
254*74a4d8c2SCharles.Forsyth 	int i;
255*74a4d8c2SCharles.Forsyth 
256*74a4d8c2SCharles.Forsyth 	for(i=REGRET+1; i<NREG; i++)
257*74a4d8c2SCharles.Forsyth 		if(reg[i] == 0)
258*74a4d8c2SCharles.Forsyth 			return i;
259*74a4d8c2SCharles.Forsyth 	diag(Z, "out of fixed registers");
260*74a4d8c2SCharles.Forsyth 	return 0;
261*74a4d8c2SCharles.Forsyth }
262*74a4d8c2SCharles.Forsyth 
263*74a4d8c2SCharles.Forsyth void
regalloc(Node * n,Node * tn,Node * o)264*74a4d8c2SCharles.Forsyth regalloc(Node *n, Node *tn, Node *o)
265*74a4d8c2SCharles.Forsyth {
266*74a4d8c2SCharles.Forsyth 	int i, j;
267*74a4d8c2SCharles.Forsyth 	static int lasti;
268*74a4d8c2SCharles.Forsyth 
269*74a4d8c2SCharles.Forsyth 	switch(tn->type->etype) {
270*74a4d8c2SCharles.Forsyth 	case TCHAR:
271*74a4d8c2SCharles.Forsyth 	case TUCHAR:
272*74a4d8c2SCharles.Forsyth 	case TSHORT:
273*74a4d8c2SCharles.Forsyth 	case TUSHORT:
274*74a4d8c2SCharles.Forsyth 	case TINT:
275*74a4d8c2SCharles.Forsyth 	case TUINT:
276*74a4d8c2SCharles.Forsyth 	case TLONG:
277*74a4d8c2SCharles.Forsyth 	case TULONG:
278*74a4d8c2SCharles.Forsyth 	case TIND:
279*74a4d8c2SCharles.Forsyth 	case TUVLONG:
280*74a4d8c2SCharles.Forsyth 	case TVLONG:
281*74a4d8c2SCharles.Forsyth 		if(o != Z && o->op == OREGISTER) {
282*74a4d8c2SCharles.Forsyth 			i = o->reg;
283*74a4d8c2SCharles.Forsyth 			if(i > 0 && i < NREG)
284*74a4d8c2SCharles.Forsyth 				goto out;
285*74a4d8c2SCharles.Forsyth 		}
286*74a4d8c2SCharles.Forsyth 		j = lasti + REGRET+1;
287*74a4d8c2SCharles.Forsyth 		for(i=REGRET+1; i<NREG; i++) {
288*74a4d8c2SCharles.Forsyth 			if(j >= NREG)
289*74a4d8c2SCharles.Forsyth 				j = REGRET+1;
290*74a4d8c2SCharles.Forsyth 			if(reg[j] == 0) {
291*74a4d8c2SCharles.Forsyth 				i = j;
292*74a4d8c2SCharles.Forsyth 				goto out;
293*74a4d8c2SCharles.Forsyth 			}
294*74a4d8c2SCharles.Forsyth 			j++;
295*74a4d8c2SCharles.Forsyth 		}
296*74a4d8c2SCharles.Forsyth 		diag(tn, "out of fixed registers");
297*74a4d8c2SCharles.Forsyth 		goto err;
298*74a4d8c2SCharles.Forsyth 
299*74a4d8c2SCharles.Forsyth 	case TFLOAT:
300*74a4d8c2SCharles.Forsyth 	case TDOUBLE:
301*74a4d8c2SCharles.Forsyth 		if(o != Z && o->op == OREGISTER) {
302*74a4d8c2SCharles.Forsyth 			i = o->reg;
303*74a4d8c2SCharles.Forsyth 			if(i >= NREG && i < NREG+NREG)
304*74a4d8c2SCharles.Forsyth 				goto out;
305*74a4d8c2SCharles.Forsyth 		}
306*74a4d8c2SCharles.Forsyth 		j = 0*2 + NREG;
307*74a4d8c2SCharles.Forsyth 		for(i=NREG; i<NREG+NREG; i+=2) {
308*74a4d8c2SCharles.Forsyth 			if(j >= NREG+NREG)
309*74a4d8c2SCharles.Forsyth 				j = NREG;
310*74a4d8c2SCharles.Forsyth 			if(reg[j] == 0) {
311*74a4d8c2SCharles.Forsyth 				i = j;
312*74a4d8c2SCharles.Forsyth 				goto out;
313*74a4d8c2SCharles.Forsyth 			}
314*74a4d8c2SCharles.Forsyth 			j += 2;
315*74a4d8c2SCharles.Forsyth 		}
316*74a4d8c2SCharles.Forsyth 		diag(tn, "out of float registers");
317*74a4d8c2SCharles.Forsyth 		goto err;
318*74a4d8c2SCharles.Forsyth 	}
319*74a4d8c2SCharles.Forsyth 	diag(tn, "unknown type in regalloc: %T", tn->type);
320*74a4d8c2SCharles.Forsyth err:
321*74a4d8c2SCharles.Forsyth 	i = 0;
322*74a4d8c2SCharles.Forsyth out:
323*74a4d8c2SCharles.Forsyth 	if(i)
324*74a4d8c2SCharles.Forsyth 		reg[i]++;
325*74a4d8c2SCharles.Forsyth 	lasti++;
326*74a4d8c2SCharles.Forsyth 	if(lasti >= 5)
327*74a4d8c2SCharles.Forsyth 		lasti = 0;
328*74a4d8c2SCharles.Forsyth 	nodreg(n, tn, i);
329*74a4d8c2SCharles.Forsyth }
330*74a4d8c2SCharles.Forsyth 
331*74a4d8c2SCharles.Forsyth void
regialloc(Node * n,Node * tn,Node * o)332*74a4d8c2SCharles.Forsyth regialloc(Node *n, Node *tn, Node *o)
333*74a4d8c2SCharles.Forsyth {
334*74a4d8c2SCharles.Forsyth 	Node nod;
335*74a4d8c2SCharles.Forsyth 
336*74a4d8c2SCharles.Forsyth 	nod = *tn;
337*74a4d8c2SCharles.Forsyth 	nod.type = types[TIND];
338*74a4d8c2SCharles.Forsyth 	regalloc(n, &nod, o);
339*74a4d8c2SCharles.Forsyth }
340*74a4d8c2SCharles.Forsyth 
341*74a4d8c2SCharles.Forsyth void
regfree(Node * n)342*74a4d8c2SCharles.Forsyth regfree(Node *n)
343*74a4d8c2SCharles.Forsyth {
344*74a4d8c2SCharles.Forsyth 	int i;
345*74a4d8c2SCharles.Forsyth 
346*74a4d8c2SCharles.Forsyth 	i = 0;
347*74a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER && n->op != OINDREG)
348*74a4d8c2SCharles.Forsyth 		goto err;
349*74a4d8c2SCharles.Forsyth 	i = n->reg;
350*74a4d8c2SCharles.Forsyth 	if(i < 0 || i >= sizeof(reg))
351*74a4d8c2SCharles.Forsyth 		goto err;
352*74a4d8c2SCharles.Forsyth 	if(reg[i] <= 0)
353*74a4d8c2SCharles.Forsyth 		goto err;
354*74a4d8c2SCharles.Forsyth 	reg[i]--;
355*74a4d8c2SCharles.Forsyth 	return;
356*74a4d8c2SCharles.Forsyth err:
357*74a4d8c2SCharles.Forsyth 	diag(n, "error in regfree: %d", i);
358*74a4d8c2SCharles.Forsyth }
359*74a4d8c2SCharles.Forsyth 
360*74a4d8c2SCharles.Forsyth void
regsalloc(Node * n,Node * nn)361*74a4d8c2SCharles.Forsyth regsalloc(Node *n, Node *nn)
362*74a4d8c2SCharles.Forsyth {
363*74a4d8c2SCharles.Forsyth 	cursafe = align(cursafe, nn->type, Aaut3);
364*74a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
365*74a4d8c2SCharles.Forsyth 	*n = *nodsafe;
366*74a4d8c2SCharles.Forsyth 	n->xoffset = -(stkoff + cursafe);
367*74a4d8c2SCharles.Forsyth 	n->type = nn->type;
368*74a4d8c2SCharles.Forsyth 	n->etype = nn->type->etype;
369*74a4d8c2SCharles.Forsyth 	n->lineno = nn->lineno;
370*74a4d8c2SCharles.Forsyth }
371*74a4d8c2SCharles.Forsyth 
372*74a4d8c2SCharles.Forsyth void
regaalloc1(Node * n,Node * nn)373*74a4d8c2SCharles.Forsyth regaalloc1(Node *n, Node *nn)
374*74a4d8c2SCharles.Forsyth {
375*74a4d8c2SCharles.Forsyth 	nodreg(n, nn, REGARG);
376*74a4d8c2SCharles.Forsyth 	reg[REGARG]++;
377*74a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
378*74a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
379*74a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
380*74a4d8c2SCharles.Forsyth }
381*74a4d8c2SCharles.Forsyth 
382*74a4d8c2SCharles.Forsyth void
regaalloc(Node * n,Node * nn)383*74a4d8c2SCharles.Forsyth regaalloc(Node *n, Node *nn)
384*74a4d8c2SCharles.Forsyth {
385*74a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
386*74a4d8c2SCharles.Forsyth 	*n = *nn;
387*74a4d8c2SCharles.Forsyth 	n->op = OINDREG;
388*74a4d8c2SCharles.Forsyth 	n->reg = REGSP;
389*74a4d8c2SCharles.Forsyth 	n->xoffset = curarg + SZ_VLONG;
390*74a4d8c2SCharles.Forsyth 	n->complex = 0;
391*74a4d8c2SCharles.Forsyth 	n->addable = 20;
392*74a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
393*74a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
394*74a4d8c2SCharles.Forsyth }
395*74a4d8c2SCharles.Forsyth 
396*74a4d8c2SCharles.Forsyth void
regind(Node * n,Node * nn)397*74a4d8c2SCharles.Forsyth regind(Node *n, Node *nn)
398*74a4d8c2SCharles.Forsyth {
399*74a4d8c2SCharles.Forsyth 
400*74a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER) {
401*74a4d8c2SCharles.Forsyth 		diag(n, "regind not OREGISTER");
402*74a4d8c2SCharles.Forsyth 		return;
403*74a4d8c2SCharles.Forsyth 	}
404*74a4d8c2SCharles.Forsyth 	n->op = OINDREG;
405*74a4d8c2SCharles.Forsyth 	n->type = nn->type;
406*74a4d8c2SCharles.Forsyth }
407*74a4d8c2SCharles.Forsyth 
408*74a4d8c2SCharles.Forsyth void
raddr(Node * n,Prog * p)409*74a4d8c2SCharles.Forsyth raddr(Node *n, Prog *p)
410*74a4d8c2SCharles.Forsyth {
411*74a4d8c2SCharles.Forsyth 	Adr a;
412*74a4d8c2SCharles.Forsyth 
413*74a4d8c2SCharles.Forsyth 	naddr(n, &a);
414*74a4d8c2SCharles.Forsyth 	if(a.type == D_CONST && a.offset == 0) {
415*74a4d8c2SCharles.Forsyth 		a.type = D_REG;
416*74a4d8c2SCharles.Forsyth 		a.reg = 0;
417*74a4d8c2SCharles.Forsyth 	}
418*74a4d8c2SCharles.Forsyth 	if(a.type != D_REG && a.type != D_FREG) {
419*74a4d8c2SCharles.Forsyth 		if(n)
420*74a4d8c2SCharles.Forsyth 			diag(n, "bad in raddr: %O", n->op);
421*74a4d8c2SCharles.Forsyth 		else
422*74a4d8c2SCharles.Forsyth 			diag(n, "bad in raddr: <null>");
423*74a4d8c2SCharles.Forsyth 		p->reg = NREG;
424*74a4d8c2SCharles.Forsyth 	} else
425*74a4d8c2SCharles.Forsyth 		p->reg = a.reg;
426*74a4d8c2SCharles.Forsyth }
427*74a4d8c2SCharles.Forsyth 
428*74a4d8c2SCharles.Forsyth void
naddr(Node * n,Adr * a)429*74a4d8c2SCharles.Forsyth naddr(Node *n, Adr *a)
430*74a4d8c2SCharles.Forsyth {
431*74a4d8c2SCharles.Forsyth 	long v;
432*74a4d8c2SCharles.Forsyth 
433*74a4d8c2SCharles.Forsyth 	a->type = D_NONE;
434*74a4d8c2SCharles.Forsyth 	if(n == Z)
435*74a4d8c2SCharles.Forsyth 		return;
436*74a4d8c2SCharles.Forsyth 	switch(n->op) {
437*74a4d8c2SCharles.Forsyth 	default:
438*74a4d8c2SCharles.Forsyth 	bad:
439*74a4d8c2SCharles.Forsyth 		diag(n, "bad in naddr: %O", n->op);
440*74a4d8c2SCharles.Forsyth 		break;
441*74a4d8c2SCharles.Forsyth 
442*74a4d8c2SCharles.Forsyth 	case OREGISTER:
443*74a4d8c2SCharles.Forsyth 		a->type = D_REG;
444*74a4d8c2SCharles.Forsyth 		a->sym = S;
445*74a4d8c2SCharles.Forsyth 		a->reg = n->reg;
446*74a4d8c2SCharles.Forsyth 		if(a->reg >= NREG) {
447*74a4d8c2SCharles.Forsyth 			a->type = D_FREG;
448*74a4d8c2SCharles.Forsyth 			a->reg -= NREG;
449*74a4d8c2SCharles.Forsyth 		}
450*74a4d8c2SCharles.Forsyth 		break;
451*74a4d8c2SCharles.Forsyth 
452*74a4d8c2SCharles.Forsyth 	case OIND:
453*74a4d8c2SCharles.Forsyth 		naddr(n->left, a);
454*74a4d8c2SCharles.Forsyth 		if(a->type == D_REG) {
455*74a4d8c2SCharles.Forsyth 			a->type = D_OREG;
456*74a4d8c2SCharles.Forsyth 			break;
457*74a4d8c2SCharles.Forsyth 		}
458*74a4d8c2SCharles.Forsyth 		if(a->type == D_CONST) {
459*74a4d8c2SCharles.Forsyth 			a->type = D_OREG;
460*74a4d8c2SCharles.Forsyth 			break;
461*74a4d8c2SCharles.Forsyth 		}
462*74a4d8c2SCharles.Forsyth 		goto bad;
463*74a4d8c2SCharles.Forsyth 
464*74a4d8c2SCharles.Forsyth 	case OINDREG:
465*74a4d8c2SCharles.Forsyth 		a->type = D_OREG;
466*74a4d8c2SCharles.Forsyth 		a->sym = S;
467*74a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
468*74a4d8c2SCharles.Forsyth 		a->reg = n->reg;
469*74a4d8c2SCharles.Forsyth 		break;
470*74a4d8c2SCharles.Forsyth 
471*74a4d8c2SCharles.Forsyth 	case ONAME:
472*74a4d8c2SCharles.Forsyth 		a->etype = n->etype;
473*74a4d8c2SCharles.Forsyth 		a->type = D_OREG;
474*74a4d8c2SCharles.Forsyth 		a->name = D_STATIC;
475*74a4d8c2SCharles.Forsyth 		a->sym = n->sym;
476*74a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
477*74a4d8c2SCharles.Forsyth 		if(n->class == CSTATIC)
478*74a4d8c2SCharles.Forsyth 			break;
479*74a4d8c2SCharles.Forsyth 		if(n->class == CEXTERN || n->class == CGLOBL) {
480*74a4d8c2SCharles.Forsyth 			a->name = D_EXTERN;
481*74a4d8c2SCharles.Forsyth 			break;
482*74a4d8c2SCharles.Forsyth 		}
483*74a4d8c2SCharles.Forsyth 		if(n->class == CAUTO) {
484*74a4d8c2SCharles.Forsyth 			a->name = D_AUTO;
485*74a4d8c2SCharles.Forsyth 			break;
486*74a4d8c2SCharles.Forsyth 		}
487*74a4d8c2SCharles.Forsyth 		if(n->class == CPARAM) {
488*74a4d8c2SCharles.Forsyth 			a->name = D_PARAM;
489*74a4d8c2SCharles.Forsyth 			break;
490*74a4d8c2SCharles.Forsyth 		}
491*74a4d8c2SCharles.Forsyth 		goto bad;
492*74a4d8c2SCharles.Forsyth 
493*74a4d8c2SCharles.Forsyth 	case OCONST:
494*74a4d8c2SCharles.Forsyth 		a->sym = S;
495*74a4d8c2SCharles.Forsyth 		a->reg = NREG;
496*74a4d8c2SCharles.Forsyth 		if(typefd[n->type->etype]) {
497*74a4d8c2SCharles.Forsyth 			a->type = D_FCONST;
498*74a4d8c2SCharles.Forsyth 			a->dval = n->fconst;
499*74a4d8c2SCharles.Forsyth 		} else
500*74a4d8c2SCharles.Forsyth 		if(llconst(n)) {
501*74a4d8c2SCharles.Forsyth 			a->type = D_VCONST;
502*74a4d8c2SCharles.Forsyth 			a->vval = n->vconst;
503*74a4d8c2SCharles.Forsyth 		} else {
504*74a4d8c2SCharles.Forsyth 			a->type = D_CONST;
505*74a4d8c2SCharles.Forsyth 			a->offset = n->vconst;
506*74a4d8c2SCharles.Forsyth 		}
507*74a4d8c2SCharles.Forsyth 		break;
508*74a4d8c2SCharles.Forsyth 
509*74a4d8c2SCharles.Forsyth 	case OADDR:
510*74a4d8c2SCharles.Forsyth 		naddr(n->left, a);
511*74a4d8c2SCharles.Forsyth 		if(a->type == D_OREG) {
512*74a4d8c2SCharles.Forsyth 			a->type = D_CONST;
513*74a4d8c2SCharles.Forsyth 			break;
514*74a4d8c2SCharles.Forsyth 		}
515*74a4d8c2SCharles.Forsyth 		goto bad;
516*74a4d8c2SCharles.Forsyth 
517*74a4d8c2SCharles.Forsyth 	case OADD:
518*74a4d8c2SCharles.Forsyth 		if(n->left->op == OCONST) {
519*74a4d8c2SCharles.Forsyth 			naddr(n->left, a);
520*74a4d8c2SCharles.Forsyth 			v = a->offset;
521*74a4d8c2SCharles.Forsyth 			naddr(n->right, a);
522*74a4d8c2SCharles.Forsyth 		} else {
523*74a4d8c2SCharles.Forsyth 			naddr(n->right, a);
524*74a4d8c2SCharles.Forsyth 			v = a->offset;
525*74a4d8c2SCharles.Forsyth 			naddr(n->left, a);
526*74a4d8c2SCharles.Forsyth 		}
527*74a4d8c2SCharles.Forsyth 		a->offset += v;
528*74a4d8c2SCharles.Forsyth 		break;
529*74a4d8c2SCharles.Forsyth 
530*74a4d8c2SCharles.Forsyth 	}
531*74a4d8c2SCharles.Forsyth }
532*74a4d8c2SCharles.Forsyth 
533*74a4d8c2SCharles.Forsyth void
fop(int as,int f1,int f2,Node * t)534*74a4d8c2SCharles.Forsyth fop(int as, int f1, int f2, Node *t)
535*74a4d8c2SCharles.Forsyth {
536*74a4d8c2SCharles.Forsyth 	Node nod1, nod2, nod3;
537*74a4d8c2SCharles.Forsyth 
538*74a4d8c2SCharles.Forsyth 	nodreg(&nod1, t, NREG+f1);
539*74a4d8c2SCharles.Forsyth 	nodreg(&nod2, t, NREG+f2);
540*74a4d8c2SCharles.Forsyth 	regalloc(&nod3, t, t);
541*74a4d8c2SCharles.Forsyth 	gopcode(as, &nod1, &nod2, &nod3);
542*74a4d8c2SCharles.Forsyth 	gmove(&nod3, t);
543*74a4d8c2SCharles.Forsyth 	regfree(&nod3);
544*74a4d8c2SCharles.Forsyth }
545*74a4d8c2SCharles.Forsyth 
546*74a4d8c2SCharles.Forsyth void
gmove(Node * f,Node * t)547*74a4d8c2SCharles.Forsyth gmove(Node *f, Node *t)
548*74a4d8c2SCharles.Forsyth {
549*74a4d8c2SCharles.Forsyth 	int ft, tt, a;
550*74a4d8c2SCharles.Forsyth 	Node nod;
551*74a4d8c2SCharles.Forsyth 	Prog *p1;
552*74a4d8c2SCharles.Forsyth 	double d;
553*74a4d8c2SCharles.Forsyth 
554*74a4d8c2SCharles.Forsyth 	ft = f->type->etype;
555*74a4d8c2SCharles.Forsyth 	tt = t->type->etype;
556*74a4d8c2SCharles.Forsyth 
557*74a4d8c2SCharles.Forsyth 	if(ft == TDOUBLE && f->op == OCONST) {
558*74a4d8c2SCharles.Forsyth 		d = f->fconst;
559*74a4d8c2SCharles.Forsyth 		if(d == 0.0) {
560*74a4d8c2SCharles.Forsyth 			a = FREGZERO;
561*74a4d8c2SCharles.Forsyth 			goto ffreg;
562*74a4d8c2SCharles.Forsyth 		}
563*74a4d8c2SCharles.Forsyth 		if(d == 0.5) {
564*74a4d8c2SCharles.Forsyth 			a = FREGHALF;
565*74a4d8c2SCharles.Forsyth 			goto ffreg;
566*74a4d8c2SCharles.Forsyth 		}
567*74a4d8c2SCharles.Forsyth 		if(d == 1.0) {
568*74a4d8c2SCharles.Forsyth 			a = FREGONE;
569*74a4d8c2SCharles.Forsyth 			goto ffreg;
570*74a4d8c2SCharles.Forsyth 		}
571*74a4d8c2SCharles.Forsyth 		if(d == 2.0) {
572*74a4d8c2SCharles.Forsyth 			a = FREGTWO;
573*74a4d8c2SCharles.Forsyth 			goto ffreg;
574*74a4d8c2SCharles.Forsyth 		}
575*74a4d8c2SCharles.Forsyth 		if(d == -.5) {
576*74a4d8c2SCharles.Forsyth 			fop(OSUB, FREGHALF, FREGZERO, t);
577*74a4d8c2SCharles.Forsyth 			return;
578*74a4d8c2SCharles.Forsyth 		}
579*74a4d8c2SCharles.Forsyth 		if(d == -1.0) {
580*74a4d8c2SCharles.Forsyth 			fop(OSUB, FREGONE, FREGZERO, t);
581*74a4d8c2SCharles.Forsyth 			return;
582*74a4d8c2SCharles.Forsyth 		}
583*74a4d8c2SCharles.Forsyth 		if(d == -2.0) {
584*74a4d8c2SCharles.Forsyth 			fop(OSUB, FREGTWO, FREGZERO, t);
585*74a4d8c2SCharles.Forsyth 			return;
586*74a4d8c2SCharles.Forsyth 		}
587*74a4d8c2SCharles.Forsyth 		if(d == 1.5) {
588*74a4d8c2SCharles.Forsyth 			fop(OADD, FREGONE, FREGHALF, t);
589*74a4d8c2SCharles.Forsyth 			return;
590*74a4d8c2SCharles.Forsyth 		}
591*74a4d8c2SCharles.Forsyth 		if(d == 2.5) {
592*74a4d8c2SCharles.Forsyth 			fop(OADD, FREGTWO, FREGHALF, t);
593*74a4d8c2SCharles.Forsyth 			return;
594*74a4d8c2SCharles.Forsyth 		}
595*74a4d8c2SCharles.Forsyth 		if(d == 3.0) {
596*74a4d8c2SCharles.Forsyth 			fop(OADD, FREGTWO, FREGONE, t);
597*74a4d8c2SCharles.Forsyth 			return;
598*74a4d8c2SCharles.Forsyth 		}
599*74a4d8c2SCharles.Forsyth 	}
600*74a4d8c2SCharles.Forsyth 	if(ft == TFLOAT && f->op == OCONST) {
601*74a4d8c2SCharles.Forsyth 		d = f->fconst;
602*74a4d8c2SCharles.Forsyth 		if(d == 0) {
603*74a4d8c2SCharles.Forsyth 			a = FREGZERO;
604*74a4d8c2SCharles.Forsyth 		ffreg:
605*74a4d8c2SCharles.Forsyth 			nodreg(&nod, f, NREG+a);
606*74a4d8c2SCharles.Forsyth 			gmove(&nod, t);
607*74a4d8c2SCharles.Forsyth 			return;
608*74a4d8c2SCharles.Forsyth 		}
609*74a4d8c2SCharles.Forsyth 	}
610*74a4d8c2SCharles.Forsyth 	/*
611*74a4d8c2SCharles.Forsyth 	 * a load --
612*74a4d8c2SCharles.Forsyth 	 * put it into a register then
613*74a4d8c2SCharles.Forsyth 	 * worry what to do with it.
614*74a4d8c2SCharles.Forsyth 	 */
615*74a4d8c2SCharles.Forsyth 	if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
616*74a4d8c2SCharles.Forsyth 		switch(ft) {
617*74a4d8c2SCharles.Forsyth 		default:
618*74a4d8c2SCharles.Forsyth 			if(typefd[tt]) {
619*74a4d8c2SCharles.Forsyth 				/* special case can load mem to Freg */
620*74a4d8c2SCharles.Forsyth 				regalloc(&nod, t, t);
621*74a4d8c2SCharles.Forsyth 				gins(AMOVW, f, &nod);
622*74a4d8c2SCharles.Forsyth 				a = AMOVWD;
623*74a4d8c2SCharles.Forsyth 				if(tt == TFLOAT)
624*74a4d8c2SCharles.Forsyth 					a = AMOVWF;
625*74a4d8c2SCharles.Forsyth 				gins(a, &nod, &nod);
626*74a4d8c2SCharles.Forsyth 				gmove(&nod, t);
627*74a4d8c2SCharles.Forsyth 				regfree(&nod);
628*74a4d8c2SCharles.Forsyth 				return;
629*74a4d8c2SCharles.Forsyth 			}
630*74a4d8c2SCharles.Forsyth 			a = AMOVW;
631*74a4d8c2SCharles.Forsyth 			break;
632*74a4d8c2SCharles.Forsyth 		case TCHAR:
633*74a4d8c2SCharles.Forsyth 			a = AMOVB;
634*74a4d8c2SCharles.Forsyth 			break;
635*74a4d8c2SCharles.Forsyth 		case TUCHAR:
636*74a4d8c2SCharles.Forsyth 			a = AMOVBU;
637*74a4d8c2SCharles.Forsyth 			break;
638*74a4d8c2SCharles.Forsyth 		case TSHORT:
639*74a4d8c2SCharles.Forsyth 			a = AMOVH;
640*74a4d8c2SCharles.Forsyth 			break;
641*74a4d8c2SCharles.Forsyth 		case TUSHORT:
642*74a4d8c2SCharles.Forsyth 			a = AMOVHU;
643*74a4d8c2SCharles.Forsyth 			break;
644*74a4d8c2SCharles.Forsyth 		case TFLOAT:
645*74a4d8c2SCharles.Forsyth 			a = AMOVF;
646*74a4d8c2SCharles.Forsyth 			break;
647*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
648*74a4d8c2SCharles.Forsyth 			a = AMOVD;
649*74a4d8c2SCharles.Forsyth 			break;
650*74a4d8c2SCharles.Forsyth 		case TUVLONG:
651*74a4d8c2SCharles.Forsyth 		case TVLONG:
652*74a4d8c2SCharles.Forsyth 			a = AMOVV;
653*74a4d8c2SCharles.Forsyth 			break;
654*74a4d8c2SCharles.Forsyth 		}
655*74a4d8c2SCharles.Forsyth 		if(typechlp[ft] && typeilp[tt])
656*74a4d8c2SCharles.Forsyth 			regalloc(&nod, t, t);
657*74a4d8c2SCharles.Forsyth 		else
658*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, t);
659*74a4d8c2SCharles.Forsyth 		gins(a, f, &nod);
660*74a4d8c2SCharles.Forsyth 		gmove(&nod, t);
661*74a4d8c2SCharles.Forsyth 		regfree(&nod);
662*74a4d8c2SCharles.Forsyth 		return;
663*74a4d8c2SCharles.Forsyth 	}
664*74a4d8c2SCharles.Forsyth 
665*74a4d8c2SCharles.Forsyth 	/*
666*74a4d8c2SCharles.Forsyth 	 * a store --
667*74a4d8c2SCharles.Forsyth 	 * put it into a register then
668*74a4d8c2SCharles.Forsyth 	 * store it.
669*74a4d8c2SCharles.Forsyth 	 */
670*74a4d8c2SCharles.Forsyth 	if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
671*74a4d8c2SCharles.Forsyth 		switch(tt) {
672*74a4d8c2SCharles.Forsyth 		default:
673*74a4d8c2SCharles.Forsyth 			a = AMOVW;
674*74a4d8c2SCharles.Forsyth 			break;
675*74a4d8c2SCharles.Forsyth 		case TUCHAR:
676*74a4d8c2SCharles.Forsyth 			a = AMOVBU;
677*74a4d8c2SCharles.Forsyth 			break;
678*74a4d8c2SCharles.Forsyth 		case TCHAR:
679*74a4d8c2SCharles.Forsyth 			a = AMOVB;
680*74a4d8c2SCharles.Forsyth 			break;
681*74a4d8c2SCharles.Forsyth 		case TUSHORT:
682*74a4d8c2SCharles.Forsyth 			a = AMOVHU;
683*74a4d8c2SCharles.Forsyth 			break;
684*74a4d8c2SCharles.Forsyth 		case TSHORT:
685*74a4d8c2SCharles.Forsyth 			a = AMOVH;
686*74a4d8c2SCharles.Forsyth 			break;
687*74a4d8c2SCharles.Forsyth 		case TFLOAT:
688*74a4d8c2SCharles.Forsyth 			a = AMOVF;
689*74a4d8c2SCharles.Forsyth 			break;
690*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
691*74a4d8c2SCharles.Forsyth 			a = AMOVD;
692*74a4d8c2SCharles.Forsyth 			break;
693*74a4d8c2SCharles.Forsyth 		case TUVLONG:
694*74a4d8c2SCharles.Forsyth 		case TVLONG:
695*74a4d8c2SCharles.Forsyth 			a = AMOVV;
696*74a4d8c2SCharles.Forsyth 			break;
697*74a4d8c2SCharles.Forsyth 		}
698*74a4d8c2SCharles.Forsyth 		if(!typefd[ft] && vconst(f) == 0) {
699*74a4d8c2SCharles.Forsyth 			gins(a, f, t);
700*74a4d8c2SCharles.Forsyth 			return;
701*74a4d8c2SCharles.Forsyth 		}
702*74a4d8c2SCharles.Forsyth 		if(ft == tt)
703*74a4d8c2SCharles.Forsyth 			regalloc(&nod, t, f);
704*74a4d8c2SCharles.Forsyth 		else
705*74a4d8c2SCharles.Forsyth 			regalloc(&nod, t, Z);
706*74a4d8c2SCharles.Forsyth 		gmove(f, &nod);
707*74a4d8c2SCharles.Forsyth 		gins(a, &nod, t);
708*74a4d8c2SCharles.Forsyth 		regfree(&nod);
709*74a4d8c2SCharles.Forsyth 		return;
710*74a4d8c2SCharles.Forsyth 	}
711*74a4d8c2SCharles.Forsyth 
712*74a4d8c2SCharles.Forsyth 	/*
713*74a4d8c2SCharles.Forsyth 	 * type x type cross table
714*74a4d8c2SCharles.Forsyth 	 */
715*74a4d8c2SCharles.Forsyth 	a = AGOK;
716*74a4d8c2SCharles.Forsyth 	switch(ft) {
717*74a4d8c2SCharles.Forsyth 	case TUVLONG:
718*74a4d8c2SCharles.Forsyth 	case TVLONG:
719*74a4d8c2SCharles.Forsyth 		switch(tt) {
720*74a4d8c2SCharles.Forsyth 		case TUVLONG:
721*74a4d8c2SCharles.Forsyth 		case TVLONG:
722*74a4d8c2SCharles.Forsyth 			a = AMOVV;
723*74a4d8c2SCharles.Forsyth 			break;
724*74a4d8c2SCharles.Forsyth 		case TINT:
725*74a4d8c2SCharles.Forsyth 		case TUINT:
726*74a4d8c2SCharles.Forsyth 		case TLONG:
727*74a4d8c2SCharles.Forsyth 		case TULONG:
728*74a4d8c2SCharles.Forsyth 		case TIND:
729*74a4d8c2SCharles.Forsyth 		case TSHORT:
730*74a4d8c2SCharles.Forsyth 		case TUSHORT:
731*74a4d8c2SCharles.Forsyth 		case TCHAR:
732*74a4d8c2SCharles.Forsyth 		case TUCHAR:
733*74a4d8c2SCharles.Forsyth 			a = AMOVW;
734*74a4d8c2SCharles.Forsyth 			break;
735*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
736*74a4d8c2SCharles.Forsyth 			gins(AMOVW, f, t);
737*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
738*74a4d8c2SCharles.Forsyth 			if(ft == TULONG || ft == TUINT) {
739*74a4d8c2SCharles.Forsyth 				regalloc(&nod, t, Z);
740*74a4d8c2SCharles.Forsyth 				gins(ACMPGED, t, Z);
741*74a4d8c2SCharles.Forsyth 				p->reg = FREGZERO;
742*74a4d8c2SCharles.Forsyth 				gins(ABFPT, Z, Z);
743*74a4d8c2SCharles.Forsyth 				p1 = p;
744*74a4d8c2SCharles.Forsyth 				gins(AMOVD, nodfconst(4294967296.), &nod);
745*74a4d8c2SCharles.Forsyth 				gins(AADDD, &nod, t);
746*74a4d8c2SCharles.Forsyth 				patch(p1, pc);
747*74a4d8c2SCharles.Forsyth 				regfree(&nod);
748*74a4d8c2SCharles.Forsyth 			}
749*74a4d8c2SCharles.Forsyth 			return;
750*74a4d8c2SCharles.Forsyth 		case TFLOAT:
751*74a4d8c2SCharles.Forsyth 			gins(AMOVW, f, t);
752*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
753*74a4d8c2SCharles.Forsyth 			if(ft == TULONG || ft == TUINT) {
754*74a4d8c2SCharles.Forsyth 				regalloc(&nod, t, Z);
755*74a4d8c2SCharles.Forsyth 				gins(ACMPGEF, t, Z);
756*74a4d8c2SCharles.Forsyth 				p->reg = FREGZERO;
757*74a4d8c2SCharles.Forsyth 				gins(ABFPT, Z, Z);
758*74a4d8c2SCharles.Forsyth 				p1 = p;
759*74a4d8c2SCharles.Forsyth 				gins(AMOVF, nodfconst(4294967296.), &nod);
760*74a4d8c2SCharles.Forsyth 				gins(AADDF, &nod, t);
761*74a4d8c2SCharles.Forsyth 				patch(p1, pc);
762*74a4d8c2SCharles.Forsyth 				regfree(&nod);
763*74a4d8c2SCharles.Forsyth 			}
764*74a4d8c2SCharles.Forsyth 			return;
765*74a4d8c2SCharles.Forsyth 		}
766*74a4d8c2SCharles.Forsyth 		break;
767*74a4d8c2SCharles.Forsyth 	case TDOUBLE:
768*74a4d8c2SCharles.Forsyth 	case TFLOAT:
769*74a4d8c2SCharles.Forsyth 		switch(tt) {
770*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
771*74a4d8c2SCharles.Forsyth 			a = AMOVD;
772*74a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
773*74a4d8c2SCharles.Forsyth 				a = AMOVFD;
774*74a4d8c2SCharles.Forsyth 			break;
775*74a4d8c2SCharles.Forsyth 		case TFLOAT:
776*74a4d8c2SCharles.Forsyth 			a = AMOVDF;
777*74a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
778*74a4d8c2SCharles.Forsyth 				a = AMOVF;
779*74a4d8c2SCharles.Forsyth 			break;
780*74a4d8c2SCharles.Forsyth 		case TINT:
781*74a4d8c2SCharles.Forsyth 		case TUINT:
782*74a4d8c2SCharles.Forsyth 		case TLONG:
783*74a4d8c2SCharles.Forsyth 		case TULONG:
784*74a4d8c2SCharles.Forsyth 		case TIND:
785*74a4d8c2SCharles.Forsyth 		case TSHORT:
786*74a4d8c2SCharles.Forsyth 		case TUSHORT:
787*74a4d8c2SCharles.Forsyth 		case TCHAR:
788*74a4d8c2SCharles.Forsyth 		case TUCHAR:
789*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
790*74a4d8c2SCharles.Forsyth 			gins(ATRUNCDW, f, &nod);
791*74a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
792*74a4d8c2SCharles.Forsyth 				p->as = ATRUNCFW;
793*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
794*74a4d8c2SCharles.Forsyth 			regfree(&nod);
795*74a4d8c2SCharles.Forsyth 			return;
796*74a4d8c2SCharles.Forsyth 		case TUVLONG:
797*74a4d8c2SCharles.Forsyth 		case TVLONG:
798*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
799*74a4d8c2SCharles.Forsyth 			gins(ATRUNCDV, f, &nod);
800*74a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
801*74a4d8c2SCharles.Forsyth 				p->as = ATRUNCFV;
802*74a4d8c2SCharles.Forsyth 			gins(AMOVV, &nod, t);
803*74a4d8c2SCharles.Forsyth 			regfree(&nod);
804*74a4d8c2SCharles.Forsyth 			return;
805*74a4d8c2SCharles.Forsyth 		}
806*74a4d8c2SCharles.Forsyth 		break;
807*74a4d8c2SCharles.Forsyth 	case TINT:
808*74a4d8c2SCharles.Forsyth 	case TUINT:
809*74a4d8c2SCharles.Forsyth 	case TLONG:
810*74a4d8c2SCharles.Forsyth 	case TULONG:
811*74a4d8c2SCharles.Forsyth 	case TIND:
812*74a4d8c2SCharles.Forsyth 		switch(tt) {
813*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
814*74a4d8c2SCharles.Forsyth 			gins(AMOVW, f, t);
815*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
816*74a4d8c2SCharles.Forsyth 			if(ft == TULONG || ft == TUINT) {
817*74a4d8c2SCharles.Forsyth 				regalloc(&nod, t, Z);
818*74a4d8c2SCharles.Forsyth 				gins(ACMPGED, t, Z);
819*74a4d8c2SCharles.Forsyth 				p->reg = FREGZERO;
820*74a4d8c2SCharles.Forsyth 				gins(ABFPT, Z, Z);
821*74a4d8c2SCharles.Forsyth 				p1 = p;
822*74a4d8c2SCharles.Forsyth 				gins(AMOVD, nodfconst(4294967296.), &nod);
823*74a4d8c2SCharles.Forsyth 				gins(AADDD, &nod, t);
824*74a4d8c2SCharles.Forsyth 				patch(p1, pc);
825*74a4d8c2SCharles.Forsyth 				regfree(&nod);
826*74a4d8c2SCharles.Forsyth 			}
827*74a4d8c2SCharles.Forsyth 			return;
828*74a4d8c2SCharles.Forsyth 		case TFLOAT:
829*74a4d8c2SCharles.Forsyth 			gins(AMOVW, f, t);
830*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
831*74a4d8c2SCharles.Forsyth 			if(ft == TULONG || ft == TUINT) {
832*74a4d8c2SCharles.Forsyth 				regalloc(&nod, t, Z);
833*74a4d8c2SCharles.Forsyth 				gins(ACMPGEF, t, Z);
834*74a4d8c2SCharles.Forsyth 				p->reg = FREGZERO;
835*74a4d8c2SCharles.Forsyth 				gins(ABFPT, Z, Z);
836*74a4d8c2SCharles.Forsyth 				p1 = p;
837*74a4d8c2SCharles.Forsyth 				gins(AMOVF, nodfconst(4294967296.), &nod);
838*74a4d8c2SCharles.Forsyth 				gins(AADDF, &nod, t);
839*74a4d8c2SCharles.Forsyth 				patch(p1, pc);
840*74a4d8c2SCharles.Forsyth 				regfree(&nod);
841*74a4d8c2SCharles.Forsyth 			}
842*74a4d8c2SCharles.Forsyth 			return;
843*74a4d8c2SCharles.Forsyth 		case TUVLONG:
844*74a4d8c2SCharles.Forsyth 		case TVLONG:
845*74a4d8c2SCharles.Forsyth 			if(ft == TULONG || ft == TUINT) {
846*74a4d8c2SCharles.Forsyth 				a = AMOVWU;
847*74a4d8c2SCharles.Forsyth 				break;
848*74a4d8c2SCharles.Forsyth 			}
849*74a4d8c2SCharles.Forsyth 		case TINT:
850*74a4d8c2SCharles.Forsyth 		case TUINT:
851*74a4d8c2SCharles.Forsyth 		case TLONG:
852*74a4d8c2SCharles.Forsyth 		case TULONG:
853*74a4d8c2SCharles.Forsyth 		case TIND:
854*74a4d8c2SCharles.Forsyth 		case TSHORT:
855*74a4d8c2SCharles.Forsyth 		case TUSHORT:
856*74a4d8c2SCharles.Forsyth 		case TCHAR:
857*74a4d8c2SCharles.Forsyth 		case TUCHAR:
858*74a4d8c2SCharles.Forsyth 			a = AMOVW;
859*74a4d8c2SCharles.Forsyth 			break;
860*74a4d8c2SCharles.Forsyth 		}
861*74a4d8c2SCharles.Forsyth 		break;
862*74a4d8c2SCharles.Forsyth 	case TSHORT:
863*74a4d8c2SCharles.Forsyth 		switch(tt) {
864*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
865*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
866*74a4d8c2SCharles.Forsyth 			gins(AMOVH, f, &nod);
867*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
868*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
869*74a4d8c2SCharles.Forsyth 			regfree(&nod);
870*74a4d8c2SCharles.Forsyth 			return;
871*74a4d8c2SCharles.Forsyth 		case TFLOAT:
872*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
873*74a4d8c2SCharles.Forsyth 			gins(AMOVH, f, &nod);
874*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
875*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
876*74a4d8c2SCharles.Forsyth 			regfree(&nod);
877*74a4d8c2SCharles.Forsyth 			return;
878*74a4d8c2SCharles.Forsyth 		case TINT:
879*74a4d8c2SCharles.Forsyth 		case TUINT:
880*74a4d8c2SCharles.Forsyth 		case TLONG:
881*74a4d8c2SCharles.Forsyth 		case TULONG:
882*74a4d8c2SCharles.Forsyth 		case TVLONG:
883*74a4d8c2SCharles.Forsyth 		case TUVLONG:
884*74a4d8c2SCharles.Forsyth 		case TIND:
885*74a4d8c2SCharles.Forsyth 			a = AMOVH;
886*74a4d8c2SCharles.Forsyth 			break;
887*74a4d8c2SCharles.Forsyth 		case TSHORT:
888*74a4d8c2SCharles.Forsyth 		case TUSHORT:
889*74a4d8c2SCharles.Forsyth 		case TCHAR:
890*74a4d8c2SCharles.Forsyth 		case TUCHAR:
891*74a4d8c2SCharles.Forsyth 			a = AMOVW;
892*74a4d8c2SCharles.Forsyth 			break;
893*74a4d8c2SCharles.Forsyth 		}
894*74a4d8c2SCharles.Forsyth 		break;
895*74a4d8c2SCharles.Forsyth 	case TUSHORT:
896*74a4d8c2SCharles.Forsyth 		switch(tt) {
897*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
898*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
899*74a4d8c2SCharles.Forsyth 			gins(AMOVHU, f, &nod);
900*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
901*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
902*74a4d8c2SCharles.Forsyth 			regfree(&nod);
903*74a4d8c2SCharles.Forsyth 			return;
904*74a4d8c2SCharles.Forsyth 		case TFLOAT:
905*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
906*74a4d8c2SCharles.Forsyth 			gins(AMOVHU, f, &nod);
907*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
908*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
909*74a4d8c2SCharles.Forsyth 			regfree(&nod);
910*74a4d8c2SCharles.Forsyth 			return;
911*74a4d8c2SCharles.Forsyth 		case TINT:
912*74a4d8c2SCharles.Forsyth 		case TUINT:
913*74a4d8c2SCharles.Forsyth 		case TLONG:
914*74a4d8c2SCharles.Forsyth 		case TULONG:
915*74a4d8c2SCharles.Forsyth 		case TVLONG:
916*74a4d8c2SCharles.Forsyth 		case TUVLONG:
917*74a4d8c2SCharles.Forsyth 		case TIND:
918*74a4d8c2SCharles.Forsyth 			a = AMOVHU;
919*74a4d8c2SCharles.Forsyth 			break;
920*74a4d8c2SCharles.Forsyth 		case TSHORT:
921*74a4d8c2SCharles.Forsyth 		case TUSHORT:
922*74a4d8c2SCharles.Forsyth 		case TCHAR:
923*74a4d8c2SCharles.Forsyth 		case TUCHAR:
924*74a4d8c2SCharles.Forsyth 			a = AMOVW;
925*74a4d8c2SCharles.Forsyth 			break;
926*74a4d8c2SCharles.Forsyth 		}
927*74a4d8c2SCharles.Forsyth 		break;
928*74a4d8c2SCharles.Forsyth 	case TCHAR:
929*74a4d8c2SCharles.Forsyth 		switch(tt) {
930*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
931*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
932*74a4d8c2SCharles.Forsyth 			gins(AMOVB, f, &nod);
933*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
934*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
935*74a4d8c2SCharles.Forsyth 			regfree(&nod);
936*74a4d8c2SCharles.Forsyth 			return;
937*74a4d8c2SCharles.Forsyth 		case TFLOAT:
938*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
939*74a4d8c2SCharles.Forsyth 			gins(AMOVB, f, &nod);
940*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
941*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
942*74a4d8c2SCharles.Forsyth 			regfree(&nod);
943*74a4d8c2SCharles.Forsyth 			return;
944*74a4d8c2SCharles.Forsyth 		case TINT:
945*74a4d8c2SCharles.Forsyth 		case TUINT:
946*74a4d8c2SCharles.Forsyth 		case TLONG:
947*74a4d8c2SCharles.Forsyth 		case TULONG:
948*74a4d8c2SCharles.Forsyth 		case TVLONG:
949*74a4d8c2SCharles.Forsyth 		case TUVLONG:
950*74a4d8c2SCharles.Forsyth 		case TIND:
951*74a4d8c2SCharles.Forsyth 		case TSHORT:
952*74a4d8c2SCharles.Forsyth 		case TUSHORT:
953*74a4d8c2SCharles.Forsyth 			a = AMOVB;
954*74a4d8c2SCharles.Forsyth 			break;
955*74a4d8c2SCharles.Forsyth 		case TCHAR:
956*74a4d8c2SCharles.Forsyth 		case TUCHAR:
957*74a4d8c2SCharles.Forsyth 			a = AMOVW;
958*74a4d8c2SCharles.Forsyth 			break;
959*74a4d8c2SCharles.Forsyth 		}
960*74a4d8c2SCharles.Forsyth 		break;
961*74a4d8c2SCharles.Forsyth 	case TUCHAR:
962*74a4d8c2SCharles.Forsyth 		switch(tt) {
963*74a4d8c2SCharles.Forsyth 		case TDOUBLE:
964*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
965*74a4d8c2SCharles.Forsyth 			gins(AMOVBU, f, &nod);
966*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
967*74a4d8c2SCharles.Forsyth 			gins(AMOVWD, t, t);
968*74a4d8c2SCharles.Forsyth 			regfree(&nod);
969*74a4d8c2SCharles.Forsyth 			return;
970*74a4d8c2SCharles.Forsyth 		case TFLOAT:
971*74a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
972*74a4d8c2SCharles.Forsyth 			gins(AMOVBU, f, &nod);
973*74a4d8c2SCharles.Forsyth 			gins(AMOVW, &nod, t);
974*74a4d8c2SCharles.Forsyth 			gins(AMOVWF, t, t);
975*74a4d8c2SCharles.Forsyth 			regfree(&nod);
976*74a4d8c2SCharles.Forsyth 			return;
977*74a4d8c2SCharles.Forsyth 		case TINT:
978*74a4d8c2SCharles.Forsyth 		case TUINT:
979*74a4d8c2SCharles.Forsyth 		case TLONG:
980*74a4d8c2SCharles.Forsyth 		case TULONG:
981*74a4d8c2SCharles.Forsyth 		case TVLONG:
982*74a4d8c2SCharles.Forsyth 		case TUVLONG:
983*74a4d8c2SCharles.Forsyth 		case TIND:
984*74a4d8c2SCharles.Forsyth 		case TSHORT:
985*74a4d8c2SCharles.Forsyth 		case TUSHORT:
986*74a4d8c2SCharles.Forsyth 			a = AMOVBU;
987*74a4d8c2SCharles.Forsyth 			break;
988*74a4d8c2SCharles.Forsyth 		case TCHAR:
989*74a4d8c2SCharles.Forsyth 		case TUCHAR:
990*74a4d8c2SCharles.Forsyth 			a = AMOVW;
991*74a4d8c2SCharles.Forsyth 			break;
992*74a4d8c2SCharles.Forsyth 		}
993*74a4d8c2SCharles.Forsyth 		break;
994*74a4d8c2SCharles.Forsyth 	}
995*74a4d8c2SCharles.Forsyth 	if(a == AGOK)
996*74a4d8c2SCharles.Forsyth 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
997*74a4d8c2SCharles.Forsyth 	if(a == AMOVW || a == AMOVF || a == AMOVD || a == AMOVV)
998*74a4d8c2SCharles.Forsyth 	if(samaddr(f, t))
999*74a4d8c2SCharles.Forsyth 		return;
1000*74a4d8c2SCharles.Forsyth 	gins(a, f, t);
1001*74a4d8c2SCharles.Forsyth }
1002*74a4d8c2SCharles.Forsyth 
1003*74a4d8c2SCharles.Forsyth void
gins(int a,Node * f,Node * t)1004*74a4d8c2SCharles.Forsyth gins(int a, Node *f, Node *t)
1005*74a4d8c2SCharles.Forsyth {
1006*74a4d8c2SCharles.Forsyth 
1007*74a4d8c2SCharles.Forsyth 	nextpc();
1008*74a4d8c2SCharles.Forsyth 	p->as = a;
1009*74a4d8c2SCharles.Forsyth 	if(f != Z)
1010*74a4d8c2SCharles.Forsyth 		naddr(f, &p->from);
1011*74a4d8c2SCharles.Forsyth 	if(t != Z)
1012*74a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
1013*74a4d8c2SCharles.Forsyth 	if(debug['g'])
1014*74a4d8c2SCharles.Forsyth 		print("%P\n", p);
1015*74a4d8c2SCharles.Forsyth }
1016*74a4d8c2SCharles.Forsyth 
1017*74a4d8c2SCharles.Forsyth void
gopcode(int o,Node * f1,Node * f2,Node * t)1018*74a4d8c2SCharles.Forsyth gopcode(int o, Node *f1, Node *f2, Node *t)
1019*74a4d8c2SCharles.Forsyth {
1020*74a4d8c2SCharles.Forsyth 	int a, et, ett;
1021*74a4d8c2SCharles.Forsyth 	Adr ta;
1022*74a4d8c2SCharles.Forsyth 	Node nod;
1023*74a4d8c2SCharles.Forsyth 
1024*74a4d8c2SCharles.Forsyth 	et = TLONG;
1025*74a4d8c2SCharles.Forsyth 	if(f1 != Z && f1->type != T)
1026*74a4d8c2SCharles.Forsyth 		et = f1->type->etype;
1027*74a4d8c2SCharles.Forsyth 	ett = TLONG;
1028*74a4d8c2SCharles.Forsyth 	if(t != Z && t->type != T)
1029*74a4d8c2SCharles.Forsyth 		ett = t->type->etype;
1030*74a4d8c2SCharles.Forsyth 	if(llconst(f1) && o != OAS) {
1031*74a4d8c2SCharles.Forsyth 		regalloc(&nod, f1, Z);
1032*74a4d8c2SCharles.Forsyth 		gmove(f1, &nod);
1033*74a4d8c2SCharles.Forsyth 		gopcode(o, &nod, f2, t);
1034*74a4d8c2SCharles.Forsyth 		regfree(&nod);
1035*74a4d8c2SCharles.Forsyth 		return;
1036*74a4d8c2SCharles.Forsyth 	}
1037*74a4d8c2SCharles.Forsyth 	a = AGOK;
1038*74a4d8c2SCharles.Forsyth 	switch(o) {
1039*74a4d8c2SCharles.Forsyth 	case OAS:
1040*74a4d8c2SCharles.Forsyth 		gmove(f1, t);
1041*74a4d8c2SCharles.Forsyth 		return;
1042*74a4d8c2SCharles.Forsyth 
1043*74a4d8c2SCharles.Forsyth 	case OASADD:
1044*74a4d8c2SCharles.Forsyth 	case OADD:
1045*74a4d8c2SCharles.Forsyth 		a = AADDU;
1046*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1047*74a4d8c2SCharles.Forsyth 			a = AADDVU;
1048*74a4d8c2SCharles.Forsyth 		else
1049*74a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
1050*74a4d8c2SCharles.Forsyth 			a = AADDF;
1051*74a4d8c2SCharles.Forsyth 		else
1052*74a4d8c2SCharles.Forsyth 		if(et == TDOUBLE)
1053*74a4d8c2SCharles.Forsyth 			a = AADDD;
1054*74a4d8c2SCharles.Forsyth 		break;
1055*74a4d8c2SCharles.Forsyth 
1056*74a4d8c2SCharles.Forsyth 	case OASSUB:
1057*74a4d8c2SCharles.Forsyth 	case OSUB:
1058*74a4d8c2SCharles.Forsyth 		a = ASUBU;
1059*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1060*74a4d8c2SCharles.Forsyth 			a = ASUBVU;
1061*74a4d8c2SCharles.Forsyth 		else
1062*74a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
1063*74a4d8c2SCharles.Forsyth 			a = ASUBF;
1064*74a4d8c2SCharles.Forsyth 		else
1065*74a4d8c2SCharles.Forsyth 		if(et == TDOUBLE)
1066*74a4d8c2SCharles.Forsyth 			a = ASUBD;
1067*74a4d8c2SCharles.Forsyth 		break;
1068*74a4d8c2SCharles.Forsyth 
1069*74a4d8c2SCharles.Forsyth 	case OASOR:
1070*74a4d8c2SCharles.Forsyth 	case OOR:
1071*74a4d8c2SCharles.Forsyth 		a = AOR;
1072*74a4d8c2SCharles.Forsyth 		break;
1073*74a4d8c2SCharles.Forsyth 
1074*74a4d8c2SCharles.Forsyth 	case OASAND:
1075*74a4d8c2SCharles.Forsyth 	case OAND:
1076*74a4d8c2SCharles.Forsyth 		a = AAND;
1077*74a4d8c2SCharles.Forsyth 		break;
1078*74a4d8c2SCharles.Forsyth 
1079*74a4d8c2SCharles.Forsyth 	case OASXOR:
1080*74a4d8c2SCharles.Forsyth 	case OXOR:
1081*74a4d8c2SCharles.Forsyth 		a = AXOR;
1082*74a4d8c2SCharles.Forsyth 		break;
1083*74a4d8c2SCharles.Forsyth 
1084*74a4d8c2SCharles.Forsyth 	case OASLSHR:
1085*74a4d8c2SCharles.Forsyth 	case OLSHR:
1086*74a4d8c2SCharles.Forsyth 		a = ASRL;
1087*74a4d8c2SCharles.Forsyth 		if(ett == TVLONG || ett == TUVLONG)
1088*74a4d8c2SCharles.Forsyth 			a = ASRLV;
1089*74a4d8c2SCharles.Forsyth 		break;
1090*74a4d8c2SCharles.Forsyth 
1091*74a4d8c2SCharles.Forsyth 	case OASASHR:
1092*74a4d8c2SCharles.Forsyth 	case OASHR:
1093*74a4d8c2SCharles.Forsyth 		a = ASRA;
1094*74a4d8c2SCharles.Forsyth 		if(ett == TVLONG || ett == TUVLONG)
1095*74a4d8c2SCharles.Forsyth 			a = ASRAV;
1096*74a4d8c2SCharles.Forsyth 		break;
1097*74a4d8c2SCharles.Forsyth 
1098*74a4d8c2SCharles.Forsyth 	case OASASHL:
1099*74a4d8c2SCharles.Forsyth 	case OASHL:
1100*74a4d8c2SCharles.Forsyth 		a = ASLL;
1101*74a4d8c2SCharles.Forsyth 		if(ett == TVLONG || ett == TUVLONG)
1102*74a4d8c2SCharles.Forsyth 			a = ASLLV;
1103*74a4d8c2SCharles.Forsyth 		break;
1104*74a4d8c2SCharles.Forsyth 
1105*74a4d8c2SCharles.Forsyth 	case OFUNC:
1106*74a4d8c2SCharles.Forsyth 		a = AJAL;
1107*74a4d8c2SCharles.Forsyth 		break;
1108*74a4d8c2SCharles.Forsyth 
1109*74a4d8c2SCharles.Forsyth 	case OCOND:
1110*74a4d8c2SCharles.Forsyth 		a = ASGTU;
1111*74a4d8c2SCharles.Forsyth 		break;
1112*74a4d8c2SCharles.Forsyth 
1113*74a4d8c2SCharles.Forsyth 	case OCOMMA:
1114*74a4d8c2SCharles.Forsyth 		a = ASGT;
1115*74a4d8c2SCharles.Forsyth 		break;
1116*74a4d8c2SCharles.Forsyth 
1117*74a4d8c2SCharles.Forsyth 	case OASMUL:
1118*74a4d8c2SCharles.Forsyth 	case OMUL:
1119*74a4d8c2SCharles.Forsyth 		if(et == TFLOAT) {
1120*74a4d8c2SCharles.Forsyth 			a = AMULF;
1121*74a4d8c2SCharles.Forsyth 			break;
1122*74a4d8c2SCharles.Forsyth 		} else
1123*74a4d8c2SCharles.Forsyth 		if(et == TDOUBLE) {
1124*74a4d8c2SCharles.Forsyth 			a = AMULD;
1125*74a4d8c2SCharles.Forsyth 			break;
1126*74a4d8c2SCharles.Forsyth 		}
1127*74a4d8c2SCharles.Forsyth 		a = AMUL;
1128*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1129*74a4d8c2SCharles.Forsyth 			a = AMULV;
1130*74a4d8c2SCharles.Forsyth 		goto muldiv;
1131*74a4d8c2SCharles.Forsyth 
1132*74a4d8c2SCharles.Forsyth 	case OASDIV:
1133*74a4d8c2SCharles.Forsyth 	case ODIV:
1134*74a4d8c2SCharles.Forsyth 		if(et == TFLOAT) {
1135*74a4d8c2SCharles.Forsyth 			a = ADIVF;
1136*74a4d8c2SCharles.Forsyth 			break;
1137*74a4d8c2SCharles.Forsyth 		} else
1138*74a4d8c2SCharles.Forsyth 		if(et == TDOUBLE) {
1139*74a4d8c2SCharles.Forsyth 			a = ADIVD;
1140*74a4d8c2SCharles.Forsyth 			break;
1141*74a4d8c2SCharles.Forsyth 		}
1142*74a4d8c2SCharles.Forsyth 		a = ADIV;
1143*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1144*74a4d8c2SCharles.Forsyth 			a = ADIVV;
1145*74a4d8c2SCharles.Forsyth 		goto muldiv;
1146*74a4d8c2SCharles.Forsyth 
1147*74a4d8c2SCharles.Forsyth 	case OASMOD:
1148*74a4d8c2SCharles.Forsyth 	case OMOD:
1149*74a4d8c2SCharles.Forsyth 		a = ADIV;
1150*74a4d8c2SCharles.Forsyth 		o = OMOD;
1151*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1152*74a4d8c2SCharles.Forsyth 			a = ADIVV;
1153*74a4d8c2SCharles.Forsyth 		goto muldiv;
1154*74a4d8c2SCharles.Forsyth 
1155*74a4d8c2SCharles.Forsyth 	case OASLMUL:
1156*74a4d8c2SCharles.Forsyth 	case OLMUL:
1157*74a4d8c2SCharles.Forsyth 		a = AMULU;
1158*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1159*74a4d8c2SCharles.Forsyth 			a = AMULVU;
1160*74a4d8c2SCharles.Forsyth 		goto muldiv;
1161*74a4d8c2SCharles.Forsyth 
1162*74a4d8c2SCharles.Forsyth 	case OASLMOD:
1163*74a4d8c2SCharles.Forsyth 	case OLMOD:
1164*74a4d8c2SCharles.Forsyth 		o = OMOD;
1165*74a4d8c2SCharles.Forsyth 
1166*74a4d8c2SCharles.Forsyth 	case OASLDIV:
1167*74a4d8c2SCharles.Forsyth 	case OLDIV:
1168*74a4d8c2SCharles.Forsyth 		a = ADIVU;
1169*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1170*74a4d8c2SCharles.Forsyth 			a = ADIVVU;
1171*74a4d8c2SCharles.Forsyth 		goto muldiv;
1172*74a4d8c2SCharles.Forsyth 
1173*74a4d8c2SCharles.Forsyth 	muldiv:
1174*74a4d8c2SCharles.Forsyth 		nextpc();
1175*74a4d8c2SCharles.Forsyth 		naddr(f1, &p->from);
1176*74a4d8c2SCharles.Forsyth 		if(f2 == Z)
1177*74a4d8c2SCharles.Forsyth 			raddr(t, p);
1178*74a4d8c2SCharles.Forsyth 		else
1179*74a4d8c2SCharles.Forsyth 			raddr(f2, p);
1180*74a4d8c2SCharles.Forsyth 		p->as = a;
1181*74a4d8c2SCharles.Forsyth 		if(debug['g'])
1182*74a4d8c2SCharles.Forsyth 			print("%P\n", p);
1183*74a4d8c2SCharles.Forsyth 		nextpc();
1184*74a4d8c2SCharles.Forsyth 		p->as = AMOVW;
1185*74a4d8c2SCharles.Forsyth 		if(et == TVLONG || et == TUVLONG)
1186*74a4d8c2SCharles.Forsyth 			p->as = AMOVV;
1187*74a4d8c2SCharles.Forsyth 		a = D_LO;
1188*74a4d8c2SCharles.Forsyth 		if(o == OMOD)
1189*74a4d8c2SCharles.Forsyth 			a = D_HI;
1190*74a4d8c2SCharles.Forsyth 		p->from.type = a;
1191*74a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
1192*74a4d8c2SCharles.Forsyth 		if(debug['g'])
1193*74a4d8c2SCharles.Forsyth 			print("%P\n", p);
1194*74a4d8c2SCharles.Forsyth 		return;
1195*74a4d8c2SCharles.Forsyth 
1196*74a4d8c2SCharles.Forsyth 	case OEQ:
1197*74a4d8c2SCharles.Forsyth 		if(!typefd[et]) {
1198*74a4d8c2SCharles.Forsyth 			a = ABEQ;
1199*74a4d8c2SCharles.Forsyth 			break;
1200*74a4d8c2SCharles.Forsyth 		}
1201*74a4d8c2SCharles.Forsyth 
1202*74a4d8c2SCharles.Forsyth 	case ONE:
1203*74a4d8c2SCharles.Forsyth 		if(!typefd[et]) {
1204*74a4d8c2SCharles.Forsyth 			a = ABNE;
1205*74a4d8c2SCharles.Forsyth 			break;
1206*74a4d8c2SCharles.Forsyth 		}
1207*74a4d8c2SCharles.Forsyth 
1208*74a4d8c2SCharles.Forsyth 	case OLT:
1209*74a4d8c2SCharles.Forsyth 	case OLE:
1210*74a4d8c2SCharles.Forsyth 	case OGE:
1211*74a4d8c2SCharles.Forsyth 	case OGT:
1212*74a4d8c2SCharles.Forsyth 		if(typefd[et]) {
1213*74a4d8c2SCharles.Forsyth 			nextpc();
1214*74a4d8c2SCharles.Forsyth 			if(et == TFLOAT) {
1215*74a4d8c2SCharles.Forsyth 				a = ACMPGTF;
1216*74a4d8c2SCharles.Forsyth 				if(o == OEQ || o == ONE)
1217*74a4d8c2SCharles.Forsyth 					a = ACMPEQF;
1218*74a4d8c2SCharles.Forsyth 				else
1219*74a4d8c2SCharles.Forsyth 				if(o == OLT || o == OGE)
1220*74a4d8c2SCharles.Forsyth 					a = ACMPGEF;
1221*74a4d8c2SCharles.Forsyth 			} else {
1222*74a4d8c2SCharles.Forsyth 				a = ACMPGTD;
1223*74a4d8c2SCharles.Forsyth 				if(o == OEQ || o == ONE)
1224*74a4d8c2SCharles.Forsyth 					a = ACMPEQD;
1225*74a4d8c2SCharles.Forsyth 				else
1226*74a4d8c2SCharles.Forsyth 				if(o == OLT || o == OGE)
1227*74a4d8c2SCharles.Forsyth 					a = ACMPGED;
1228*74a4d8c2SCharles.Forsyth 			}
1229*74a4d8c2SCharles.Forsyth 			p->as = a;
1230*74a4d8c2SCharles.Forsyth 			naddr(f1, &p->from);
1231*74a4d8c2SCharles.Forsyth 			raddr(f2, p);
1232*74a4d8c2SCharles.Forsyth 			if(debug['g'])
1233*74a4d8c2SCharles.Forsyth 				print("%P\n", p);
1234*74a4d8c2SCharles.Forsyth 			nextpc();
1235*74a4d8c2SCharles.Forsyth 			a = ABFPF;
1236*74a4d8c2SCharles.Forsyth 			if(o == OEQ || o == OGE || o == OGT)
1237*74a4d8c2SCharles.Forsyth 				a = ABFPT;
1238*74a4d8c2SCharles.Forsyth 			p->as = a;
1239*74a4d8c2SCharles.Forsyth 			if(debug['g'])
1240*74a4d8c2SCharles.Forsyth 				print("%P\n", p);
1241*74a4d8c2SCharles.Forsyth 			return;
1242*74a4d8c2SCharles.Forsyth 		}
1243*74a4d8c2SCharles.Forsyth 		if(vconst(f1) == 0 || vconst(f2) == 0) {
1244*74a4d8c2SCharles.Forsyth 			if(vconst(f1) == 0) {
1245*74a4d8c2SCharles.Forsyth 				o = invrel[relindex(o)];
1246*74a4d8c2SCharles.Forsyth 				f1 = f2;
1247*74a4d8c2SCharles.Forsyth 			}
1248*74a4d8c2SCharles.Forsyth 			switch(o) {
1249*74a4d8c2SCharles.Forsyth 			case OLT:
1250*74a4d8c2SCharles.Forsyth 				a = ABLTZ;
1251*74a4d8c2SCharles.Forsyth 				break;
1252*74a4d8c2SCharles.Forsyth 			case OLE:
1253*74a4d8c2SCharles.Forsyth 				a = ABLEZ;
1254*74a4d8c2SCharles.Forsyth 				break;
1255*74a4d8c2SCharles.Forsyth 			case OGE:
1256*74a4d8c2SCharles.Forsyth 				a = ABGEZ;
1257*74a4d8c2SCharles.Forsyth 				break;
1258*74a4d8c2SCharles.Forsyth 			case OGT:
1259*74a4d8c2SCharles.Forsyth 				a = ABGTZ;
1260*74a4d8c2SCharles.Forsyth 				break;
1261*74a4d8c2SCharles.Forsyth 			}
1262*74a4d8c2SCharles.Forsyth 			f2 = Z;
1263*74a4d8c2SCharles.Forsyth 			break;
1264*74a4d8c2SCharles.Forsyth 		}
1265*74a4d8c2SCharles.Forsyth 
1266*74a4d8c2SCharles.Forsyth 	case OLO:
1267*74a4d8c2SCharles.Forsyth 	case OLS:
1268*74a4d8c2SCharles.Forsyth 	case OHS:
1269*74a4d8c2SCharles.Forsyth 	case OHI:
1270*74a4d8c2SCharles.Forsyth 		nextpc();
1271*74a4d8c2SCharles.Forsyth 		if(o == OLE || o == OGT || o == OLS || o == OHI) {
1272*74a4d8c2SCharles.Forsyth 			naddr(f1, &p->from);
1273*74a4d8c2SCharles.Forsyth 			raddr(f2, p);
1274*74a4d8c2SCharles.Forsyth 		} else {
1275*74a4d8c2SCharles.Forsyth 			naddr(f2, &p->from);
1276*74a4d8c2SCharles.Forsyth 			raddr(f1, p);
1277*74a4d8c2SCharles.Forsyth 		}
1278*74a4d8c2SCharles.Forsyth 		naddr(&regnode, &p->to);
1279*74a4d8c2SCharles.Forsyth 		p->to.reg = tmpreg();
1280*74a4d8c2SCharles.Forsyth 		a = ASGT;
1281*74a4d8c2SCharles.Forsyth 		if(o == OLO || o == OLS || o == OHS || o == OHI)
1282*74a4d8c2SCharles.Forsyth 			a = ASGTU;
1283*74a4d8c2SCharles.Forsyth 		p->as = a;
1284*74a4d8c2SCharles.Forsyth 		if(debug['g'])
1285*74a4d8c2SCharles.Forsyth 			print("%P\n", p);
1286*74a4d8c2SCharles.Forsyth 
1287*74a4d8c2SCharles.Forsyth 		nextpc();
1288*74a4d8c2SCharles.Forsyth 		naddr(&regnode, &p->from);
1289*74a4d8c2SCharles.Forsyth 		p->from.reg = tmpreg();
1290*74a4d8c2SCharles.Forsyth 		a = ABEQ;
1291*74a4d8c2SCharles.Forsyth 		if(o == OLT || o == OGT || o == OLO || o == OHI)
1292*74a4d8c2SCharles.Forsyth 			a = ABNE;
1293*74a4d8c2SCharles.Forsyth 		p->as = a;
1294*74a4d8c2SCharles.Forsyth 		if(debug['g'])
1295*74a4d8c2SCharles.Forsyth 			print("%P\n", p);
1296*74a4d8c2SCharles.Forsyth 		return;
1297*74a4d8c2SCharles.Forsyth 	}
1298*74a4d8c2SCharles.Forsyth 	if(a == AGOK)
1299*74a4d8c2SCharles.Forsyth 		diag(Z, "bad in gopcode %O", o);
1300*74a4d8c2SCharles.Forsyth 	nextpc();
1301*74a4d8c2SCharles.Forsyth 	p->as = a;
1302*74a4d8c2SCharles.Forsyth 	if(f1 != Z)
1303*74a4d8c2SCharles.Forsyth 		naddr(f1, &p->from);
1304*74a4d8c2SCharles.Forsyth 	if(f2 != Z) {
1305*74a4d8c2SCharles.Forsyth 		naddr(f2, &ta);
1306*74a4d8c2SCharles.Forsyth 		p->reg = ta.reg;
1307*74a4d8c2SCharles.Forsyth 		if(ta.type == D_CONST && ta.offset == 0)
1308*74a4d8c2SCharles.Forsyth 			p->reg = REGZERO;
1309*74a4d8c2SCharles.Forsyth 	}
1310*74a4d8c2SCharles.Forsyth 	if(t != Z)
1311*74a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
1312*74a4d8c2SCharles.Forsyth 	if(debug['g'])
1313*74a4d8c2SCharles.Forsyth 		print("%P\n", p);
1314*74a4d8c2SCharles.Forsyth }
1315*74a4d8c2SCharles.Forsyth 
1316*74a4d8c2SCharles.Forsyth int
samaddr(Node * f,Node * t)1317*74a4d8c2SCharles.Forsyth samaddr(Node *f, Node *t)
1318*74a4d8c2SCharles.Forsyth {
1319*74a4d8c2SCharles.Forsyth 
1320*74a4d8c2SCharles.Forsyth 	if(f->op != t->op)
1321*74a4d8c2SCharles.Forsyth 		return 0;
1322*74a4d8c2SCharles.Forsyth 	switch(f->op) {
1323*74a4d8c2SCharles.Forsyth 
1324*74a4d8c2SCharles.Forsyth 	case OREGISTER:
1325*74a4d8c2SCharles.Forsyth 		if(f->reg != t->reg)
1326*74a4d8c2SCharles.Forsyth 			break;
1327*74a4d8c2SCharles.Forsyth 		return 1;
1328*74a4d8c2SCharles.Forsyth 	}
1329*74a4d8c2SCharles.Forsyth 	return 0;
1330*74a4d8c2SCharles.Forsyth }
1331*74a4d8c2SCharles.Forsyth 
1332*74a4d8c2SCharles.Forsyth void
gbranch(int o)1333*74a4d8c2SCharles.Forsyth gbranch(int o)
1334*74a4d8c2SCharles.Forsyth {
1335*74a4d8c2SCharles.Forsyth 	int a;
1336*74a4d8c2SCharles.Forsyth 
1337*74a4d8c2SCharles.Forsyth 	a = AGOK;
1338*74a4d8c2SCharles.Forsyth 	switch(o) {
1339*74a4d8c2SCharles.Forsyth 	case ORETURN:
1340*74a4d8c2SCharles.Forsyth 		a = ARET;
1341*74a4d8c2SCharles.Forsyth 		break;
1342*74a4d8c2SCharles.Forsyth 	case OGOTO:
1343*74a4d8c2SCharles.Forsyth 		a = AJMP;
1344*74a4d8c2SCharles.Forsyth 		break;
1345*74a4d8c2SCharles.Forsyth 	}
1346*74a4d8c2SCharles.Forsyth 	nextpc();
1347*74a4d8c2SCharles.Forsyth 	if(a == AGOK) {
1348*74a4d8c2SCharles.Forsyth 		diag(Z, "bad in gbranch %O",  o);
1349*74a4d8c2SCharles.Forsyth 		nextpc();
1350*74a4d8c2SCharles.Forsyth 	}
1351*74a4d8c2SCharles.Forsyth 	p->as = a;
1352*74a4d8c2SCharles.Forsyth }
1353*74a4d8c2SCharles.Forsyth 
1354*74a4d8c2SCharles.Forsyth void
patch(Prog * op,long pc)1355*74a4d8c2SCharles.Forsyth patch(Prog *op, long pc)
1356*74a4d8c2SCharles.Forsyth {
1357*74a4d8c2SCharles.Forsyth 
1358*74a4d8c2SCharles.Forsyth 	op->to.offset = pc;
1359*74a4d8c2SCharles.Forsyth 	op->to.type = D_BRANCH;
1360*74a4d8c2SCharles.Forsyth }
1361*74a4d8c2SCharles.Forsyth 
1362*74a4d8c2SCharles.Forsyth void
gpseudo(int a,Sym * s,Node * n)1363*74a4d8c2SCharles.Forsyth gpseudo(int a, Sym *s, Node *n)
1364*74a4d8c2SCharles.Forsyth {
1365*74a4d8c2SCharles.Forsyth 
1366*74a4d8c2SCharles.Forsyth 	nextpc();
1367*74a4d8c2SCharles.Forsyth 	p->as = a;
1368*74a4d8c2SCharles.Forsyth 	p->from.type = D_OREG;
1369*74a4d8c2SCharles.Forsyth 	p->from.sym = s;
1370*74a4d8c2SCharles.Forsyth 	p->from.name = D_EXTERN;
1371*74a4d8c2SCharles.Forsyth 	if(s->class == CSTATIC)
1372*74a4d8c2SCharles.Forsyth 		p->from.name = D_STATIC;
1373*74a4d8c2SCharles.Forsyth 	naddr(n, &p->to);
1374*74a4d8c2SCharles.Forsyth 	if(a == ADATA || a == AGLOBL)
1375*74a4d8c2SCharles.Forsyth 		pc--;
1376*74a4d8c2SCharles.Forsyth }
1377*74a4d8c2SCharles.Forsyth 
1378*74a4d8c2SCharles.Forsyth int
sconst(Node * n)1379*74a4d8c2SCharles.Forsyth sconst(Node *n)
1380*74a4d8c2SCharles.Forsyth {
1381*74a4d8c2SCharles.Forsyth 	vlong vv;
1382*74a4d8c2SCharles.Forsyth 
1383*74a4d8c2SCharles.Forsyth 	if(n->op == OCONST) {
1384*74a4d8c2SCharles.Forsyth 		if(!typefd[n->type->etype]) {
1385*74a4d8c2SCharles.Forsyth 			vv = n->vconst;
1386*74a4d8c2SCharles.Forsyth 			if(vv >= (vlong)-32766 && vv < (vlong)32766)
1387*74a4d8c2SCharles.Forsyth 				return 1;
1388*74a4d8c2SCharles.Forsyth 		}
1389*74a4d8c2SCharles.Forsyth 	}
1390*74a4d8c2SCharles.Forsyth 	return 0;
1391*74a4d8c2SCharles.Forsyth }
1392*74a4d8c2SCharles.Forsyth 
1393*74a4d8c2SCharles.Forsyth int
llconst(Node * n)1394*74a4d8c2SCharles.Forsyth llconst(Node *n)
1395*74a4d8c2SCharles.Forsyth {
1396*74a4d8c2SCharles.Forsyth 	vlong vv;
1397*74a4d8c2SCharles.Forsyth 
1398*74a4d8c2SCharles.Forsyth 	if(n != Z && n->op == OCONST) {
1399*74a4d8c2SCharles.Forsyth 		if(typev[n->type->etype]) {
1400*74a4d8c2SCharles.Forsyth 			vv = n->vconst >> 32;
1401*74a4d8c2SCharles.Forsyth 			if(vv != 0 && vv != -1)
1402*74a4d8c2SCharles.Forsyth 				return 1;
1403*74a4d8c2SCharles.Forsyth 		}
1404*74a4d8c2SCharles.Forsyth 	}
1405*74a4d8c2SCharles.Forsyth 	return 0;
1406*74a4d8c2SCharles.Forsyth }
1407*74a4d8c2SCharles.Forsyth 
1408*74a4d8c2SCharles.Forsyth int
sval(long v)1409*74a4d8c2SCharles.Forsyth sval(long v)
1410*74a4d8c2SCharles.Forsyth {
1411*74a4d8c2SCharles.Forsyth 	if(v >= -32766L && v < 32766L)
1412*74a4d8c2SCharles.Forsyth 		return 1;
1413*74a4d8c2SCharles.Forsyth 	return 0;
1414*74a4d8c2SCharles.Forsyth }
1415*74a4d8c2SCharles.Forsyth 
1416*74a4d8c2SCharles.Forsyth long
exreg(Type * t)1417*74a4d8c2SCharles.Forsyth exreg(Type *t)
1418*74a4d8c2SCharles.Forsyth {
1419*74a4d8c2SCharles.Forsyth 	long o;
1420*74a4d8c2SCharles.Forsyth 
1421*74a4d8c2SCharles.Forsyth 	if(typechlp[t->etype]) {
1422*74a4d8c2SCharles.Forsyth 		if(exregoffset <= 16)
1423*74a4d8c2SCharles.Forsyth 			return 0;
1424*74a4d8c2SCharles.Forsyth 		o = exregoffset;
1425*74a4d8c2SCharles.Forsyth 		exregoffset--;
1426*74a4d8c2SCharles.Forsyth 		return o;
1427*74a4d8c2SCharles.Forsyth 	}
1428*74a4d8c2SCharles.Forsyth 	if(typefd[t->etype]) {
1429*74a4d8c2SCharles.Forsyth 		if(exfregoffset <= 16)
1430*74a4d8c2SCharles.Forsyth 			return 0;
1431*74a4d8c2SCharles.Forsyth 		o = exfregoffset + NREG;
1432*74a4d8c2SCharles.Forsyth 		exfregoffset--;
1433*74a4d8c2SCharles.Forsyth 		return o;
1434*74a4d8c2SCharles.Forsyth 	}
1435*74a4d8c2SCharles.Forsyth 	return 0;
1436*74a4d8c2SCharles.Forsyth }
1437*74a4d8c2SCharles.Forsyth 
1438*74a4d8c2SCharles.Forsyth schar	ewidth[NTYPE] =
1439*74a4d8c2SCharles.Forsyth {
1440*74a4d8c2SCharles.Forsyth 	-1,		/*[TXXX]*/
1441*74a4d8c2SCharles.Forsyth 	SZ_CHAR,	/*[TCHAR]*/
1442*74a4d8c2SCharles.Forsyth 	SZ_CHAR,	/*[TUCHAR]*/
1443*74a4d8c2SCharles.Forsyth 	SZ_SHORT,	/*[TSHORT]*/
1444*74a4d8c2SCharles.Forsyth 	SZ_SHORT,	/*[TUSHORT]*/
1445*74a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TINT]*/
1446*74a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TUINT]*/
1447*74a4d8c2SCharles.Forsyth 	SZ_LONG,	/*[TLONG]*/
1448*74a4d8c2SCharles.Forsyth 	SZ_LONG,	/*[TULONG]*/
1449*74a4d8c2SCharles.Forsyth 	SZ_VLONG,	/*[TVLONG]*/
1450*74a4d8c2SCharles.Forsyth 	SZ_VLONG,	/*[TUVLONG]*/
1451*74a4d8c2SCharles.Forsyth 	SZ_FLOAT,	/*[TFLOAT]*/
1452*74a4d8c2SCharles.Forsyth 	SZ_DOUBLE,	/*[TDOUBLE]*/
1453*74a4d8c2SCharles.Forsyth 	SZ_IND,		/*[TIND]*/
1454*74a4d8c2SCharles.Forsyth 	0,		/*[TFUNC]*/
1455*74a4d8c2SCharles.Forsyth 	-1,		/*[TARRAY]*/
1456*74a4d8c2SCharles.Forsyth 	0,		/*[TVOID]*/
1457*74a4d8c2SCharles.Forsyth 	-1,		/*[TSTRUCT]*/
1458*74a4d8c2SCharles.Forsyth 	-1,		/*[TUNION]*/
1459*74a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TENUM]*/
1460*74a4d8c2SCharles.Forsyth };
1461*74a4d8c2SCharles.Forsyth long	ncast[NTYPE] =
1462*74a4d8c2SCharles.Forsyth {
1463*74a4d8c2SCharles.Forsyth 	0,				/*[TXXX]*/
1464*74a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/*[TCHAR]*/
1465*74a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/*[TUCHAR]*/
1466*74a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/*[TSHORT]*/
1467*74a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/*[TUSHORT]*/
1468*74a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TINT]*/
1469*74a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TUINT]*/
1470*74a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TLONG]*/
1471*74a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TULONG]*/
1472*74a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/*[TVLONG]*/
1473*74a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/*[TUVLONG]*/
1474*74a4d8c2SCharles.Forsyth 	BFLOAT,				/*[TFLOAT]*/
1475*74a4d8c2SCharles.Forsyth 	BDOUBLE,			/*[TDOUBLE]*/
1476*74a4d8c2SCharles.Forsyth 	BLONG|BULONG|BIND,		/*[TIND]*/
1477*74a4d8c2SCharles.Forsyth 	0,				/*[TFUNC]*/
1478*74a4d8c2SCharles.Forsyth 	0,				/*[TARRAY]*/
1479*74a4d8c2SCharles.Forsyth 	0,				/*[TVOID]*/
1480*74a4d8c2SCharles.Forsyth 	BSTRUCT,			/*[TSTRUCT]*/
1481*74a4d8c2SCharles.Forsyth 	BUNION,				/*[TUNION]*/
1482*74a4d8c2SCharles.Forsyth 	0,				/*[TENUM]*/
1483*74a4d8c2SCharles.Forsyth };
1484