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