13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier void
ginit(void)43e12c5d1SDavid du Colombier ginit(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier int i;
73e12c5d1SDavid du Colombier Type *t;
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier thechar = '8';
103e12c5d1SDavid du Colombier thestring = "386";
113e12c5d1SDavid du Colombier exregoffset = 0;
123e12c5d1SDavid du Colombier exfregoffset = 0;
133e12c5d1SDavid du Colombier listinit();
143e12c5d1SDavid du Colombier nstring = 0;
153e12c5d1SDavid du Colombier mnstring = 0;
163e12c5d1SDavid du Colombier nrathole = 0;
173e12c5d1SDavid du Colombier pc = 0;
183e12c5d1SDavid du Colombier breakpc = -1;
193e12c5d1SDavid du Colombier continpc = -1;
203e12c5d1SDavid du Colombier cases = C;
213e12c5d1SDavid du Colombier firstp = P;
223e12c5d1SDavid du Colombier lastp = P;
237dd7cddfSDavid du Colombier tfield = types[TLONG];
243e12c5d1SDavid du Colombier
25*3a276d32SDavid du Colombier typeswitch = typechlv;
26*3a276d32SDavid du Colombier
273e12c5d1SDavid du Colombier zprog.link = P;
283e12c5d1SDavid du Colombier zprog.as = AGOK;
293e12c5d1SDavid du Colombier zprog.from.type = D_NONE;
303e12c5d1SDavid du Colombier zprog.from.index = D_NONE;
313e12c5d1SDavid du Colombier zprog.from.scale = 0;
323e12c5d1SDavid du Colombier zprog.to = zprog.from;
333e12c5d1SDavid du Colombier
343e12c5d1SDavid du Colombier regnode.op = OREGISTER;
353e12c5d1SDavid du Colombier regnode.class = CEXREG;
363e12c5d1SDavid du Colombier regnode.reg = REGTMP;
373e12c5d1SDavid du Colombier regnode.complex = 0;
383e12c5d1SDavid du Colombier regnode.addable = 11;
393e12c5d1SDavid du Colombier regnode.type = types[TLONG];
403e12c5d1SDavid du Colombier
413e12c5d1SDavid du Colombier fregnode0 = regnode;
423e12c5d1SDavid du Colombier fregnode0.reg = D_F0;
433e12c5d1SDavid du Colombier fregnode0.type = types[TDOUBLE];
443e12c5d1SDavid du Colombier
453e12c5d1SDavid du Colombier fregnode1 = fregnode0;
463e12c5d1SDavid du Colombier fregnode1.reg = D_F0+1;
473e12c5d1SDavid du Colombier
483e12c5d1SDavid du Colombier constnode.op = OCONST;
493e12c5d1SDavid du Colombier constnode.class = CXXX;
503e12c5d1SDavid du Colombier constnode.complex = 0;
513e12c5d1SDavid du Colombier constnode.addable = 20;
523e12c5d1SDavid du Colombier constnode.type = types[TLONG];
533e12c5d1SDavid du Colombier
543e12c5d1SDavid du Colombier fconstnode.op = OCONST;
553e12c5d1SDavid du Colombier fconstnode.class = CXXX;
563e12c5d1SDavid du Colombier fconstnode.complex = 0;
573e12c5d1SDavid du Colombier fconstnode.addable = 20;
583e12c5d1SDavid du Colombier fconstnode.type = types[TDOUBLE];
593e12c5d1SDavid du Colombier
603e12c5d1SDavid du Colombier nodsafe = new(ONAME, Z, Z);
613e12c5d1SDavid du Colombier nodsafe->sym = slookup(".safe");
627dd7cddfSDavid du Colombier nodsafe->type = types[TINT];
637dd7cddfSDavid du Colombier nodsafe->etype = types[TINT]->etype;
643e12c5d1SDavid du Colombier nodsafe->class = CAUTO;
653e12c5d1SDavid du Colombier complex(nodsafe);
663e12c5d1SDavid du Colombier
673e12c5d1SDavid du Colombier t = typ(TARRAY, types[TCHAR]);
683e12c5d1SDavid du Colombier symrathole = slookup(".rathole");
693e12c5d1SDavid du Colombier symrathole->class = CGLOBL;
703e12c5d1SDavid du Colombier symrathole->type = t;
713e12c5d1SDavid du Colombier
723e12c5d1SDavid du Colombier nodrat = new(ONAME, Z, Z);
733e12c5d1SDavid du Colombier nodrat->sym = symrathole;
743e12c5d1SDavid du Colombier nodrat->type = types[TIND];
753e12c5d1SDavid du Colombier nodrat->etype = TVOID;
763e12c5d1SDavid du Colombier nodrat->class = CGLOBL;
773e12c5d1SDavid du Colombier complex(nodrat);
783e12c5d1SDavid du Colombier nodrat->type = t;
793e12c5d1SDavid du Colombier
803e12c5d1SDavid du Colombier nodret = new(ONAME, Z, Z);
813e12c5d1SDavid du Colombier nodret->sym = slookup(".ret");
823e12c5d1SDavid du Colombier nodret->type = types[TIND];
833e12c5d1SDavid du Colombier nodret->etype = TIND;
843e12c5d1SDavid du Colombier nodret->class = CPARAM;
853e12c5d1SDavid du Colombier nodret = new(OIND, nodret, Z);
863e12c5d1SDavid du Colombier complex(nodret);
873e12c5d1SDavid du Colombier
88219b2ee8SDavid du Colombier com64init();
89219b2ee8SDavid du Colombier
907dd7cddfSDavid du Colombier for(i=0; i<nelem(reg); i++) {
917dd7cddfSDavid du Colombier reg[i] = 1;
927dd7cddfSDavid du Colombier if(i >= D_AX && i <= D_DI && i != D_SP)
933e12c5d1SDavid du Colombier reg[i] = 0;
943e12c5d1SDavid du Colombier }
957dd7cddfSDavid du Colombier }
963e12c5d1SDavid du Colombier
973e12c5d1SDavid du Colombier void
gclean(void)983e12c5d1SDavid du Colombier gclean(void)
993e12c5d1SDavid du Colombier {
1003e12c5d1SDavid du Colombier int i;
1013e12c5d1SDavid du Colombier Sym *s;
1023e12c5d1SDavid du Colombier
1033e12c5d1SDavid du Colombier reg[D_SP]--;
1043e12c5d1SDavid du Colombier for(i=D_AX; i<=D_DI; i++)
1053e12c5d1SDavid du Colombier if(reg[i])
1063e12c5d1SDavid du Colombier diag(Z, "reg %R left allocated", i);
1073e12c5d1SDavid du Colombier while(mnstring)
1083e12c5d1SDavid du Colombier outstring("", 1L);
1093e12c5d1SDavid du Colombier symstring->type->width = nstring;
1103e12c5d1SDavid du Colombier symrathole->type->width = nrathole;
1113e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++)
1123e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
1133e12c5d1SDavid du Colombier if(s->type == T)
1143e12c5d1SDavid du Colombier continue;
1153e12c5d1SDavid du Colombier if(s->type->width == 0)
1163e12c5d1SDavid du Colombier continue;
1173e12c5d1SDavid du Colombier if(s->class != CGLOBL && s->class != CSTATIC)
1183e12c5d1SDavid du Colombier continue;
1193e12c5d1SDavid du Colombier if(s->type == types[TENUM])
1203e12c5d1SDavid du Colombier continue;
1213e12c5d1SDavid du Colombier gpseudo(AGLOBL, s, nodconst(s->type->width));
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier nextpc();
1243e12c5d1SDavid du Colombier p->as = AEND;
1253e12c5d1SDavid du Colombier outcode();
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier void
nextpc(void)1293e12c5d1SDavid du Colombier nextpc(void)
1303e12c5d1SDavid du Colombier {
1313e12c5d1SDavid du Colombier
1327dd7cddfSDavid du Colombier p = alloc(sizeof(*p));
1333e12c5d1SDavid du Colombier *p = zprog;
1343e12c5d1SDavid du Colombier p->lineno = nearln;
1353e12c5d1SDavid du Colombier pc++;
1363e12c5d1SDavid du Colombier if(firstp == P) {
1373e12c5d1SDavid du Colombier firstp = p;
1383e12c5d1SDavid du Colombier lastp = p;
1393e12c5d1SDavid du Colombier return;
1403e12c5d1SDavid du Colombier }
1413e12c5d1SDavid du Colombier lastp->link = p;
1423e12c5d1SDavid du Colombier lastp = p;
1433e12c5d1SDavid du Colombier }
1443e12c5d1SDavid du Colombier
1453e12c5d1SDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)1463e12c5d1SDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
1473e12c5d1SDavid du Colombier {
1483e12c5d1SDavid du Colombier long regs;
1493e12c5d1SDavid du Colombier Node fnxargs[20], *fnxp;
1503e12c5d1SDavid du Colombier
1513e12c5d1SDavid du Colombier regs = cursafe;
1523e12c5d1SDavid du Colombier
1533e12c5d1SDavid du Colombier fnxp = fnxargs;
1543e12c5d1SDavid du Colombier garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
1553e12c5d1SDavid du Colombier
1563e12c5d1SDavid du Colombier curarg = 0;
1573e12c5d1SDavid du Colombier fnxp = fnxargs;
1583e12c5d1SDavid du Colombier garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
1593e12c5d1SDavid du Colombier
1603e12c5d1SDavid du Colombier cursafe = regs;
1613e12c5d1SDavid du Colombier }
1623e12c5d1SDavid du Colombier
163d40255d8SDavid du Colombier int
nareg(int notbp)164d40255d8SDavid du Colombier nareg(int notbp)
1657dd7cddfSDavid du Colombier {
1667dd7cddfSDavid du Colombier int i, n;
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier n = 0;
1697dd7cddfSDavid du Colombier for(i=D_AX; i<=D_DI; i++)
1707dd7cddfSDavid du Colombier if(reg[i] == 0)
1717dd7cddfSDavid du Colombier n++;
172d40255d8SDavid du Colombier if(notbp && reg[D_BP] == 0)
173d40255d8SDavid du Colombier n--;
1747dd7cddfSDavid du Colombier return n;
1757dd7cddfSDavid du Colombier }
1767dd7cddfSDavid du Colombier
1773e12c5d1SDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)1783e12c5d1SDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
1793e12c5d1SDavid du Colombier {
1803e12c5d1SDavid du Colombier Node nod;
1813e12c5d1SDavid du Colombier
1823e12c5d1SDavid du Colombier if(n == Z)
1833e12c5d1SDavid du Colombier return;
1843e12c5d1SDavid du Colombier if(n->op == OLIST) {
1853e12c5d1SDavid du Colombier garg1(n->left, tn1, tn2, f, fnxp);
1863e12c5d1SDavid du Colombier garg1(n->right, tn1, tn2, f, fnxp);
1873e12c5d1SDavid du Colombier return;
1883e12c5d1SDavid du Colombier }
1893e12c5d1SDavid du Colombier if(f == 0) {
1903e12c5d1SDavid du Colombier if(n->complex >= FNX) {
1913e12c5d1SDavid du Colombier regsalloc(*fnxp, n);
1923e12c5d1SDavid du Colombier nod = znode;
1933e12c5d1SDavid du Colombier nod.op = OAS;
1943e12c5d1SDavid du Colombier nod.left = *fnxp;
1953e12c5d1SDavid du Colombier nod.right = n;
1963e12c5d1SDavid du Colombier nod.type = n->type;
1973e12c5d1SDavid du Colombier cgen(&nod, Z);
1983e12c5d1SDavid du Colombier (*fnxp)++;
1993e12c5d1SDavid du Colombier }
2003e12c5d1SDavid du Colombier return;
2013e12c5d1SDavid du Colombier }
202219b2ee8SDavid du Colombier if(typesu[n->type->etype] || typev[n->type->etype]) {
2033e12c5d1SDavid du Colombier regaalloc(tn2, n);
2043e12c5d1SDavid du Colombier if(n->complex >= FNX) {
2053e12c5d1SDavid du Colombier sugen(*fnxp, tn2, n->type->width);
2063e12c5d1SDavid du Colombier (*fnxp)++;
2073e12c5d1SDavid du Colombier } else
2083e12c5d1SDavid du Colombier sugen(n, tn2, n->type->width);
2093e12c5d1SDavid du Colombier return;
2103e12c5d1SDavid du Colombier }
2114ac975e2SDavid du Colombier if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) {
2123e12c5d1SDavid du Colombier regaalloc1(tn1, n);
2133e12c5d1SDavid du Colombier if(n->complex >= FNX) {
2143e12c5d1SDavid du Colombier cgen(*fnxp, tn1);
2153e12c5d1SDavid du Colombier (*fnxp)++;
2163e12c5d1SDavid du Colombier } else
2173e12c5d1SDavid du Colombier cgen(n, tn1);
2183e12c5d1SDavid du Colombier return;
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier if(vconst(n) == 0) {
2213e12c5d1SDavid du Colombier regaalloc(tn2, n);
2223e12c5d1SDavid du Colombier gmove(n, tn2);
2233e12c5d1SDavid du Colombier return;
2243e12c5d1SDavid du Colombier }
2253e12c5d1SDavid du Colombier regalloc(tn1, n, Z);
2263e12c5d1SDavid du Colombier if(n->complex >= FNX) {
2273e12c5d1SDavid du Colombier cgen(*fnxp, tn1);
2283e12c5d1SDavid du Colombier (*fnxp)++;
2293e12c5d1SDavid du Colombier } else
2303e12c5d1SDavid du Colombier cgen(n, tn1);
2313e12c5d1SDavid du Colombier regaalloc(tn2, n);
2323e12c5d1SDavid du Colombier gmove(tn1, tn2);
2333e12c5d1SDavid du Colombier regfree(tn1);
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier Node*
nodconst(long v)2373e12c5d1SDavid du Colombier nodconst(long v)
2383e12c5d1SDavid du Colombier {
239219b2ee8SDavid du Colombier constnode.vconst = v;
2403e12c5d1SDavid du Colombier return &constnode;
2413e12c5d1SDavid du Colombier }
2423e12c5d1SDavid du Colombier
2433e12c5d1SDavid du Colombier Node*
nodfconst(double d)244bd389b36SDavid du Colombier nodfconst(double d)
2453e12c5d1SDavid du Colombier {
246219b2ee8SDavid du Colombier fconstnode.fconst = d;
2473e12c5d1SDavid du Colombier return &fconstnode;
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier
2503e12c5d1SDavid du Colombier int
isreg(Node * n,int r)2513e12c5d1SDavid du Colombier isreg(Node *n, int r)
2523e12c5d1SDavid du Colombier {
2533e12c5d1SDavid du Colombier
2543e12c5d1SDavid du Colombier if(n->op == OREGISTER)
2553e12c5d1SDavid du Colombier if(n->reg == r)
2563e12c5d1SDavid du Colombier return 1;
2573e12c5d1SDavid du Colombier return 0;
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier int
nodreg(Node * n,Node * nn,int r)2613e12c5d1SDavid du Colombier nodreg(Node *n, Node *nn, int r)
2623e12c5d1SDavid du Colombier {
2633e12c5d1SDavid du Colombier
2643e12c5d1SDavid du Colombier *n = regnode;
2653e12c5d1SDavid du Colombier n->reg = r;
2663e12c5d1SDavid du Colombier if(reg[r] == 0)
2673e12c5d1SDavid du Colombier return 0;
2683e12c5d1SDavid du Colombier if(nn != Z) {
2693e12c5d1SDavid du Colombier n->type = nn->type;
2703e12c5d1SDavid du Colombier n->lineno = nn->lineno;
2713e12c5d1SDavid du Colombier if(nn->op == OREGISTER)
2723e12c5d1SDavid du Colombier if(nn->reg == r)
2733e12c5d1SDavid du Colombier return 0;
2743e12c5d1SDavid du Colombier }
2753e12c5d1SDavid du Colombier return 1;
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier
2783e12c5d1SDavid du Colombier void
regret(Node * n,Node * nn)2793e12c5d1SDavid du Colombier regret(Node *n, Node *nn)
2803e12c5d1SDavid du Colombier {
2813e12c5d1SDavid du Colombier int r;
2823e12c5d1SDavid du Colombier
2833e12c5d1SDavid du Colombier r = REGRET;
284219b2ee8SDavid du Colombier if(typefd[nn->type->etype])
2853e12c5d1SDavid du Colombier r = FREGRET;
2863e12c5d1SDavid du Colombier nodreg(n, nn, r);
2873e12c5d1SDavid du Colombier reg[r]++;
2883e12c5d1SDavid du Colombier }
2893e12c5d1SDavid du Colombier
2903e12c5d1SDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2913e12c5d1SDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2923e12c5d1SDavid du Colombier {
2933e12c5d1SDavid du Colombier int i;
2943e12c5d1SDavid du Colombier
2953e12c5d1SDavid du Colombier switch(tn->type->etype) {
2963e12c5d1SDavid du Colombier case TCHAR:
2973e12c5d1SDavid du Colombier case TUCHAR:
2983e12c5d1SDavid du Colombier case TSHORT:
2993e12c5d1SDavid du Colombier case TUSHORT:
3007dd7cddfSDavid du Colombier case TINT:
3017dd7cddfSDavid du Colombier case TUINT:
3023e12c5d1SDavid du Colombier case TLONG:
3033e12c5d1SDavid du Colombier case TULONG:
3043e12c5d1SDavid du Colombier case TIND:
3053e12c5d1SDavid du Colombier if(o != Z && o->op == OREGISTER) {
3063e12c5d1SDavid du Colombier i = o->reg;
3073e12c5d1SDavid du Colombier if(i >= D_AX && i <= D_DI)
3083e12c5d1SDavid du Colombier goto out;
3093e12c5d1SDavid du Colombier }
3103e12c5d1SDavid du Colombier for(i=D_AX; i<=D_DI; i++)
3113e12c5d1SDavid du Colombier if(reg[i] == 0)
3123e12c5d1SDavid du Colombier goto out;
3133e12c5d1SDavid du Colombier diag(tn, "out of fixed registers");
314d40255d8SDavid du Colombier abort();
3153e12c5d1SDavid du Colombier goto err;
3163e12c5d1SDavid du Colombier
3173e12c5d1SDavid du Colombier case TFLOAT:
3183e12c5d1SDavid du Colombier case TDOUBLE:
3193e12c5d1SDavid du Colombier i = D_F0;
3203e12c5d1SDavid du Colombier goto out;
321*3a276d32SDavid du Colombier
322*3a276d32SDavid du Colombier case TVLONG:
323*3a276d32SDavid du Colombier case TUVLONG:
324*3a276d32SDavid du Colombier n->op = OREGPAIR;
325*3a276d32SDavid du Colombier n->complex = 0; /* already in registers */
326*3a276d32SDavid du Colombier n->addable = 11;
327*3a276d32SDavid du Colombier n->type = tn->type;
328*3a276d32SDavid du Colombier n->lineno = nearln;
329*3a276d32SDavid du Colombier n->left = alloc(sizeof(Node));
330*3a276d32SDavid du Colombier n->right = alloc(sizeof(Node));
331*3a276d32SDavid du Colombier if(o != Z && o->op == OREGPAIR) {
332*3a276d32SDavid du Colombier regalloc(n->left, ®node, o->left);
333*3a276d32SDavid du Colombier regalloc(n->right, ®node, o->right);
334*3a276d32SDavid du Colombier } else {
335*3a276d32SDavid du Colombier regalloc(n->left, ®node, Z);
336*3a276d32SDavid du Colombier regalloc(n->right, ®node, Z);
337*3a276d32SDavid du Colombier }
338*3a276d32SDavid du Colombier n->right->type = types[TULONG];
339*3a276d32SDavid du Colombier if(tn->type->etype == TUVLONG)
340*3a276d32SDavid du Colombier n->left->type = types[TULONG];
341*3a276d32SDavid du Colombier return;
3423e12c5d1SDavid du Colombier }
3433e12c5d1SDavid du Colombier diag(tn, "unknown type in regalloc: %T", tn->type);
3443e12c5d1SDavid du Colombier err:
3453e12c5d1SDavid du Colombier i = 0;
3463e12c5d1SDavid du Colombier out:
3473e12c5d1SDavid du Colombier if(i)
3483e12c5d1SDavid du Colombier reg[i]++;
3493e12c5d1SDavid du Colombier nodreg(n, tn, i);
350375daca8SDavid du Colombier //print("+ %R %d\n", i, reg[i]);
3513e12c5d1SDavid du Colombier }
3523e12c5d1SDavid du Colombier
3533e12c5d1SDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3543e12c5d1SDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3553e12c5d1SDavid du Colombier {
3563e12c5d1SDavid du Colombier Node nod;
3573e12c5d1SDavid du Colombier
3583e12c5d1SDavid du Colombier nod = *tn;
3593e12c5d1SDavid du Colombier nod.type = types[TIND];
3603e12c5d1SDavid du Colombier regalloc(n, &nod, o);
3613e12c5d1SDavid du Colombier }
3623e12c5d1SDavid du Colombier
3633e12c5d1SDavid du Colombier void
regfree(Node * n)3643e12c5d1SDavid du Colombier regfree(Node *n)
3653e12c5d1SDavid du Colombier {
3663e12c5d1SDavid du Colombier int i;
3673e12c5d1SDavid du Colombier
368*3a276d32SDavid du Colombier if(n->op == OREGPAIR) {
369*3a276d32SDavid du Colombier regfree(n->left);
370*3a276d32SDavid du Colombier regfree(n->right);
371*3a276d32SDavid du Colombier return;
372*3a276d32SDavid du Colombier }
373*3a276d32SDavid du Colombier
3743e12c5d1SDavid du Colombier i = 0;
3753e12c5d1SDavid du Colombier if(n->op != OREGISTER && n->op != OINDREG)
3763e12c5d1SDavid du Colombier goto err;
3773e12c5d1SDavid du Colombier i = n->reg;
3783e12c5d1SDavid du Colombier if(i < 0 || i >= sizeof(reg))
3793e12c5d1SDavid du Colombier goto err;
3803e12c5d1SDavid du Colombier if(reg[i] <= 0)
3813e12c5d1SDavid du Colombier goto err;
3823e12c5d1SDavid du Colombier reg[i]--;
383375daca8SDavid du Colombier //print("- %R %d\n", i, reg[i]);
3843e12c5d1SDavid du Colombier return;
3853e12c5d1SDavid du Colombier err:
386da51d93aSDavid du Colombier diag(n, "error in regfree: %R", i);
3873e12c5d1SDavid du Colombier }
3883e12c5d1SDavid du Colombier
3893e12c5d1SDavid du Colombier void
regsalloc(Node * n,Node * nn)3903e12c5d1SDavid du Colombier regsalloc(Node *n, Node *nn)
3913e12c5d1SDavid du Colombier {
3927dd7cddfSDavid du Colombier cursafe = align(cursafe, nn->type, Aaut3);
3937dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
3943e12c5d1SDavid du Colombier *n = *nodsafe;
395219b2ee8SDavid du Colombier n->xoffset = -(stkoff + cursafe);
3963e12c5d1SDavid du Colombier n->type = nn->type;
3973e12c5d1SDavid du Colombier n->etype = nn->type->etype;
3983e12c5d1SDavid du Colombier n->lineno = nn->lineno;
3993e12c5d1SDavid du Colombier }
4003e12c5d1SDavid du Colombier
4013e12c5d1SDavid du Colombier void
regaalloc1(Node * n,Node * nn)4023e12c5d1SDavid du Colombier regaalloc1(Node *n, Node *nn)
4033e12c5d1SDavid du Colombier {
404b85a8364SDavid du Colombier USED(nn);
405b85a8364SDavid du Colombier
4064ac975e2SDavid du Colombier if(REGARG < 0) {
4074ac975e2SDavid du Colombier diag(n, "regaalloc1");
4084ac975e2SDavid du Colombier return;
4094ac975e2SDavid du Colombier }
410b85a8364SDavid du Colombier /* not reached
4117dd7cddfSDavid du Colombier nodreg(n, nn, REGARG);
4127dd7cddfSDavid du Colombier reg[REGARG]++;
4137dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
4147dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
4157dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
416b85a8364SDavid du Colombier */
4173e12c5d1SDavid du Colombier }
4183e12c5d1SDavid du Colombier
4193e12c5d1SDavid du Colombier void
regaalloc(Node * n,Node * nn)4203e12c5d1SDavid du Colombier regaalloc(Node *n, Node *nn)
4213e12c5d1SDavid du Colombier {
4227dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
4233e12c5d1SDavid du Colombier *n = *nn;
4243e12c5d1SDavid du Colombier n->op = OINDREG;
4253e12c5d1SDavid du Colombier n->reg = REGSP;
426219b2ee8SDavid du Colombier n->xoffset = curarg;
4273e12c5d1SDavid du Colombier n->complex = 0;
4283e12c5d1SDavid du Colombier n->addable = 20;
4297dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
4307dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
4313e12c5d1SDavid du Colombier }
4323e12c5d1SDavid du Colombier
4333e12c5d1SDavid du Colombier void
regind(Node * n,Node * nn)4343e12c5d1SDavid du Colombier regind(Node *n, Node *nn)
4353e12c5d1SDavid du Colombier {
4363e12c5d1SDavid du Colombier
4373e12c5d1SDavid du Colombier if(n->op != OREGISTER) {
4383e12c5d1SDavid du Colombier diag(n, "regind not OREGISTER");
4393e12c5d1SDavid du Colombier return;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier n->op = OINDREG;
4423e12c5d1SDavid du Colombier n->type = nn->type;
4433e12c5d1SDavid du Colombier }
4443e12c5d1SDavid du Colombier
4453e12c5d1SDavid du Colombier void
naddr(Node * n,Adr * a)4463e12c5d1SDavid du Colombier naddr(Node *n, Adr *a)
4473e12c5d1SDavid du Colombier {
4483e12c5d1SDavid du Colombier long v;
4493e12c5d1SDavid du Colombier
4503e12c5d1SDavid du Colombier a->type = D_NONE;
4513e12c5d1SDavid du Colombier if(n == Z)
4523e12c5d1SDavid du Colombier return;
4533e12c5d1SDavid du Colombier switch(n->op) {
4543e12c5d1SDavid du Colombier default:
4553e12c5d1SDavid du Colombier bad:
4563e12c5d1SDavid du Colombier diag(n, "bad in naddr: %O %D", n->op, a);
457375daca8SDavid du Colombier //prtree(n, "naddr");
4583e12c5d1SDavid du Colombier break;
4593e12c5d1SDavid du Colombier
4603e12c5d1SDavid du Colombier case OREGISTER:
4613e12c5d1SDavid du Colombier a->type = n->reg;
4623e12c5d1SDavid du Colombier a->sym = S;
4633e12c5d1SDavid du Colombier break;
4643e12c5d1SDavid du Colombier
465d40255d8SDavid du Colombier case OEXREG:
466d40255d8SDavid du Colombier a->type = D_INDIR + D_GS;
467d40255d8SDavid du Colombier a->offset = n->reg - 1;
468d40255d8SDavid du Colombier a->etype = n->etype;
469d40255d8SDavid du Colombier break;
4703e12c5d1SDavid du Colombier
4713e12c5d1SDavid du Colombier case OIND:
4723e12c5d1SDavid du Colombier naddr(n->left, a);
4733e12c5d1SDavid du Colombier if(a->type >= D_AX && a->type <= D_DI)
4743e12c5d1SDavid du Colombier a->type += D_INDIR;
4753e12c5d1SDavid du Colombier else
4763e12c5d1SDavid du Colombier if(a->type == D_CONST)
4773e12c5d1SDavid du Colombier a->type = D_NONE+D_INDIR;
4783e12c5d1SDavid du Colombier else
4793e12c5d1SDavid du Colombier if(a->type == D_ADDR) {
4803e12c5d1SDavid du Colombier a->type = a->index;
4813e12c5d1SDavid du Colombier a->index = D_NONE;
4823e12c5d1SDavid du Colombier } else
4833e12c5d1SDavid du Colombier goto bad;
48480ee5cbfSDavid du Colombier break;
48580ee5cbfSDavid du Colombier
48680ee5cbfSDavid du Colombier case OINDEX:
48780ee5cbfSDavid du Colombier a->type = idx.ptr;
488375daca8SDavid du Colombier if(n->left->op == OADDR || n->left->op == OCONST)
48980ee5cbfSDavid du Colombier naddr(n->left, a);
49080ee5cbfSDavid du Colombier if(a->type >= D_AX && a->type <= D_DI)
49180ee5cbfSDavid du Colombier a->type += D_INDIR;
49280ee5cbfSDavid du Colombier else
49380ee5cbfSDavid du Colombier if(a->type == D_CONST)
49480ee5cbfSDavid du Colombier a->type = D_NONE+D_INDIR;
49580ee5cbfSDavid du Colombier else
49680ee5cbfSDavid du Colombier if(a->type == D_ADDR) {
49780ee5cbfSDavid du Colombier a->type = a->index;
49880ee5cbfSDavid du Colombier a->index = D_NONE;
49980ee5cbfSDavid du Colombier } else
50080ee5cbfSDavid du Colombier goto bad;
5013e12c5d1SDavid du Colombier a->index = idx.reg;
5023e12c5d1SDavid du Colombier a->scale = n->scale;
50380ee5cbfSDavid du Colombier a->offset += n->xoffset;
5043e12c5d1SDavid du Colombier break;
5053e12c5d1SDavid du Colombier
5063e12c5d1SDavid du Colombier case OINDREG:
5073e12c5d1SDavid du Colombier a->type = n->reg+D_INDIR;
5083e12c5d1SDavid du Colombier a->sym = S;
509219b2ee8SDavid du Colombier a->offset = n->xoffset;
5103e12c5d1SDavid du Colombier break;
5113e12c5d1SDavid du Colombier
5123e12c5d1SDavid du Colombier case ONAME:
5133e12c5d1SDavid du Colombier a->etype = n->etype;
5143e12c5d1SDavid du Colombier a->type = D_STATIC;
5153e12c5d1SDavid du Colombier a->sym = n->sym;
516219b2ee8SDavid du Colombier a->offset = n->xoffset;
5173e12c5d1SDavid du Colombier if(n->class == CSTATIC)
5183e12c5d1SDavid du Colombier break;
5193e12c5d1SDavid du Colombier if(n->class == CEXTERN || n->class == CGLOBL) {
5203e12c5d1SDavid du Colombier a->type = D_EXTERN;
5213e12c5d1SDavid du Colombier break;
5223e12c5d1SDavid du Colombier }
5233e12c5d1SDavid du Colombier if(n->class == CAUTO) {
5243e12c5d1SDavid du Colombier a->type = D_AUTO;
5253e12c5d1SDavid du Colombier break;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier if(n->class == CPARAM) {
5283e12c5d1SDavid du Colombier a->type = D_PARAM;
5293e12c5d1SDavid du Colombier break;
5303e12c5d1SDavid du Colombier }
5313e12c5d1SDavid du Colombier goto bad;
5323e12c5d1SDavid du Colombier
5333e12c5d1SDavid du Colombier case OCONST:
534219b2ee8SDavid du Colombier if(typefd[n->type->etype]) {
5353e12c5d1SDavid du Colombier a->type = D_FCONST;
536219b2ee8SDavid du Colombier a->dval = n->fconst;
5373e12c5d1SDavid du Colombier break;
5383e12c5d1SDavid du Colombier }
5393e12c5d1SDavid du Colombier a->sym = S;
5403e12c5d1SDavid du Colombier a->type = D_CONST;
541219b2ee8SDavid du Colombier a->offset = n->vconst;
5423e12c5d1SDavid du Colombier break;
5433e12c5d1SDavid du Colombier
5443e12c5d1SDavid du Colombier case OADDR:
5453e12c5d1SDavid du Colombier naddr(n->left, a);
5463e12c5d1SDavid du Colombier if(a->type >= D_INDIR) {
5473e12c5d1SDavid du Colombier a->type -= D_INDIR;
5483e12c5d1SDavid du Colombier break;
5493e12c5d1SDavid du Colombier }
5503e12c5d1SDavid du Colombier if(a->type == D_EXTERN || a->type == D_STATIC ||
5513e12c5d1SDavid du Colombier a->type == D_AUTO || a->type == D_PARAM)
5523e12c5d1SDavid du Colombier if(a->index == D_NONE) {
5533e12c5d1SDavid du Colombier a->index = a->type;
5543e12c5d1SDavid du Colombier a->type = D_ADDR;
5553e12c5d1SDavid du Colombier break;
5563e12c5d1SDavid du Colombier }
5573e12c5d1SDavid du Colombier goto bad;
5583e12c5d1SDavid du Colombier
5593e12c5d1SDavid du Colombier case OADD:
5603e12c5d1SDavid du Colombier if(n->right->op == OCONST) {
561219b2ee8SDavid du Colombier v = n->right->vconst;
5623e12c5d1SDavid du Colombier naddr(n->left, a);
5633e12c5d1SDavid du Colombier } else
5643e12c5d1SDavid du Colombier if(n->left->op == OCONST) {
565219b2ee8SDavid du Colombier v = n->left->vconst;
5663e12c5d1SDavid du Colombier naddr(n->right, a);
5673e12c5d1SDavid du Colombier } else
5683e12c5d1SDavid du Colombier goto bad;
5693e12c5d1SDavid du Colombier a->offset += v;
5703e12c5d1SDavid du Colombier break;
5713e12c5d1SDavid du Colombier
5723e12c5d1SDavid du Colombier }
5733e12c5d1SDavid du Colombier }
5743e12c5d1SDavid du Colombier
5753e12c5d1SDavid du Colombier #define CASE(a,b) ((a<<8)|(b<<0))
5763e12c5d1SDavid du Colombier
5773e12c5d1SDavid du Colombier void
gmove(Node * f,Node * t)5783e12c5d1SDavid du Colombier gmove(Node *f, Node *t)
5793e12c5d1SDavid du Colombier {
5803e12c5d1SDavid du Colombier int ft, tt, a;
5813e12c5d1SDavid du Colombier Node nod, nod1;
582bd389b36SDavid du Colombier Prog *p1;
5833e12c5d1SDavid du Colombier
5843e12c5d1SDavid du Colombier ft = f->type->etype;
5853e12c5d1SDavid du Colombier tt = t->type->etype;
5863e12c5d1SDavid du Colombier if(debug['M'])
5873e12c5d1SDavid du Colombier print("gop: %O %O[%s],%O[%s]\n", OAS,
5883e12c5d1SDavid du Colombier f->op, tnames[ft], t->op, tnames[tt]);
589219b2ee8SDavid du Colombier if(typefd[ft] && f->op == OCONST) {
590219b2ee8SDavid du Colombier if(f->fconst == 0)
5913e12c5d1SDavid du Colombier gins(AFLDZ, Z, Z);
5923e12c5d1SDavid du Colombier else
593219b2ee8SDavid du Colombier if(f->fconst == 1)
5943e12c5d1SDavid du Colombier gins(AFLD1, Z, Z);
5953e12c5d1SDavid du Colombier else
5963e12c5d1SDavid du Colombier gins(AFMOVD, f, &fregnode0);
5973e12c5d1SDavid du Colombier gmove(&fregnode0, t);
5983e12c5d1SDavid du Colombier return;
5993e12c5d1SDavid du Colombier }
6003e12c5d1SDavid du Colombier /*
6013e12c5d1SDavid du Colombier * load
6023e12c5d1SDavid du Colombier */
60380ee5cbfSDavid du Colombier if(f->op == ONAME || f->op == OINDREG ||
60480ee5cbfSDavid du Colombier f->op == OIND || f->op == OINDEX)
6053e12c5d1SDavid du Colombier switch(ft) {
6063e12c5d1SDavid du Colombier case TCHAR:
6073e12c5d1SDavid du Colombier a = AMOVBLSX;
6083e12c5d1SDavid du Colombier goto ld;
6093e12c5d1SDavid du Colombier case TUCHAR:
6103e12c5d1SDavid du Colombier a = AMOVBLZX;
6113e12c5d1SDavid du Colombier goto ld;
6123e12c5d1SDavid du Colombier case TSHORT:
613219b2ee8SDavid du Colombier if(typefd[tt]) {
6143e12c5d1SDavid du Colombier gins(AFMOVW, f, &fregnode0);
6153e12c5d1SDavid du Colombier gmove(&fregnode0, t);
6163e12c5d1SDavid du Colombier return;
6173e12c5d1SDavid du Colombier }
6183e12c5d1SDavid du Colombier a = AMOVWLSX;
6193e12c5d1SDavid du Colombier goto ld;
6203e12c5d1SDavid du Colombier case TUSHORT:
6213e12c5d1SDavid du Colombier a = AMOVWLZX;
6223e12c5d1SDavid du Colombier goto ld;
6237dd7cddfSDavid du Colombier case TINT:
6247dd7cddfSDavid du Colombier case TUINT:
6253e12c5d1SDavid du Colombier case TLONG:
6263e12c5d1SDavid du Colombier case TULONG:
6273e12c5d1SDavid du Colombier case TIND:
628219b2ee8SDavid du Colombier if(typefd[tt]) {
6293e12c5d1SDavid du Colombier gins(AFMOVL, f, &fregnode0);
6303e12c5d1SDavid du Colombier gmove(&fregnode0, t);
6313e12c5d1SDavid du Colombier return;
6323e12c5d1SDavid du Colombier }
6333e12c5d1SDavid du Colombier a = AMOVL;
6343e12c5d1SDavid du Colombier
6353e12c5d1SDavid du Colombier ld:
6363e12c5d1SDavid du Colombier regalloc(&nod, f, t);
6373e12c5d1SDavid du Colombier nod.type = types[TLONG];
6383e12c5d1SDavid du Colombier gins(a, f, &nod);
6393e12c5d1SDavid du Colombier gmove(&nod, t);
6403e12c5d1SDavid du Colombier regfree(&nod);
6413e12c5d1SDavid du Colombier return;
6423e12c5d1SDavid du Colombier
6433e12c5d1SDavid du Colombier case TFLOAT:
6443e12c5d1SDavid du Colombier gins(AFMOVF, f, t);
6453e12c5d1SDavid du Colombier return;
6463e12c5d1SDavid du Colombier case TDOUBLE:
6473e12c5d1SDavid du Colombier gins(AFMOVD, f, t);
6483e12c5d1SDavid du Colombier return;
6493e12c5d1SDavid du Colombier }
6503e12c5d1SDavid du Colombier
6513e12c5d1SDavid du Colombier /*
6523e12c5d1SDavid du Colombier * store
6533e12c5d1SDavid du Colombier */
654219b2ee8SDavid du Colombier if(t->op == ONAME || t->op == OINDREG ||
655219b2ee8SDavid du Colombier t->op == OIND || t->op == OINDEX)
6563e12c5d1SDavid du Colombier switch(tt) {
6573e12c5d1SDavid du Colombier case TCHAR:
6583e12c5d1SDavid du Colombier case TUCHAR:
6593e12c5d1SDavid du Colombier a = AMOVB; goto st;
6603e12c5d1SDavid du Colombier case TSHORT:
6613e12c5d1SDavid du Colombier case TUSHORT:
6623e12c5d1SDavid du Colombier a = AMOVW; goto st;
6637dd7cddfSDavid du Colombier case TINT:
6647dd7cddfSDavid du Colombier case TUINT:
6653e12c5d1SDavid du Colombier case TLONG:
6663e12c5d1SDavid du Colombier case TULONG:
6673e12c5d1SDavid du Colombier case TIND:
6683e12c5d1SDavid du Colombier a = AMOVL; goto st;
6693e12c5d1SDavid du Colombier
6703e12c5d1SDavid du Colombier st:
6713e12c5d1SDavid du Colombier if(f->op == OCONST) {
6723e12c5d1SDavid du Colombier gins(a, f, t);
6733e12c5d1SDavid du Colombier return;
6743e12c5d1SDavid du Colombier }
6753e12c5d1SDavid du Colombier regalloc(&nod, t, f);
6763e12c5d1SDavid du Colombier gmove(f, &nod);
6773e12c5d1SDavid du Colombier gins(a, &nod, t);
6783e12c5d1SDavid du Colombier regfree(&nod);
6793e12c5d1SDavid du Colombier return;
6803e12c5d1SDavid du Colombier
6813e12c5d1SDavid du Colombier case TFLOAT:
6823e12c5d1SDavid du Colombier gins(AFMOVFP, f, t);
6833e12c5d1SDavid du Colombier return;
6843e12c5d1SDavid du Colombier case TDOUBLE:
6853e12c5d1SDavid du Colombier gins(AFMOVDP, f, t);
6863e12c5d1SDavid du Colombier return;
6873e12c5d1SDavid du Colombier }
6883e12c5d1SDavid du Colombier
6893e12c5d1SDavid du Colombier /*
6903e12c5d1SDavid du Colombier * convert
6913e12c5d1SDavid du Colombier */
6923e12c5d1SDavid du Colombier switch(CASE(ft,tt)) {
6933e12c5d1SDavid du Colombier default:
6943e12c5d1SDavid du Colombier /*
6953e12c5d1SDavid du Colombier * integer to integer
6963e12c5d1SDavid du Colombier ********
6973e12c5d1SDavid du Colombier a = AGOK; break;
6983e12c5d1SDavid du Colombier
6993e12c5d1SDavid du Colombier case CASE( TCHAR, TCHAR):
7003e12c5d1SDavid du Colombier case CASE( TUCHAR, TCHAR):
7013e12c5d1SDavid du Colombier case CASE( TSHORT, TCHAR):
7023e12c5d1SDavid du Colombier case CASE( TUSHORT,TCHAR):
7037dd7cddfSDavid du Colombier case CASE( TINT, TCHAR):
7047dd7cddfSDavid du Colombier case CASE( TUINT, TCHAR):
7053e12c5d1SDavid du Colombier case CASE( TLONG, TCHAR):
7063e12c5d1SDavid du Colombier case CASE( TULONG, TCHAR):
7073e12c5d1SDavid du Colombier case CASE( TIND, TCHAR):
7083e12c5d1SDavid du Colombier
7093e12c5d1SDavid du Colombier case CASE( TCHAR, TUCHAR):
7103e12c5d1SDavid du Colombier case CASE( TUCHAR, TUCHAR):
7113e12c5d1SDavid du Colombier case CASE( TSHORT, TUCHAR):
7123e12c5d1SDavid du Colombier case CASE( TUSHORT,TUCHAR):
7137dd7cddfSDavid du Colombier case CASE( TINT, TUCHAR):
7147dd7cddfSDavid du Colombier case CASE( TUINT, TUCHAR):
7153e12c5d1SDavid du Colombier case CASE( TLONG, TUCHAR):
7163e12c5d1SDavid du Colombier case CASE( TULONG, TUCHAR):
7173e12c5d1SDavid du Colombier case CASE( TIND, TUCHAR):
7183e12c5d1SDavid du Colombier
7193e12c5d1SDavid du Colombier case CASE( TSHORT, TSHORT):
7203e12c5d1SDavid du Colombier case CASE( TUSHORT,TSHORT):
7217dd7cddfSDavid du Colombier case CASE( TINT, TSHORT):
7227dd7cddfSDavid du Colombier case CASE( TUINT, TSHORT):
7233e12c5d1SDavid du Colombier case CASE( TLONG, TSHORT):
7243e12c5d1SDavid du Colombier case CASE( TULONG, TSHORT):
7253e12c5d1SDavid du Colombier case CASE( TIND, TSHORT):
7263e12c5d1SDavid du Colombier
7273e12c5d1SDavid du Colombier case CASE( TSHORT, TUSHORT):
7283e12c5d1SDavid du Colombier case CASE( TUSHORT,TUSHORT):
7297dd7cddfSDavid du Colombier case CASE( TINT, TUSHORT):
7307dd7cddfSDavid du Colombier case CASE( TUINT, TUSHORT):
7313e12c5d1SDavid du Colombier case CASE( TLONG, TUSHORT):
7323e12c5d1SDavid du Colombier case CASE( TULONG, TUSHORT):
7333e12c5d1SDavid du Colombier case CASE( TIND, TUSHORT):
7343e12c5d1SDavid du Colombier
7357dd7cddfSDavid du Colombier case CASE( TINT, TINT):
7367dd7cddfSDavid du Colombier case CASE( TUINT, TINT):
7377dd7cddfSDavid du Colombier case CASE( TLONG, TINT):
7387dd7cddfSDavid du Colombier case CASE( TULONG, TINT):
7397dd7cddfSDavid du Colombier case CASE( TIND, TINT):
7407dd7cddfSDavid du Colombier
7417dd7cddfSDavid du Colombier case CASE( TINT, TUINT):
7427dd7cddfSDavid du Colombier case CASE( TUINT, TUINT):
7437dd7cddfSDavid du Colombier case CASE( TLONG, TUINT):
7447dd7cddfSDavid du Colombier case CASE( TULONG, TUINT):
7457dd7cddfSDavid du Colombier case CASE( TIND, TUINT):
7467dd7cddfSDavid du Colombier
7477dd7cddfSDavid du Colombier case CASE( TINT, TLONG):
7487dd7cddfSDavid du Colombier case CASE( TUINT, TLONG):
7493e12c5d1SDavid du Colombier case CASE( TLONG, TLONG):
7503e12c5d1SDavid du Colombier case CASE( TULONG, TLONG):
7513e12c5d1SDavid du Colombier case CASE( TIND, TLONG):
7523e12c5d1SDavid du Colombier
7537dd7cddfSDavid du Colombier case CASE( TINT, TULONG):
7547dd7cddfSDavid du Colombier case CASE( TUINT, TULONG):
7553e12c5d1SDavid du Colombier case CASE( TLONG, TULONG):
7563e12c5d1SDavid du Colombier case CASE( TULONG, TULONG):
7573e12c5d1SDavid du Colombier case CASE( TIND, TULONG):
7583e12c5d1SDavid du Colombier
7597dd7cddfSDavid du Colombier case CASE( TINT, TIND):
7607dd7cddfSDavid du Colombier case CASE( TUINT, TIND):
7613e12c5d1SDavid du Colombier case CASE( TLONG, TIND):
7623e12c5d1SDavid du Colombier case CASE( TULONG, TIND):
7633e12c5d1SDavid du Colombier case CASE( TIND, TIND):
7643e12c5d1SDavid du Colombier *****/
765219b2ee8SDavid du Colombier a = AMOVL;
766219b2ee8SDavid du Colombier break;
767219b2ee8SDavid du Colombier
7687dd7cddfSDavid du Colombier case CASE( TSHORT, TINT):
7697dd7cddfSDavid du Colombier case CASE( TSHORT, TUINT):
770219b2ee8SDavid du Colombier case CASE( TSHORT, TLONG):
771219b2ee8SDavid du Colombier case CASE( TSHORT, TULONG):
772219b2ee8SDavid du Colombier case CASE( TSHORT, TIND):
773219b2ee8SDavid du Colombier a = AMOVWLSX;
774219b2ee8SDavid du Colombier if(f->op == OCONST) {
775219b2ee8SDavid du Colombier f->vconst &= 0xffff;
776219b2ee8SDavid du Colombier if(f->vconst & 0x8000)
777219b2ee8SDavid du Colombier f->vconst |= 0xffff0000;
778219b2ee8SDavid du Colombier a = AMOVL;
779219b2ee8SDavid du Colombier }
780219b2ee8SDavid du Colombier break;
781219b2ee8SDavid du Colombier
7827dd7cddfSDavid du Colombier case CASE( TUSHORT,TINT):
7837dd7cddfSDavid du Colombier case CASE( TUSHORT,TUINT):
784219b2ee8SDavid du Colombier case CASE( TUSHORT,TLONG):
785219b2ee8SDavid du Colombier case CASE( TUSHORT,TULONG):
786219b2ee8SDavid du Colombier case CASE( TUSHORT,TIND):
787219b2ee8SDavid du Colombier a = AMOVWLZX;
788219b2ee8SDavid du Colombier if(f->op == OCONST) {
789219b2ee8SDavid du Colombier f->vconst &= 0xffff;
790219b2ee8SDavid du Colombier a = AMOVL;
791219b2ee8SDavid du Colombier }
792219b2ee8SDavid du Colombier break;
793219b2ee8SDavid du Colombier
794219b2ee8SDavid du Colombier case CASE( TCHAR, TSHORT):
795219b2ee8SDavid du Colombier case CASE( TCHAR, TUSHORT):
7967dd7cddfSDavid du Colombier case CASE( TCHAR, TINT):
7977dd7cddfSDavid du Colombier case CASE( TCHAR, TUINT):
798219b2ee8SDavid du Colombier case CASE( TCHAR, TLONG):
799219b2ee8SDavid du Colombier case CASE( TCHAR, TULONG):
800219b2ee8SDavid du Colombier case CASE( TCHAR, TIND):
801219b2ee8SDavid du Colombier a = AMOVBLSX;
802219b2ee8SDavid du Colombier if(f->op == OCONST) {
803219b2ee8SDavid du Colombier f->vconst &= 0xff;
804219b2ee8SDavid du Colombier if(f->vconst & 0x80)
805219b2ee8SDavid du Colombier f->vconst |= 0xffffff00;
806219b2ee8SDavid du Colombier a = AMOVL;
807219b2ee8SDavid du Colombier }
808219b2ee8SDavid du Colombier break;
809219b2ee8SDavid du Colombier
810219b2ee8SDavid du Colombier case CASE( TUCHAR, TSHORT):
811219b2ee8SDavid du Colombier case CASE( TUCHAR, TUSHORT):
8127dd7cddfSDavid du Colombier case CASE( TUCHAR, TINT):
8137dd7cddfSDavid du Colombier case CASE( TUCHAR, TUINT):
814219b2ee8SDavid du Colombier case CASE( TUCHAR, TLONG):
815219b2ee8SDavid du Colombier case CASE( TUCHAR, TULONG):
816219b2ee8SDavid du Colombier case CASE( TUCHAR, TIND):
817219b2ee8SDavid du Colombier a = AMOVBLZX;
818219b2ee8SDavid du Colombier if(f->op == OCONST) {
819219b2ee8SDavid du Colombier f->vconst &= 0xff;
820219b2ee8SDavid du Colombier a = AMOVL;
821219b2ee8SDavid du Colombier }
822219b2ee8SDavid du Colombier break;
8233e12c5d1SDavid du Colombier
8243e12c5d1SDavid du Colombier /*
8253e12c5d1SDavid du Colombier * float to fix
8263e12c5d1SDavid du Colombier */
8273e12c5d1SDavid du Colombier case CASE( TFLOAT, TCHAR):
8283e12c5d1SDavid du Colombier case CASE( TFLOAT, TUCHAR):
8293e12c5d1SDavid du Colombier case CASE( TFLOAT, TSHORT):
8303e12c5d1SDavid du Colombier case CASE( TFLOAT, TUSHORT):
8317dd7cddfSDavid du Colombier case CASE( TFLOAT, TINT):
8323e12c5d1SDavid du Colombier case CASE( TFLOAT, TLONG):
8333e12c5d1SDavid du Colombier case CASE( TFLOAT, TIND):
8343e12c5d1SDavid du Colombier
8353e12c5d1SDavid du Colombier case CASE( TDOUBLE,TCHAR):
8363e12c5d1SDavid du Colombier case CASE( TDOUBLE,TUCHAR):
8373e12c5d1SDavid du Colombier case CASE( TDOUBLE,TSHORT):
8383e12c5d1SDavid du Colombier case CASE( TDOUBLE,TUSHORT):
8397dd7cddfSDavid du Colombier case CASE( TDOUBLE,TINT):
8403e12c5d1SDavid du Colombier case CASE( TDOUBLE,TLONG):
8413e12c5d1SDavid du Colombier case CASE( TDOUBLE,TIND):
8427dd7cddfSDavid du Colombier if(fproundflg) {
8437dd7cddfSDavid du Colombier regsalloc(&nod, ®node);
8447dd7cddfSDavid du Colombier gins(AFMOVLP, f, &nod);
8457dd7cddfSDavid du Colombier gmove(&nod, t);
8467dd7cddfSDavid du Colombier return;
8477dd7cddfSDavid du Colombier }
8483e12c5d1SDavid du Colombier regsalloc(&nod, ®node);
8493e12c5d1SDavid du Colombier regsalloc(&nod1, ®node);
8503e12c5d1SDavid du Colombier gins(AFSTCW, Z, &nod1);
851219b2ee8SDavid du Colombier nod1.xoffset += 2;
8523e12c5d1SDavid du Colombier gins(AMOVW, nodconst(0xf7f), &nod1);
8533e12c5d1SDavid du Colombier gins(AFLDCW, &nod1, Z);
8543e12c5d1SDavid du Colombier gins(AFMOVLP, f, &nod);
855219b2ee8SDavid du Colombier nod1.xoffset -= 2;
8563e12c5d1SDavid du Colombier gins(AFLDCW, &nod1, Z);
8573e12c5d1SDavid du Colombier gmove(&nod, t);
8583e12c5d1SDavid du Colombier return;
8593e12c5d1SDavid du Colombier
8603e12c5d1SDavid du Colombier /*
8612cca75a1SDavid du Colombier * float to ulong
8622cca75a1SDavid du Colombier */
8632cca75a1SDavid du Colombier case CASE( TDOUBLE, TULONG):
8642cca75a1SDavid du Colombier case CASE( TFLOAT, TULONG):
8652cca75a1SDavid du Colombier case CASE( TDOUBLE, TUINT):
8662cca75a1SDavid du Colombier case CASE( TFLOAT, TUINT):
8672cca75a1SDavid du Colombier regsalloc(&nod, ®node);
8682cca75a1SDavid du Colombier gmove(f, &fregnode0);
8692cca75a1SDavid du Colombier gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
8702cca75a1SDavid du Colombier gins(AFMOVLP, f, &nod);
8712cca75a1SDavid du Colombier gins(ASUBL, nodconst(-2147483648), &nod);
8722cca75a1SDavid du Colombier gmove(&nod, t);
8732cca75a1SDavid du Colombier return;
8742cca75a1SDavid du Colombier
8752cca75a1SDavid du Colombier /*
876bd389b36SDavid du Colombier * ulong to float
877bd389b36SDavid du Colombier */
878bd389b36SDavid du Colombier case CASE( TULONG, TDOUBLE):
879bd389b36SDavid du Colombier case CASE( TULONG, TFLOAT):
8807dd7cddfSDavid du Colombier case CASE( TUINT, TDOUBLE):
8817dd7cddfSDavid du Colombier case CASE( TUINT, TFLOAT):
882bd389b36SDavid du Colombier regalloc(&nod, f, f);
883bd389b36SDavid du Colombier gmove(f, &nod);
884bd389b36SDavid du Colombier regsalloc(&nod1, ®node);
885bd389b36SDavid du Colombier gmove(&nod, &nod1);
886bd389b36SDavid du Colombier gins(AFMOVL, &nod1, &fregnode0);
887bd389b36SDavid du Colombier gins(ACMPL, &nod, nodconst(0));
888bd389b36SDavid du Colombier gins(AJGE, Z, Z);
889bd389b36SDavid du Colombier p1 = p;
890bd389b36SDavid du Colombier gins(AFADDD, nodfconst(4294967296.), &fregnode0);
891bd389b36SDavid du Colombier patch(p1, pc);
892bd389b36SDavid du Colombier regfree(&nod);
893bd389b36SDavid du Colombier return;
894bd389b36SDavid du Colombier
895bd389b36SDavid du Colombier /*
8963e12c5d1SDavid du Colombier * fix to float
8973e12c5d1SDavid du Colombier */
8983e12c5d1SDavid du Colombier case CASE( TCHAR, TFLOAT):
8993e12c5d1SDavid du Colombier case CASE( TUCHAR, TFLOAT):
9003e12c5d1SDavid du Colombier case CASE( TSHORT, TFLOAT):
9013e12c5d1SDavid du Colombier case CASE( TUSHORT,TFLOAT):
9027dd7cddfSDavid du Colombier case CASE( TINT, TFLOAT):
9033e12c5d1SDavid du Colombier case CASE( TLONG, TFLOAT):
9043e12c5d1SDavid du Colombier case CASE( TIND, TFLOAT):
9053e12c5d1SDavid du Colombier
9063e12c5d1SDavid du Colombier case CASE( TCHAR, TDOUBLE):
9073e12c5d1SDavid du Colombier case CASE( TUCHAR, TDOUBLE):
9083e12c5d1SDavid du Colombier case CASE( TSHORT, TDOUBLE):
9093e12c5d1SDavid du Colombier case CASE( TUSHORT,TDOUBLE):
9107dd7cddfSDavid du Colombier case CASE( TINT, TDOUBLE):
9113e12c5d1SDavid du Colombier case CASE( TLONG, TDOUBLE):
9123e12c5d1SDavid du Colombier case CASE( TIND, TDOUBLE):
9133e12c5d1SDavid du Colombier regsalloc(&nod, ®node);
9143e12c5d1SDavid du Colombier gmove(f, &nod);
9153e12c5d1SDavid du Colombier gins(AFMOVL, &nod, &fregnode0);
9163e12c5d1SDavid du Colombier return;
9173e12c5d1SDavid du Colombier
9183e12c5d1SDavid du Colombier /*
9193e12c5d1SDavid du Colombier * float to float
9203e12c5d1SDavid du Colombier */
9213e12c5d1SDavid du Colombier case CASE( TFLOAT, TFLOAT):
9223e12c5d1SDavid du Colombier case CASE( TDOUBLE,TFLOAT):
9233e12c5d1SDavid du Colombier
9243e12c5d1SDavid du Colombier case CASE( TFLOAT, TDOUBLE):
9253e12c5d1SDavid du Colombier case CASE( TDOUBLE,TDOUBLE):
9263e12c5d1SDavid du Colombier a = AFMOVD; break;
9273e12c5d1SDavid du Colombier }
9283e12c5d1SDavid du Colombier if(a == AMOVL || a == AFMOVD)
9293e12c5d1SDavid du Colombier if(samaddr(f, t))
9303e12c5d1SDavid du Colombier return;
9313e12c5d1SDavid du Colombier gins(a, f, t);
9323e12c5d1SDavid du Colombier }
9333e12c5d1SDavid du Colombier
9343e12c5d1SDavid du Colombier void
doindex(Node * n)93580ee5cbfSDavid du Colombier doindex(Node *n)
9363e12c5d1SDavid du Colombier {
93780ee5cbfSDavid du Colombier Node nod, nod1;
9383e12c5d1SDavid du Colombier long v;
9393e12c5d1SDavid du Colombier
94080ee5cbfSDavid du Colombier if(debug['Y'])
94180ee5cbfSDavid du Colombier prtree(n, "index");
94280ee5cbfSDavid du Colombier
94380ee5cbfSDavid du Colombier if(n->left->complex >= FNX)
94480ee5cbfSDavid du Colombier print("botch in doindex\n");
94580ee5cbfSDavid du Colombier
9463e12c5d1SDavid du Colombier regalloc(&nod, ®node, Z);
947219b2ee8SDavid du Colombier v = constnode.vconst;
94880ee5cbfSDavid du Colombier cgen(n->right, &nod);
94980ee5cbfSDavid du Colombier idx.ptr = D_NONE;
950375daca8SDavid du Colombier if(n->left->op == OCONST)
951375daca8SDavid du Colombier idx.ptr = D_CONST;
952375daca8SDavid du Colombier else if(n->left->op == OREGISTER)
953375daca8SDavid du Colombier // else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
954375daca8SDavid du Colombier idx.ptr = n->left->reg;
955375daca8SDavid du Colombier else if(n->left->op != OADDR) {
95680ee5cbfSDavid du Colombier reg[D_BP]++; // cant be used as a base
95780ee5cbfSDavid du Colombier regalloc(&nod1, ®node, Z);
95880ee5cbfSDavid du Colombier cgen(n->left, &nod1);
95980ee5cbfSDavid du Colombier idx.ptr = nod1.reg;
96080ee5cbfSDavid du Colombier regfree(&nod1);
96180ee5cbfSDavid du Colombier reg[D_BP]--;
9623e12c5d1SDavid du Colombier }
963375daca8SDavid du Colombier idx.reg = nod.reg;
96480ee5cbfSDavid du Colombier regfree(&nod);
965219b2ee8SDavid du Colombier constnode.vconst = v;
9663e12c5d1SDavid du Colombier }
96780ee5cbfSDavid du Colombier
96880ee5cbfSDavid du Colombier void
gins(int a,Node * f,Node * t)96980ee5cbfSDavid du Colombier gins(int a, Node *f, Node *t)
97080ee5cbfSDavid du Colombier {
97180ee5cbfSDavid du Colombier
97280ee5cbfSDavid du Colombier if(f != Z && f->op == OINDEX)
97380ee5cbfSDavid du Colombier doindex(f);
97480ee5cbfSDavid du Colombier if(t != Z && t->op == OINDEX)
97580ee5cbfSDavid du Colombier doindex(t);
9763e12c5d1SDavid du Colombier nextpc();
9773e12c5d1SDavid du Colombier p->as = a;
9783e12c5d1SDavid du Colombier if(f != Z)
9793e12c5d1SDavid du Colombier naddr(f, &p->from);
9803e12c5d1SDavid du Colombier if(t != Z)
9813e12c5d1SDavid du Colombier naddr(t, &p->to);
9823e12c5d1SDavid du Colombier if(debug['g'])
9833e12c5d1SDavid du Colombier print("%P\n", p);
9843e12c5d1SDavid du Colombier }
9853e12c5d1SDavid du Colombier
9863e12c5d1SDavid du Colombier void
fgopcode(int o,Node * f,Node * t,int pop,int rev)9873e12c5d1SDavid du Colombier fgopcode(int o, Node *f, Node *t, int pop, int rev)
9883e12c5d1SDavid du Colombier {
9893e12c5d1SDavid du Colombier int a, et;
9903e12c5d1SDavid du Colombier Node nod;
9913e12c5d1SDavid du Colombier
9923e12c5d1SDavid du Colombier et = TLONG;
9933e12c5d1SDavid du Colombier if(f != Z && f->type != T)
9943e12c5d1SDavid du Colombier et = f->type->etype;
995219b2ee8SDavid du Colombier if(!typefd[et]) {
9963e12c5d1SDavid du Colombier diag(f, "fop: integer %O", o);
9973e12c5d1SDavid du Colombier return;
9983e12c5d1SDavid du Colombier }
9993e12c5d1SDavid du Colombier if(debug['M']) {
10003e12c5d1SDavid du Colombier if(t != Z && t->type != T)
10013e12c5d1SDavid du Colombier print("gop: %O %O-%s Z\n", o, f->op, tnames[et]);
10023e12c5d1SDavid du Colombier else
10033e12c5d1SDavid du Colombier print("gop: %O %O-%s %O-%s\n", o,
10043e12c5d1SDavid du Colombier f->op, tnames[et], t->op, tnames[t->type->etype]);
10053e12c5d1SDavid du Colombier }
10063e12c5d1SDavid du Colombier a = AGOK;
10073e12c5d1SDavid du Colombier switch(o) {
1008219b2ee8SDavid du Colombier
10093e12c5d1SDavid du Colombier case OASADD:
10103e12c5d1SDavid du Colombier case OADD:
10113e12c5d1SDavid du Colombier if(et == TFLOAT)
10123e12c5d1SDavid du Colombier a = AFADDF;
10133e12c5d1SDavid du Colombier else
1014*3a276d32SDavid du Colombier if(et == TDOUBLE) {
10153e12c5d1SDavid du Colombier a = AFADDD;
10163e12c5d1SDavid du Colombier if(pop)
10173e12c5d1SDavid du Colombier a = AFADDDP;
10183e12c5d1SDavid du Colombier }
10193e12c5d1SDavid du Colombier break;
10203e12c5d1SDavid du Colombier
10213e12c5d1SDavid du Colombier case OASSUB:
10223e12c5d1SDavid du Colombier case OSUB:
10233e12c5d1SDavid du Colombier if(et == TFLOAT) {
10243e12c5d1SDavid du Colombier a = AFSUBF;
10253e12c5d1SDavid du Colombier if(rev)
10263e12c5d1SDavid du Colombier a = AFSUBRF;
10273e12c5d1SDavid du Colombier } else
1028*3a276d32SDavid du Colombier if(et == TDOUBLE) {
10293e12c5d1SDavid du Colombier a = AFSUBD;
10303e12c5d1SDavid du Colombier if(pop)
10313e12c5d1SDavid du Colombier a = AFSUBDP;
10323e12c5d1SDavid du Colombier if(rev) {
10333e12c5d1SDavid du Colombier a = AFSUBRD;
10343e12c5d1SDavid du Colombier if(pop)
10353e12c5d1SDavid du Colombier a = AFSUBRDP;
10363e12c5d1SDavid du Colombier }
10373e12c5d1SDavid du Colombier }
10383e12c5d1SDavid du Colombier break;
10393e12c5d1SDavid du Colombier
10403e12c5d1SDavid du Colombier case OASMUL:
10413e12c5d1SDavid du Colombier case OMUL:
10423e12c5d1SDavid du Colombier if(et == TFLOAT)
10433e12c5d1SDavid du Colombier a = AFMULF;
10443e12c5d1SDavid du Colombier else
1045*3a276d32SDavid du Colombier if(et == TDOUBLE) {
10463e12c5d1SDavid du Colombier a = AFMULD;
10473e12c5d1SDavid du Colombier if(pop)
10483e12c5d1SDavid du Colombier a = AFMULDP;
10493e12c5d1SDavid du Colombier }
10503e12c5d1SDavid du Colombier break;
10513e12c5d1SDavid du Colombier
10523e12c5d1SDavid du Colombier case OASMOD:
10533e12c5d1SDavid du Colombier case OMOD:
10543e12c5d1SDavid du Colombier case OASDIV:
10553e12c5d1SDavid du Colombier case ODIV:
10563e12c5d1SDavid du Colombier if(et == TFLOAT) {
10573e12c5d1SDavid du Colombier a = AFDIVF;
10583e12c5d1SDavid du Colombier if(rev)
10593e12c5d1SDavid du Colombier a = AFDIVRF;
10603e12c5d1SDavid du Colombier } else
1061*3a276d32SDavid du Colombier if(et == TDOUBLE) {
10623e12c5d1SDavid du Colombier a = AFDIVD;
10633e12c5d1SDavid du Colombier if(pop)
10643e12c5d1SDavid du Colombier a = AFDIVDP;
10653e12c5d1SDavid du Colombier if(rev) {
10663e12c5d1SDavid du Colombier a = AFDIVRD;
10673e12c5d1SDavid du Colombier if(pop)
10683e12c5d1SDavid du Colombier a = AFDIVRDP;
10693e12c5d1SDavid du Colombier }
10703e12c5d1SDavid du Colombier }
10713e12c5d1SDavid du Colombier break;
10723e12c5d1SDavid du Colombier
10733e12c5d1SDavid du Colombier case OEQ:
10743e12c5d1SDavid du Colombier case ONE:
10753e12c5d1SDavid du Colombier case OLT:
10763e12c5d1SDavid du Colombier case OLE:
10773e12c5d1SDavid du Colombier case OGE:
10783e12c5d1SDavid du Colombier case OGT:
10793e12c5d1SDavid du Colombier pop += rev;
10803e12c5d1SDavid du Colombier if(et == TFLOAT) {
10813e12c5d1SDavid du Colombier a = AFCOMF;
10823e12c5d1SDavid du Colombier if(pop) {
10833e12c5d1SDavid du Colombier a = AFCOMFP;
10843e12c5d1SDavid du Colombier if(pop > 1)
10853e12c5d1SDavid du Colombier a = AGOK;
10863e12c5d1SDavid du Colombier }
10873e12c5d1SDavid du Colombier } else
1088*3a276d32SDavid du Colombier if(et == TDOUBLE) {
10893e12c5d1SDavid du Colombier a = AFCOMF;
10903e12c5d1SDavid du Colombier if(pop) {
10913e12c5d1SDavid du Colombier a = AFCOMDP;
10923e12c5d1SDavid du Colombier if(pop > 1)
10933e12c5d1SDavid du Colombier a = AFCOMDPP;
10943e12c5d1SDavid du Colombier }
10953e12c5d1SDavid du Colombier }
10963e12c5d1SDavid du Colombier gins(a, f, t);
10973e12c5d1SDavid du Colombier regalloc(&nod, ®node, Z);
10983e12c5d1SDavid du Colombier if(nod.reg != D_AX) {
10993e12c5d1SDavid du Colombier regfree(&nod);
11003e12c5d1SDavid du Colombier nod.reg = D_AX;
11013e12c5d1SDavid du Colombier gins(APUSHL, &nod, Z);
11023e12c5d1SDavid du Colombier gins(AWAIT, Z, Z);
11033e12c5d1SDavid du Colombier gins(AFSTSW, Z, &nod);
11043e12c5d1SDavid du Colombier gins(ASAHF, Z, Z);
11053e12c5d1SDavid du Colombier gins(APOPL, Z, &nod);
11063e12c5d1SDavid du Colombier } else {
11073e12c5d1SDavid du Colombier gins(AWAIT, Z, Z);
11083e12c5d1SDavid du Colombier gins(AFSTSW, Z, &nod);
11093e12c5d1SDavid du Colombier gins(ASAHF, Z, Z);
11103e12c5d1SDavid du Colombier regfree(&nod);
11113e12c5d1SDavid du Colombier }
11123e12c5d1SDavid du Colombier switch(o) {
11133e12c5d1SDavid du Colombier case OEQ: a = AJEQ; break;
11143e12c5d1SDavid du Colombier case ONE: a = AJNE; break;
11153e12c5d1SDavid du Colombier case OLT: a = AJCS; break;
11163e12c5d1SDavid du Colombier case OLE: a = AJLS; break;
11173e12c5d1SDavid du Colombier case OGE: a = AJCC; break;
11183e12c5d1SDavid du Colombier case OGT: a = AJHI; break;
11193e12c5d1SDavid du Colombier }
11203e12c5d1SDavid du Colombier gins(a, Z, Z);
11213e12c5d1SDavid du Colombier return;
11223e12c5d1SDavid du Colombier }
11233e12c5d1SDavid du Colombier if(a == AGOK)
11243e12c5d1SDavid du Colombier diag(Z, "bad in gopcode %O", o);
11253e12c5d1SDavid du Colombier gins(a, f, t);
11263e12c5d1SDavid du Colombier }
11273e12c5d1SDavid du Colombier
11283e12c5d1SDavid du Colombier void
gopcode(int o,Type * ty,Node * f,Node * t)11293e12c5d1SDavid du Colombier gopcode(int o, Type *ty, Node *f, Node *t)
11303e12c5d1SDavid du Colombier {
11313e12c5d1SDavid du Colombier int a, et;
11323e12c5d1SDavid du Colombier
11333e12c5d1SDavid du Colombier et = TLONG;
11343e12c5d1SDavid du Colombier if(ty != T)
11353e12c5d1SDavid du Colombier et = ty->etype;
1136219b2ee8SDavid du Colombier if(typefd[et] && o != OADDR && o != OFUNC) {
11373e12c5d1SDavid du Colombier diag(f, "gop: float %O", o);
11383e12c5d1SDavid du Colombier return;
11393e12c5d1SDavid du Colombier }
11403e12c5d1SDavid du Colombier if(debug['M']) {
11413e12c5d1SDavid du Colombier if(f != Z && f->type != T)
11423e12c5d1SDavid du Colombier print("gop: %O %O[%s],", o, f->op, tnames[et]);
11433e12c5d1SDavid du Colombier else
11443e12c5d1SDavid du Colombier print("gop: %O Z,", o);
11453e12c5d1SDavid du Colombier if(t != Z && t->type != T)
11463e12c5d1SDavid du Colombier print("%O[%s]\n", t->op, tnames[t->type->etype]);
11473e12c5d1SDavid du Colombier else
11483e12c5d1SDavid du Colombier print("Z\n");
11493e12c5d1SDavid du Colombier }
11503e12c5d1SDavid du Colombier a = AGOK;
11513e12c5d1SDavid du Colombier switch(o) {
1152da51d93aSDavid du Colombier case OCOM:
1153da51d93aSDavid du Colombier a = ANOTL;
1154da51d93aSDavid du Colombier if(et == TCHAR || et == TUCHAR)
1155da51d93aSDavid du Colombier a = ANOTB;
1156da51d93aSDavid du Colombier if(et == TSHORT || et == TUSHORT)
1157da51d93aSDavid du Colombier a = ANOTW;
1158da51d93aSDavid du Colombier break;
1159da51d93aSDavid du Colombier
1160da51d93aSDavid du Colombier case ONEG:
1161da51d93aSDavid du Colombier a = ANEGL;
1162da51d93aSDavid du Colombier if(et == TCHAR || et == TUCHAR)
1163da51d93aSDavid du Colombier a = ANEGB;
1164da51d93aSDavid du Colombier if(et == TSHORT || et == TUSHORT)
1165da51d93aSDavid du Colombier a = ANEGW;
1166da51d93aSDavid du Colombier break;
1167da51d93aSDavid du Colombier
11683e12c5d1SDavid du Colombier case OADDR:
11693e12c5d1SDavid du Colombier a = ALEAL;
11703e12c5d1SDavid du Colombier break;
11713e12c5d1SDavid du Colombier
11723e12c5d1SDavid du Colombier case OASADD:
11733e12c5d1SDavid du Colombier case OADD:
11743e12c5d1SDavid du Colombier a = AADDL;
11753e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
11763e12c5d1SDavid du Colombier a = AADDB;
11773e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
11783e12c5d1SDavid du Colombier a = AADDW;
11793e12c5d1SDavid du Colombier break;
11803e12c5d1SDavid du Colombier
11813e12c5d1SDavid du Colombier case OASSUB:
11823e12c5d1SDavid du Colombier case OSUB:
11833e12c5d1SDavid du Colombier a = ASUBL;
11843e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
11853e12c5d1SDavid du Colombier a = ASUBB;
11863e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
11873e12c5d1SDavid du Colombier a = ASUBW;
11883e12c5d1SDavid du Colombier break;
11893e12c5d1SDavid du Colombier
11903e12c5d1SDavid du Colombier case OASOR:
11913e12c5d1SDavid du Colombier case OOR:
11923e12c5d1SDavid du Colombier a = AORL;
11933e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
11943e12c5d1SDavid du Colombier a = AORB;
11953e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
11963e12c5d1SDavid du Colombier a = AORW;
11973e12c5d1SDavid du Colombier break;
11983e12c5d1SDavid du Colombier
11993e12c5d1SDavid du Colombier case OASAND:
12003e12c5d1SDavid du Colombier case OAND:
12013e12c5d1SDavid du Colombier a = AANDL;
12023e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12033e12c5d1SDavid du Colombier a = AANDB;
12043e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12053e12c5d1SDavid du Colombier a = AANDW;
12063e12c5d1SDavid du Colombier break;
12073e12c5d1SDavid du Colombier
12083e12c5d1SDavid du Colombier case OASXOR:
12093e12c5d1SDavid du Colombier case OXOR:
12103e12c5d1SDavid du Colombier a = AXORL;
12113e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12123e12c5d1SDavid du Colombier a = AXORB;
12133e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12143e12c5d1SDavid du Colombier a = AXORW;
12153e12c5d1SDavid du Colombier break;
12163e12c5d1SDavid du Colombier
12173e12c5d1SDavid du Colombier case OASLSHR:
12183e12c5d1SDavid du Colombier case OLSHR:
12193e12c5d1SDavid du Colombier a = ASHRL;
12203e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12213e12c5d1SDavid du Colombier a = ASHRB;
12223e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12233e12c5d1SDavid du Colombier a = ASHRW;
12243e12c5d1SDavid du Colombier break;
12253e12c5d1SDavid du Colombier
12263e12c5d1SDavid du Colombier case OASASHR:
12273e12c5d1SDavid du Colombier case OASHR:
12283e12c5d1SDavid du Colombier a = ASARL;
12293e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12303e12c5d1SDavid du Colombier a = ASARB;
12313e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12323e12c5d1SDavid du Colombier a = ASARW;
12333e12c5d1SDavid du Colombier break;
12343e12c5d1SDavid du Colombier
12353e12c5d1SDavid du Colombier case OASASHL:
12363e12c5d1SDavid du Colombier case OASHL:
12373e12c5d1SDavid du Colombier a = ASALL;
12383e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12393e12c5d1SDavid du Colombier a = ASALB;
12403e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12413e12c5d1SDavid du Colombier a = ASALW;
12423e12c5d1SDavid du Colombier break;
12433e12c5d1SDavid du Colombier
12443e12c5d1SDavid du Colombier case OFUNC:
12453e12c5d1SDavid du Colombier a = ACALL;
12463e12c5d1SDavid du Colombier break;
12473e12c5d1SDavid du Colombier
12483e12c5d1SDavid du Colombier case OASMUL:
12493e12c5d1SDavid du Colombier case OMUL:
1250375daca8SDavid du Colombier if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1251375daca8SDavid du Colombier t = Z;
12523e12c5d1SDavid du Colombier a = AIMULL;
12533e12c5d1SDavid du Colombier break;
12543e12c5d1SDavid du Colombier
12553e12c5d1SDavid du Colombier case OASMOD:
12563e12c5d1SDavid du Colombier case OMOD:
12573e12c5d1SDavid du Colombier case OASDIV:
12583e12c5d1SDavid du Colombier case ODIV:
12593e12c5d1SDavid du Colombier a = AIDIVL;
12603e12c5d1SDavid du Colombier break;
12613e12c5d1SDavid du Colombier
12623e12c5d1SDavid du Colombier case OASLMUL:
12633e12c5d1SDavid du Colombier case OLMUL:
12643e12c5d1SDavid du Colombier a = AMULL;
12653e12c5d1SDavid du Colombier break;
12663e12c5d1SDavid du Colombier
12673e12c5d1SDavid du Colombier case OASLMOD:
12683e12c5d1SDavid du Colombier case OLMOD:
12693e12c5d1SDavid du Colombier case OASLDIV:
12703e12c5d1SDavid du Colombier case OLDIV:
12713e12c5d1SDavid du Colombier a = ADIVL;
12723e12c5d1SDavid du Colombier break;
12733e12c5d1SDavid du Colombier
12743e12c5d1SDavid du Colombier case OEQ:
12753e12c5d1SDavid du Colombier case ONE:
12763e12c5d1SDavid du Colombier case OLT:
12773e12c5d1SDavid du Colombier case OLE:
12783e12c5d1SDavid du Colombier case OGE:
12793e12c5d1SDavid du Colombier case OGT:
12803e12c5d1SDavid du Colombier case OLO:
12813e12c5d1SDavid du Colombier case OLS:
12823e12c5d1SDavid du Colombier case OHS:
12833e12c5d1SDavid du Colombier case OHI:
12843e12c5d1SDavid du Colombier a = ACMPL;
12853e12c5d1SDavid du Colombier if(et == TCHAR || et == TUCHAR)
12863e12c5d1SDavid du Colombier a = ACMPB;
12873e12c5d1SDavid du Colombier if(et == TSHORT || et == TUSHORT)
12883e12c5d1SDavid du Colombier a = ACMPW;
12893e12c5d1SDavid du Colombier gins(a, f, t);
12903e12c5d1SDavid du Colombier switch(o) {
12913e12c5d1SDavid du Colombier case OEQ: a = AJEQ; break;
12923e12c5d1SDavid du Colombier case ONE: a = AJNE; break;
12933e12c5d1SDavid du Colombier case OLT: a = AJLT; break;
12943e12c5d1SDavid du Colombier case OLE: a = AJLE; break;
12953e12c5d1SDavid du Colombier case OGE: a = AJGE; break;
12963e12c5d1SDavid du Colombier case OGT: a = AJGT; break;
12973e12c5d1SDavid du Colombier case OLO: a = AJCS; break;
12983e12c5d1SDavid du Colombier case OLS: a = AJLS; break;
12993e12c5d1SDavid du Colombier case OHS: a = AJCC; break;
13003e12c5d1SDavid du Colombier case OHI: a = AJHI; break;
13013e12c5d1SDavid du Colombier }
13023e12c5d1SDavid du Colombier gins(a, Z, Z);
13033e12c5d1SDavid du Colombier return;
13043e12c5d1SDavid du Colombier }
13053e12c5d1SDavid du Colombier if(a == AGOK)
13063e12c5d1SDavid du Colombier diag(Z, "bad in gopcode %O", o);
13073e12c5d1SDavid du Colombier gins(a, f, t);
13083e12c5d1SDavid du Colombier }
13093e12c5d1SDavid du Colombier
13103e12c5d1SDavid du Colombier int
samaddr(Node * f,Node * t)13113e12c5d1SDavid du Colombier samaddr(Node *f, Node *t)
13123e12c5d1SDavid du Colombier {
13133e12c5d1SDavid du Colombier
13143e12c5d1SDavid du Colombier if(f->op != t->op)
13153e12c5d1SDavid du Colombier return 0;
13163e12c5d1SDavid du Colombier switch(f->op) {
13173e12c5d1SDavid du Colombier
13183e12c5d1SDavid du Colombier case OREGISTER:
13193e12c5d1SDavid du Colombier if(f->reg != t->reg)
13203e12c5d1SDavid du Colombier break;
13213e12c5d1SDavid du Colombier return 1;
13223e12c5d1SDavid du Colombier }
13233e12c5d1SDavid du Colombier return 0;
13243e12c5d1SDavid du Colombier }
13253e12c5d1SDavid du Colombier
13263e12c5d1SDavid du Colombier void
gbranch(int o)13273e12c5d1SDavid du Colombier gbranch(int o)
13283e12c5d1SDavid du Colombier {
13293e12c5d1SDavid du Colombier int a;
13303e12c5d1SDavid du Colombier
13313e12c5d1SDavid du Colombier a = AGOK;
13323e12c5d1SDavid du Colombier switch(o) {
13333e12c5d1SDavid du Colombier case ORETURN:
13343e12c5d1SDavid du Colombier a = ARET;
13353e12c5d1SDavid du Colombier break;
13363e12c5d1SDavid du Colombier case OGOTO:
13373e12c5d1SDavid du Colombier a = AJMP;
13383e12c5d1SDavid du Colombier break;
13393e12c5d1SDavid du Colombier }
13403e12c5d1SDavid du Colombier nextpc();
13413e12c5d1SDavid du Colombier if(a == AGOK) {
13423e12c5d1SDavid du Colombier diag(Z, "bad in gbranch %O", o);
13433e12c5d1SDavid du Colombier nextpc();
13443e12c5d1SDavid du Colombier }
13453e12c5d1SDavid du Colombier p->as = a;
13463e12c5d1SDavid du Colombier }
13473e12c5d1SDavid du Colombier
13483e12c5d1SDavid du Colombier void
patch(Prog * op,long pc)13493e12c5d1SDavid du Colombier patch(Prog *op, long pc)
13503e12c5d1SDavid du Colombier {
13513e12c5d1SDavid du Colombier
13523e12c5d1SDavid du Colombier op->to.offset = pc;
13533e12c5d1SDavid du Colombier op->to.type = D_BRANCH;
13543e12c5d1SDavid du Colombier }
13553e12c5d1SDavid du Colombier
13563e12c5d1SDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)13573e12c5d1SDavid du Colombier gpseudo(int a, Sym *s, Node *n)
13583e12c5d1SDavid du Colombier {
13593e12c5d1SDavid du Colombier
13603e12c5d1SDavid du Colombier nextpc();
13613e12c5d1SDavid du Colombier p->as = a;
13623e12c5d1SDavid du Colombier p->from.type = D_EXTERN;
13633e12c5d1SDavid du Colombier p->from.sym = s;
1364e288d156SDavid du Colombier p->from.scale = (profileflg ? 0 : NOPROF);
13653e12c5d1SDavid du Colombier if(s->class == CSTATIC)
13663e12c5d1SDavid du Colombier p->from.type = D_STATIC;
13673e12c5d1SDavid du Colombier naddr(n, &p->to);
13683e12c5d1SDavid du Colombier if(a == ADATA || a == AGLOBL)
13693e12c5d1SDavid du Colombier pc--;
13703e12c5d1SDavid du Colombier }
13713e12c5d1SDavid du Colombier
13723e12c5d1SDavid du Colombier int
sconst(Node * n)13733e12c5d1SDavid du Colombier sconst(Node *n)
13743e12c5d1SDavid du Colombier {
13753e12c5d1SDavid du Colombier long v;
13763e12c5d1SDavid du Colombier
1377219b2ee8SDavid du Colombier if(n->op == OCONST && !typefd[n->type->etype]) {
1378219b2ee8SDavid du Colombier v = n->vconst;
13793e12c5d1SDavid du Colombier if(v >= -32766L && v < 32766L)
13803e12c5d1SDavid du Colombier return 1;
13813e12c5d1SDavid du Colombier }
13823e12c5d1SDavid du Colombier return 0;
13833e12c5d1SDavid du Colombier }
13843e12c5d1SDavid du Colombier
13853e12c5d1SDavid du Colombier long
exreg(Type * t)13863e12c5d1SDavid du Colombier exreg(Type *t)
13873e12c5d1SDavid du Colombier {
13883e12c5d1SDavid du Colombier
1389d40255d8SDavid du Colombier int o;
1390d40255d8SDavid du Colombier
1391d40255d8SDavid du Colombier if(typechlp[t->etype]){
1392d40255d8SDavid du Colombier if(exregoffset >= 32)
1393d40255d8SDavid du Colombier return 0;
1394d40255d8SDavid du Colombier o = exregoffset;
1395d40255d8SDavid du Colombier exregoffset += 4;
1396d40255d8SDavid du Colombier return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
1397d40255d8SDavid du Colombier }
13983e12c5d1SDavid du Colombier return 0;
13993e12c5d1SDavid du Colombier }
14003e12c5d1SDavid du Colombier
14017dd7cddfSDavid du Colombier schar ewidth[NTYPE] =
14023e12c5d1SDavid du Colombier {
14037dd7cddfSDavid du Colombier -1, /*[TXXX]*/
14047dd7cddfSDavid du Colombier SZ_CHAR, /*[TCHAR]*/
14057dd7cddfSDavid du Colombier SZ_CHAR, /*[TUCHAR]*/
14067dd7cddfSDavid du Colombier SZ_SHORT, /*[TSHORT]*/
14077dd7cddfSDavid du Colombier SZ_SHORT, /*[TUSHORT]*/
14087dd7cddfSDavid du Colombier SZ_INT, /*[TINT]*/
14097dd7cddfSDavid du Colombier SZ_INT, /*[TUINT]*/
14107dd7cddfSDavid du Colombier SZ_LONG, /*[TLONG]*/
14117dd7cddfSDavid du Colombier SZ_LONG, /*[TULONG]*/
14127dd7cddfSDavid du Colombier SZ_VLONG, /*[TVLONG]*/
14137dd7cddfSDavid du Colombier SZ_VLONG, /*[TUVLONG]*/
14147dd7cddfSDavid du Colombier SZ_FLOAT, /*[TFLOAT]*/
14157dd7cddfSDavid du Colombier SZ_DOUBLE, /*[TDOUBLE]*/
14167dd7cddfSDavid du Colombier SZ_IND, /*[TIND]*/
14177dd7cddfSDavid du Colombier 0, /*[TFUNC]*/
14187dd7cddfSDavid du Colombier -1, /*[TARRAY]*/
14197dd7cddfSDavid du Colombier 0, /*[TVOID]*/
14207dd7cddfSDavid du Colombier -1, /*[TSTRUCT]*/
14217dd7cddfSDavid du Colombier -1, /*[TUNION]*/
14227dd7cddfSDavid du Colombier SZ_INT, /*[TENUM]*/
14233e12c5d1SDavid du Colombier };
14247dd7cddfSDavid du Colombier long ncast[NTYPE] =
14253e12c5d1SDavid du Colombier {
14267dd7cddfSDavid du Colombier 0, /*[TXXX]*/
14277dd7cddfSDavid du Colombier BCHAR|BUCHAR, /*[TCHAR]*/
14287dd7cddfSDavid du Colombier BCHAR|BUCHAR, /*[TUCHAR]*/
14297dd7cddfSDavid du Colombier BSHORT|BUSHORT, /*[TSHORT]*/
14307dd7cddfSDavid du Colombier BSHORT|BUSHORT, /*[TUSHORT]*/
14317dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/
14327dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/
14337dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/
14347dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/
14357dd7cddfSDavid du Colombier BVLONG|BUVLONG, /*[TVLONG]*/
14367dd7cddfSDavid du Colombier BVLONG|BUVLONG, /*[TUVLONG]*/
14377dd7cddfSDavid du Colombier BFLOAT, /*[TFLOAT]*/
14387dd7cddfSDavid du Colombier BDOUBLE, /*[TDOUBLE]*/
14397dd7cddfSDavid du Colombier BLONG|BULONG|BIND, /*[TIND]*/
14407dd7cddfSDavid du Colombier 0, /*[TFUNC]*/
14417dd7cddfSDavid du Colombier 0, /*[TARRAY]*/
14427dd7cddfSDavid du Colombier 0, /*[TVOID]*/
14437dd7cddfSDavid du Colombier BSTRUCT, /*[TSTRUCT]*/
14447dd7cddfSDavid du Colombier BUNION, /*[TUNION]*/
14457dd7cddfSDavid du Colombier 0, /*[TENUM]*/
14463e12c5d1SDavid du Colombier };
1447