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