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