17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier
3375daca8SDavid du Colombier static int resvreg[nelem(reg)];
47dd7cddfSDavid du Colombier
56891d857SDavid du Colombier static void gopcode64(int, Node*, Node*, Node*);
66891d857SDavid du Colombier static void gori64(int, Node*, Node*, Node*);
76891d857SDavid du Colombier static void gandi64(int, Node*, Node*, Node*);
87dd7cddfSDavid du Colombier
97dd7cddfSDavid du Colombier void
ginit(void)107dd7cddfSDavid du Colombier ginit(void)
117dd7cddfSDavid du Colombier {
127dd7cddfSDavid du Colombier Type *t;
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier thechar = 'q';
157dd7cddfSDavid du Colombier thestring = "power";
167dd7cddfSDavid du Colombier exregoffset = REGEXT;
177dd7cddfSDavid du Colombier exfregoffset = FREGEXT;
183a276d32SDavid du Colombier newvlongcode = 1;
197dd7cddfSDavid du Colombier listinit();
207dd7cddfSDavid du Colombier nstring = 0;
217dd7cddfSDavid du Colombier mnstring = 0;
227dd7cddfSDavid du Colombier nrathole = 0;
237dd7cddfSDavid du Colombier pc = 0;
247dd7cddfSDavid du Colombier breakpc = -1;
257dd7cddfSDavid du Colombier continpc = -1;
267dd7cddfSDavid du Colombier cases = C;
277dd7cddfSDavid du Colombier firstp = P;
287dd7cddfSDavid du Colombier lastp = P;
297dd7cddfSDavid du Colombier tfield = types[TLONG];
307dd7cddfSDavid du Colombier
313a276d32SDavid du Colombier typeswitch = typechlv;
323a276d32SDavid du Colombier
337dd7cddfSDavid du Colombier zprog.link = P;
347dd7cddfSDavid du Colombier zprog.as = AGOK;
357dd7cddfSDavid du Colombier zprog.reg = NREG;
367dd7cddfSDavid du Colombier zprog.from.type = D_NONE;
377dd7cddfSDavid du Colombier zprog.from.name = D_NONE;
387dd7cddfSDavid du Colombier zprog.from.reg = NREG;
396891d857SDavid du Colombier zprog.from3 = zprog.from;
407dd7cddfSDavid du Colombier zprog.to = zprog.from;
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier regnode.op = OREGISTER;
437dd7cddfSDavid du Colombier regnode.class = CEXREG;
447dd7cddfSDavid du Colombier regnode.reg = 0;
457dd7cddfSDavid du Colombier regnode.complex = 0;
467dd7cddfSDavid du Colombier regnode.addable = 11;
477dd7cddfSDavid du Colombier regnode.type = types[TLONG];
487dd7cddfSDavid du Colombier
497dd7cddfSDavid du Colombier constnode.op = OCONST;
507dd7cddfSDavid du Colombier constnode.class = CXXX;
517dd7cddfSDavid du Colombier constnode.complex = 0;
527dd7cddfSDavid du Colombier constnode.addable = 20;
537dd7cddfSDavid du Colombier constnode.type = types[TLONG];
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier fconstnode.op = OCONST;
567dd7cddfSDavid du Colombier fconstnode.class = CXXX;
577dd7cddfSDavid du Colombier fconstnode.complex = 0;
587dd7cddfSDavid du Colombier fconstnode.addable = 20;
597dd7cddfSDavid du Colombier fconstnode.type = types[TDOUBLE];
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier nodsafe = new(ONAME, Z, Z);
627dd7cddfSDavid du Colombier nodsafe->sym = slookup(".safe");
637dd7cddfSDavid du Colombier nodsafe->type = types[TINT];
647dd7cddfSDavid du Colombier nodsafe->etype = types[TINT]->etype;
657dd7cddfSDavid du Colombier nodsafe->class = CAUTO;
667dd7cddfSDavid du Colombier complex(nodsafe);
677dd7cddfSDavid du Colombier
687dd7cddfSDavid du Colombier t = typ(TARRAY, types[TCHAR]);
697dd7cddfSDavid du Colombier symrathole = slookup(".rathole");
707dd7cddfSDavid du Colombier symrathole->class = CGLOBL;
717dd7cddfSDavid du Colombier symrathole->type = t;
727dd7cddfSDavid du Colombier
737dd7cddfSDavid du Colombier nodrat = new(ONAME, Z, Z);
747dd7cddfSDavid du Colombier nodrat->sym = symrathole;
757dd7cddfSDavid du Colombier nodrat->type = types[TIND];
767dd7cddfSDavid du Colombier nodrat->etype = TVOID;
777dd7cddfSDavid du Colombier nodrat->class = CGLOBL;
787dd7cddfSDavid du Colombier complex(nodrat);
797dd7cddfSDavid du Colombier nodrat->type = t;
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier com64init();
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier memset(reg, 0, sizeof(reg));
847dd7cddfSDavid du Colombier reg[REGZERO] = 1; /* don't use */
857dd7cddfSDavid du Colombier reg[REGTMP] = 1;
867dd7cddfSDavid du Colombier reg[FREGCVI+NREG] = 1;
877dd7cddfSDavid du Colombier reg[FREGZERO+NREG] = 1;
887dd7cddfSDavid du Colombier reg[FREGHALF+NREG] = 1;
897dd7cddfSDavid du Colombier reg[FREGONE+NREG] = 1;
907dd7cddfSDavid du Colombier reg[FREGTWO+NREG] = 1;
917dd7cddfSDavid du Colombier memmove(resvreg, reg, sizeof(reg));
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier
947dd7cddfSDavid du Colombier void
gclean(void)957dd7cddfSDavid du Colombier gclean(void)
967dd7cddfSDavid du Colombier {
977dd7cddfSDavid du Colombier int i;
987dd7cddfSDavid du Colombier Sym *s;
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier for(i=0; i<NREG; i++)
1017dd7cddfSDavid du Colombier if(reg[i] && !resvreg[i])
1027dd7cddfSDavid du Colombier diag(Z, "reg %d left allocated", i);
1037dd7cddfSDavid du Colombier for(i=NREG; i<NREG+NREG; i++)
1047dd7cddfSDavid du Colombier if(reg[i] && !resvreg[i])
1057dd7cddfSDavid du Colombier diag(Z, "freg %d left allocated", i-NREG);
1067dd7cddfSDavid du Colombier while(mnstring)
1077dd7cddfSDavid du Colombier outstring("", 1L);
1087dd7cddfSDavid du Colombier symstring->type->width = nstring;
1097dd7cddfSDavid du Colombier symrathole->type->width = nrathole;
1107dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
1117dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
1127dd7cddfSDavid du Colombier if(s->type == T)
1137dd7cddfSDavid du Colombier continue;
1147dd7cddfSDavid du Colombier if(s->type->width == 0)
1157dd7cddfSDavid du Colombier continue;
1167dd7cddfSDavid du Colombier if(s->class != CGLOBL && s->class != CSTATIC)
1177dd7cddfSDavid du Colombier continue;
1187dd7cddfSDavid du Colombier if(s->type == types[TENUM])
1197dd7cddfSDavid du Colombier continue;
1207dd7cddfSDavid du Colombier gpseudo(AGLOBL, s, nodconst(s->type->width));
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier nextpc();
1237dd7cddfSDavid du Colombier p->as = AEND;
1247dd7cddfSDavid du Colombier outcode();
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier void
nextpc(void)1287dd7cddfSDavid du Colombier nextpc(void)
1297dd7cddfSDavid du Colombier {
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier p = alloc(sizeof(*p));
1327dd7cddfSDavid du Colombier *p = zprog;
1337dd7cddfSDavid du Colombier p->lineno = nearln;
1347dd7cddfSDavid du Colombier pc++;
1357dd7cddfSDavid du Colombier if(firstp == P) {
1367dd7cddfSDavid du Colombier firstp = p;
1377dd7cddfSDavid du Colombier lastp = p;
1387dd7cddfSDavid du Colombier return;
1397dd7cddfSDavid du Colombier }
1407dd7cddfSDavid du Colombier lastp->link = p;
1417dd7cddfSDavid du Colombier lastp = p;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)1457dd7cddfSDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
1467dd7cddfSDavid du Colombier {
1477dd7cddfSDavid du Colombier long regs;
1487dd7cddfSDavid du Colombier Node fnxargs[20], *fnxp;
1497dd7cddfSDavid du Colombier
1507dd7cddfSDavid du Colombier regs = cursafe;
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier fnxp = fnxargs;
1537dd7cddfSDavid du Colombier garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier curarg = 0;
1567dd7cddfSDavid du Colombier fnxp = fnxargs;
1577dd7cddfSDavid du Colombier garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier cursafe = regs;
1607dd7cddfSDavid du Colombier }
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)1637dd7cddfSDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
1647dd7cddfSDavid du Colombier {
1657dd7cddfSDavid du Colombier Node nod;
1667dd7cddfSDavid du Colombier
1677dd7cddfSDavid du Colombier if(n == Z)
1687dd7cddfSDavid du Colombier return;
1697dd7cddfSDavid du Colombier if(n->op == OLIST) {
1707dd7cddfSDavid du Colombier garg1(n->left, tn1, tn2, f, fnxp);
1717dd7cddfSDavid du Colombier garg1(n->right, tn1, tn2, f, fnxp);
1727dd7cddfSDavid du Colombier return;
1737dd7cddfSDavid du Colombier }
1747dd7cddfSDavid du Colombier if(f == 0) {
1757dd7cddfSDavid du Colombier if(n->complex >= FNX) {
1767dd7cddfSDavid du Colombier regsalloc(*fnxp, n);
1777dd7cddfSDavid du Colombier nod = znode;
1787dd7cddfSDavid du Colombier nod.op = OAS;
1797dd7cddfSDavid du Colombier nod.left = *fnxp;
1807dd7cddfSDavid du Colombier nod.right = n;
1817dd7cddfSDavid du Colombier nod.type = n->type;
1827dd7cddfSDavid du Colombier cgen(&nod, Z);
1837dd7cddfSDavid du Colombier (*fnxp)++;
1847dd7cddfSDavid du Colombier }
1857dd7cddfSDavid du Colombier return;
1867dd7cddfSDavid du Colombier }
1877dd7cddfSDavid du Colombier if(typesuv[n->type->etype]) {
1887dd7cddfSDavid du Colombier regaalloc(tn2, n);
1897dd7cddfSDavid du Colombier if(n->complex >= FNX) {
1906891d857SDavid du Colombier cgen(*fnxp, tn2);
1917dd7cddfSDavid du Colombier (*fnxp)++;
1927dd7cddfSDavid du Colombier } else
1936891d857SDavid du Colombier cgen(n, tn2);
1947dd7cddfSDavid du Colombier return;
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
1977dd7cddfSDavid du Colombier regaalloc1(tn1, n);
1987dd7cddfSDavid du Colombier if(n->complex >= FNX) {
1997dd7cddfSDavid du Colombier cgen(*fnxp, tn1);
2007dd7cddfSDavid du Colombier (*fnxp)++;
2017dd7cddfSDavid du Colombier } else
2027dd7cddfSDavid du Colombier cgen(n, tn1);
2037dd7cddfSDavid du Colombier return;
2047dd7cddfSDavid du Colombier }
2057dd7cddfSDavid du Colombier if(vconst(n) == 0) {
2067dd7cddfSDavid du Colombier regaalloc(tn2, n);
2077dd7cddfSDavid du Colombier gopcode(OAS, n, Z, tn2);
2087dd7cddfSDavid du Colombier return;
2097dd7cddfSDavid du Colombier }
2107dd7cddfSDavid du Colombier regalloc(tn1, n, Z);
2117dd7cddfSDavid du Colombier if(n->complex >= FNX) {
2127dd7cddfSDavid du Colombier cgen(*fnxp, tn1);
2137dd7cddfSDavid du Colombier (*fnxp)++;
2147dd7cddfSDavid du Colombier } else
2157dd7cddfSDavid du Colombier cgen(n, tn1);
2167dd7cddfSDavid du Colombier regaalloc(tn2, n);
2177dd7cddfSDavid du Colombier gopcode(OAS, tn1, Z, tn2);
2187dd7cddfSDavid du Colombier regfree(tn1);
2197dd7cddfSDavid du Colombier }
2207dd7cddfSDavid du Colombier
2217dd7cddfSDavid du Colombier Node*
nod32const(vlong v)2227dd7cddfSDavid du Colombier nod32const(vlong v)
2237dd7cddfSDavid du Colombier {
2247dd7cddfSDavid du Colombier constnode.vconst = v & MASK(32);
2257dd7cddfSDavid du Colombier return &constnode;
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier Node*
nodconst(long v)2297dd7cddfSDavid du Colombier nodconst(long v)
2307dd7cddfSDavid du Colombier {
2317dd7cddfSDavid du Colombier constnode.vconst = v;
2327dd7cddfSDavid du Colombier return &constnode;
2337dd7cddfSDavid du Colombier }
2347dd7cddfSDavid du Colombier
2357dd7cddfSDavid du Colombier Node*
nodfconst(double d)2367dd7cddfSDavid du Colombier nodfconst(double d)
2377dd7cddfSDavid du Colombier {
2387dd7cddfSDavid du Colombier fconstnode.fconst = d;
2397dd7cddfSDavid du Colombier return &fconstnode;
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier
2427dd7cddfSDavid du Colombier void
nodreg(Node * n,Node * nn,int reg)2437dd7cddfSDavid du Colombier nodreg(Node *n, Node *nn, int reg)
2447dd7cddfSDavid du Colombier {
2457dd7cddfSDavid du Colombier *n = regnode;
2467dd7cddfSDavid du Colombier n->reg = reg;
2477dd7cddfSDavid du Colombier n->type = nn->type;
2487dd7cddfSDavid du Colombier n->lineno = nn->lineno;
2497dd7cddfSDavid du Colombier }
2507dd7cddfSDavid du Colombier
2517dd7cddfSDavid du Colombier void
regret(Node * n,Node * nn)2527dd7cddfSDavid du Colombier regret(Node *n, Node *nn)
2537dd7cddfSDavid du Colombier {
2547dd7cddfSDavid du Colombier int r;
2557dd7cddfSDavid du Colombier
2567dd7cddfSDavid du Colombier r = REGRET;
2577dd7cddfSDavid du Colombier if(typefd[nn->type->etype])
2587dd7cddfSDavid du Colombier r = FREGRET+NREG;
2597dd7cddfSDavid du Colombier nodreg(n, nn, r);
2607dd7cddfSDavid du Colombier reg[r]++;
2617dd7cddfSDavid du Colombier }
2627dd7cddfSDavid du Colombier
2637dd7cddfSDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2647dd7cddfSDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2657dd7cddfSDavid du Colombier {
2667dd7cddfSDavid du Colombier int i, j;
2677dd7cddfSDavid du Colombier static int lasti;
2687dd7cddfSDavid du Colombier
2697dd7cddfSDavid du Colombier switch(tn->type->etype) {
2707dd7cddfSDavid du Colombier case TCHAR:
2717dd7cddfSDavid du Colombier case TUCHAR:
2727dd7cddfSDavid du Colombier case TSHORT:
2737dd7cddfSDavid du Colombier case TUSHORT:
2747dd7cddfSDavid du Colombier case TINT:
2757dd7cddfSDavid du Colombier case TUINT:
2767dd7cddfSDavid du Colombier case TLONG:
2777dd7cddfSDavid du Colombier case TULONG:
2787dd7cddfSDavid du Colombier case TIND:
2797dd7cddfSDavid du Colombier if(o != Z && o->op == OREGISTER) {
2807dd7cddfSDavid du Colombier i = o->reg;
2817dd7cddfSDavid du Colombier if(i > 0 && i < NREG)
2827dd7cddfSDavid du Colombier goto out;
2837dd7cddfSDavid du Colombier }
2847dd7cddfSDavid du Colombier j = lasti + REGRET+1;
2857dd7cddfSDavid du Colombier for(i=REGRET+1; i<NREG; i++) {
2867dd7cddfSDavid du Colombier if(j >= NREG)
2877dd7cddfSDavid du Colombier j = REGRET+1;
2887dd7cddfSDavid du Colombier if(reg[j] == 0) {
2897dd7cddfSDavid du Colombier i = j;
2907dd7cddfSDavid du Colombier goto out;
2917dd7cddfSDavid du Colombier }
2927dd7cddfSDavid du Colombier j++;
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier diag(tn, "out of fixed registers");
2957dd7cddfSDavid du Colombier goto err;
2967dd7cddfSDavid du Colombier
2977dd7cddfSDavid du Colombier case TFLOAT:
2987dd7cddfSDavid du Colombier case TDOUBLE:
2997dd7cddfSDavid du Colombier if(o != Z && o->op == OREGISTER) {
3007dd7cddfSDavid du Colombier i = o->reg;
3017dd7cddfSDavid du Colombier if(i >= NREG && i < NREG+NREG)
3027dd7cddfSDavid du Colombier goto out;
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier j = lasti + NREG;
3057dd7cddfSDavid du Colombier for(i=NREG; i<NREG+NREG; i++) {
3067dd7cddfSDavid du Colombier if(j >= NREG+NREG)
3077dd7cddfSDavid du Colombier j = NREG;
3087dd7cddfSDavid du Colombier if(reg[j] == 0) {
3097dd7cddfSDavid du Colombier i = j;
3107dd7cddfSDavid du Colombier goto out;
3117dd7cddfSDavid du Colombier }
3127dd7cddfSDavid du Colombier j++;
3137dd7cddfSDavid du Colombier }
3147dd7cddfSDavid du Colombier diag(tn, "out of float registers");
3157dd7cddfSDavid du Colombier goto err;
3166891d857SDavid du Colombier
3176891d857SDavid du Colombier case TVLONG:
3186891d857SDavid du Colombier case TUVLONG:
3196891d857SDavid du Colombier n->op = OREGPAIR;
3206891d857SDavid du Colombier n->complex = 0; /* already in registers */
3216891d857SDavid du Colombier n->addable = 11;
3226891d857SDavid du Colombier n->type = tn->type;
3236891d857SDavid du Colombier n->lineno = nearln;
3246891d857SDavid du Colombier n->left = alloc(sizeof(Node));
3256891d857SDavid du Colombier n->right = alloc(sizeof(Node));
3266891d857SDavid du Colombier if(o != Z && o->op == OREGPAIR) {
3276891d857SDavid du Colombier regalloc(n->left, ®node, o->left);
3286891d857SDavid du Colombier regalloc(n->right, ®node, o->right);
3296891d857SDavid du Colombier } else {
3306891d857SDavid du Colombier regalloc(n->left, ®node, Z);
3316891d857SDavid du Colombier regalloc(n->right, ®node, Z);
3326891d857SDavid du Colombier }
3336891d857SDavid du Colombier n->right->type = types[TULONG];
3346891d857SDavid du Colombier if(tn->type->etype == TUVLONG)
3356891d857SDavid du Colombier n->left->type = types[TULONG]; /* TO DO: is this a bad idea? */
3366891d857SDavid du Colombier return;
3377dd7cddfSDavid du Colombier }
3387dd7cddfSDavid du Colombier diag(tn, "unknown type in regalloc: %T", tn->type);
3397dd7cddfSDavid du Colombier err:
3407dd7cddfSDavid du Colombier i = 0;
3417dd7cddfSDavid du Colombier out:
3427dd7cddfSDavid du Colombier if(i)
3437dd7cddfSDavid du Colombier reg[i]++;
3447dd7cddfSDavid du Colombier lasti++;
3457dd7cddfSDavid du Colombier if(lasti >= 5)
3467dd7cddfSDavid du Colombier lasti = 0;
3477dd7cddfSDavid du Colombier nodreg(n, tn, i);
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier
3507dd7cddfSDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3517dd7cddfSDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3527dd7cddfSDavid du Colombier {
3537dd7cddfSDavid du Colombier Node nod;
3547dd7cddfSDavid du Colombier
3557dd7cddfSDavid du Colombier nod = *tn;
3567dd7cddfSDavid du Colombier nod.type = types[TIND];
3577dd7cddfSDavid du Colombier regalloc(n, &nod, o);
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier void
regfree(Node * n)3617dd7cddfSDavid du Colombier regfree(Node *n)
3627dd7cddfSDavid du Colombier {
3637dd7cddfSDavid du Colombier int i;
3647dd7cddfSDavid du Colombier
3656891d857SDavid du Colombier if(n->op == OREGPAIR) {
3666891d857SDavid du Colombier regfree(n->left);
3676891d857SDavid du Colombier regfree(n->right);
3686891d857SDavid du Colombier return;
3696891d857SDavid du Colombier }
3707dd7cddfSDavid du Colombier i = 0;
3717dd7cddfSDavid du Colombier if(n->op != OREGISTER && n->op != OINDREG)
3727dd7cddfSDavid du Colombier goto err;
3737dd7cddfSDavid du Colombier i = n->reg;
3747dd7cddfSDavid du Colombier if(i < 0 || i >= sizeof(reg))
3757dd7cddfSDavid du Colombier goto err;
3767dd7cddfSDavid du Colombier if(reg[i] <= 0)
3777dd7cddfSDavid du Colombier goto err;
3787dd7cddfSDavid du Colombier reg[i]--;
3797dd7cddfSDavid du Colombier return;
3807dd7cddfSDavid du Colombier err:
3816891d857SDavid du Colombier diag(n, "error in regfree: %d [%d]", i, reg[i]);
3826891d857SDavid du Colombier prtree(n, "regfree");
3837dd7cddfSDavid du Colombier }
3847dd7cddfSDavid du Colombier
3857dd7cddfSDavid du Colombier void
regsalloc(Node * n,Node * nn)3867dd7cddfSDavid du Colombier regsalloc(Node *n, Node *nn)
3877dd7cddfSDavid du Colombier {
3886891d857SDavid du Colombier cursafe = align(cursafe+stkoff, nn->type, Aaut3)-stkoff;
3897dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
3906891d857SDavid du Colombier // if(nn->type->etype == TDOUBLE || nn->type->etype == TVLONG){
3916891d857SDavid du Colombier // extern int hasdoubled;
3926891d857SDavid du Colombier // fprint(2, "stkoff=%ld cursafe=%ld curarg=%ld %d\n", stkoff, cursafe, curarg, hasdoubled);
3936891d857SDavid du Colombier // }
3947dd7cddfSDavid du Colombier *n = *nodsafe;
3957dd7cddfSDavid du Colombier n->xoffset = -(stkoff + cursafe);
3967dd7cddfSDavid du Colombier n->type = nn->type;
3977dd7cddfSDavid du Colombier n->etype = nn->type->etype;
3987dd7cddfSDavid du Colombier n->lineno = nn->lineno;
3997dd7cddfSDavid du Colombier }
4007dd7cddfSDavid du Colombier
4017dd7cddfSDavid du Colombier void
regaalloc1(Node * n,Node * nn)4027dd7cddfSDavid du Colombier regaalloc1(Node *n, Node *nn)
4037dd7cddfSDavid du Colombier {
4047dd7cddfSDavid du Colombier nodreg(n, nn, REGARG);
4057dd7cddfSDavid du Colombier reg[REGARG]++;
4067dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
4077dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
4087dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
4097dd7cddfSDavid du Colombier }
4107dd7cddfSDavid du Colombier
4117dd7cddfSDavid du Colombier void
regaalloc(Node * n,Node * nn)4127dd7cddfSDavid du Colombier regaalloc(Node *n, Node *nn)
4137dd7cddfSDavid du Colombier {
4147dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
4157dd7cddfSDavid du Colombier *n = *nn;
4167dd7cddfSDavid du Colombier n->op = OINDREG;
4177dd7cddfSDavid du Colombier n->reg = REGSP;
4187dd7cddfSDavid du Colombier n->xoffset = curarg + SZ_LONG;
4197dd7cddfSDavid du Colombier n->complex = 0;
4207dd7cddfSDavid du Colombier n->addable = 20;
4217dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
4227dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier
4257dd7cddfSDavid du Colombier void
regind(Node * n,Node * nn)4267dd7cddfSDavid du Colombier regind(Node *n, Node *nn)
4277dd7cddfSDavid du Colombier {
4287dd7cddfSDavid du Colombier
4297dd7cddfSDavid du Colombier if(n->op != OREGISTER) {
4307dd7cddfSDavid du Colombier diag(n, "regind not OREGISTER");
4317dd7cddfSDavid du Colombier return;
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier n->op = OINDREG;
4347dd7cddfSDavid du Colombier n->type = nn->type;
4357dd7cddfSDavid du Colombier }
4367dd7cddfSDavid du Colombier
4377dd7cddfSDavid du Colombier void
raddr(Node * n,Prog * p)4387dd7cddfSDavid du Colombier raddr(Node *n, Prog *p)
4397dd7cddfSDavid du Colombier {
4407dd7cddfSDavid du Colombier Adr a;
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier naddr(n, &a);
443375daca8SDavid du Colombier if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
4447dd7cddfSDavid du Colombier a.type = D_REG;
4457dd7cddfSDavid du Colombier a.reg = REGZERO;
4467dd7cddfSDavid du Colombier }
4477dd7cddfSDavid du Colombier if(a.type != D_REG && a.type != D_FREG) {
4487dd7cddfSDavid du Colombier if(n)
4497dd7cddfSDavid du Colombier diag(n, "bad in raddr: %O", n->op);
4507dd7cddfSDavid du Colombier else
4517dd7cddfSDavid du Colombier diag(n, "bad in raddr: <null>");
4527dd7cddfSDavid du Colombier p->reg = NREG;
4537dd7cddfSDavid du Colombier } else
4547dd7cddfSDavid du Colombier p->reg = a.reg;
4557dd7cddfSDavid du Colombier }
4567dd7cddfSDavid du Colombier
4577dd7cddfSDavid du Colombier void
naddr(Node * n,Adr * a)4587dd7cddfSDavid du Colombier naddr(Node *n, Adr *a)
4597dd7cddfSDavid du Colombier {
4607dd7cddfSDavid du Colombier long v;
4617dd7cddfSDavid du Colombier
4627dd7cddfSDavid du Colombier a->type = D_NONE;
4637dd7cddfSDavid du Colombier if(n == Z)
4647dd7cddfSDavid du Colombier return;
4657dd7cddfSDavid du Colombier switch(n->op) {
4667dd7cddfSDavid du Colombier default:
4677dd7cddfSDavid du Colombier bad:
4687dd7cddfSDavid du Colombier diag(n, "bad in naddr: %O", n->op);
4697dd7cddfSDavid du Colombier break;
4707dd7cddfSDavid du Colombier
4717dd7cddfSDavid du Colombier case OREGISTER:
4727dd7cddfSDavid du Colombier a->type = D_REG;
4737dd7cddfSDavid du Colombier a->sym = S;
4747dd7cddfSDavid du Colombier a->reg = n->reg;
4757dd7cddfSDavid du Colombier if(a->reg >= NREG) {
4767dd7cddfSDavid du Colombier a->type = D_FREG;
4777dd7cddfSDavid du Colombier a->reg -= NREG;
4787dd7cddfSDavid du Colombier }
4797dd7cddfSDavid du Colombier break;
4807dd7cddfSDavid du Colombier
4817dd7cddfSDavid du Colombier case OIND:
4827dd7cddfSDavid du Colombier naddr(n->left, a);
4836891d857SDavid du Colombier a->offset += n->xoffset; /* little hack for reglcgenv */
4847dd7cddfSDavid du Colombier if(a->type == D_REG) {
4857dd7cddfSDavid du Colombier a->type = D_OREG;
4867dd7cddfSDavid du Colombier break;
4877dd7cddfSDavid du Colombier }
4887dd7cddfSDavid du Colombier if(a->type == D_CONST) {
4897dd7cddfSDavid du Colombier a->type = D_OREG;
4907dd7cddfSDavid du Colombier break;
4917dd7cddfSDavid du Colombier }
4927dd7cddfSDavid du Colombier goto bad;
4937dd7cddfSDavid du Colombier
4947dd7cddfSDavid du Colombier case OINDREG:
4957dd7cddfSDavid du Colombier a->type = D_OREG;
4967dd7cddfSDavid du Colombier a->sym = S;
4977dd7cddfSDavid du Colombier a->offset = n->xoffset;
4987dd7cddfSDavid du Colombier a->reg = n->reg;
4997dd7cddfSDavid du Colombier break;
5007dd7cddfSDavid du Colombier
5017dd7cddfSDavid du Colombier case ONAME:
5027dd7cddfSDavid du Colombier a->etype = n->etype;
5037dd7cddfSDavid du Colombier a->type = D_OREG;
5047dd7cddfSDavid du Colombier a->name = D_STATIC;
5057dd7cddfSDavid du Colombier a->sym = n->sym;
5067dd7cddfSDavid du Colombier a->offset = n->xoffset;
5077dd7cddfSDavid du Colombier if(n->class == CSTATIC)
5087dd7cddfSDavid du Colombier break;
5097dd7cddfSDavid du Colombier if(n->class == CEXTERN || n->class == CGLOBL) {
5107dd7cddfSDavid du Colombier a->name = D_EXTERN;
5117dd7cddfSDavid du Colombier break;
5127dd7cddfSDavid du Colombier }
5137dd7cddfSDavid du Colombier if(n->class == CAUTO) {
5147dd7cddfSDavid du Colombier a->name = D_AUTO;
5157dd7cddfSDavid du Colombier break;
5167dd7cddfSDavid du Colombier }
5177dd7cddfSDavid du Colombier if(n->class == CPARAM) {
5187dd7cddfSDavid du Colombier a->name = D_PARAM;
5197dd7cddfSDavid du Colombier break;
5207dd7cddfSDavid du Colombier }
5217dd7cddfSDavid du Colombier goto bad;
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier case OCONST:
5247dd7cddfSDavid du Colombier a->sym = S;
5257dd7cddfSDavid du Colombier a->reg = NREG;
5267dd7cddfSDavid du Colombier if(typefd[n->type->etype]) {
5277dd7cddfSDavid du Colombier a->type = D_FCONST;
5287dd7cddfSDavid du Colombier a->dval = n->fconst;
5297dd7cddfSDavid du Colombier } else {
5307dd7cddfSDavid du Colombier a->type = D_CONST;
5317dd7cddfSDavid du Colombier a->offset = n->vconst;
5327dd7cddfSDavid du Colombier }
5337dd7cddfSDavid du Colombier break;
5347dd7cddfSDavid du Colombier
5357dd7cddfSDavid du Colombier case OADDR:
5367dd7cddfSDavid du Colombier naddr(n->left, a);
5377dd7cddfSDavid du Colombier if(a->type == D_OREG) {
5387dd7cddfSDavid du Colombier a->type = D_CONST;
5397dd7cddfSDavid du Colombier break;
5407dd7cddfSDavid du Colombier }
5417dd7cddfSDavid du Colombier goto bad;
5427dd7cddfSDavid du Colombier
5437dd7cddfSDavid du Colombier case OADD:
5447dd7cddfSDavid du Colombier if(n->left->op == OCONST) {
5457dd7cddfSDavid du Colombier naddr(n->left, a);
5467dd7cddfSDavid du Colombier v = a->offset;
5477dd7cddfSDavid du Colombier naddr(n->right, a);
5487dd7cddfSDavid du Colombier } else {
5497dd7cddfSDavid du Colombier naddr(n->right, a);
5507dd7cddfSDavid du Colombier v = a->offset;
5517dd7cddfSDavid du Colombier naddr(n->left, a);
5527dd7cddfSDavid du Colombier }
5537dd7cddfSDavid du Colombier a->offset += v;
5547dd7cddfSDavid du Colombier break;
5557dd7cddfSDavid du Colombier
5567dd7cddfSDavid du Colombier }
5577dd7cddfSDavid du Colombier }
5587dd7cddfSDavid du Colombier
5597dd7cddfSDavid du Colombier void
gloadhi(Node * f,Node * t,int c)5606891d857SDavid du Colombier gloadhi(Node *f, Node *t, int c)
5616891d857SDavid du Colombier {
5626891d857SDavid du Colombier Type *ot;
5636891d857SDavid du Colombier
5646891d857SDavid du Colombier if(f->op == OCONST){
5656891d857SDavid du Colombier f = nodconst((long)(f->vconst>>32));
5666891d857SDavid du Colombier if(c==1 && sconst(f) || c==2 && uconst(f)){
5676891d857SDavid du Colombier if(t->op == OREGISTER)
5686891d857SDavid du Colombier regfree(t);
5696891d857SDavid du Colombier *t = *f;
5706891d857SDavid du Colombier return;
5716891d857SDavid du Colombier }
5726891d857SDavid du Colombier }
5736891d857SDavid du Colombier if(f->op == OREGPAIR) {
5746891d857SDavid du Colombier gmove(f->left, t);
5756891d857SDavid du Colombier return;
5766891d857SDavid du Colombier }
5776891d857SDavid du Colombier ot = f->type;
5786891d857SDavid du Colombier f->type = types[TLONG];
5796891d857SDavid du Colombier gmove(f, t);
5806891d857SDavid du Colombier f->type = ot;
5816891d857SDavid du Colombier }
5826891d857SDavid du Colombier
5836891d857SDavid du Colombier void
gloadlo(Node * f,Node * t,int c)5846891d857SDavid du Colombier gloadlo(Node *f, Node *t, int c)
5856891d857SDavid du Colombier {
5866891d857SDavid du Colombier Type *ot;
5876891d857SDavid du Colombier
5886891d857SDavid du Colombier if(f->op == OCONST){
5896891d857SDavid du Colombier f = nodconst((long)f->vconst);
5906891d857SDavid du Colombier if(c && uconst(f)){
5916891d857SDavid du Colombier if(t->op == OREGISTER)
5926891d857SDavid du Colombier regfree(t);
5936891d857SDavid du Colombier *t = *f;
5946891d857SDavid du Colombier return;
5956891d857SDavid du Colombier }
5966891d857SDavid du Colombier }
5976891d857SDavid du Colombier if(f->op == OREGPAIR) {
5986891d857SDavid du Colombier gmove(f->right, t);
5996891d857SDavid du Colombier return;
6006891d857SDavid du Colombier }
6016891d857SDavid du Colombier ot = f->type;
6026891d857SDavid du Colombier f->type = types[TLONG];
6036891d857SDavid du Colombier f->xoffset += SZ_LONG;
6046891d857SDavid du Colombier if(0){
6056891d857SDavid du Colombier prtree(f, "gloadlo f"); prtree(t, "gloadlo t");
6066891d857SDavid du Colombier }
6076891d857SDavid du Colombier gmove(f, t);
6086891d857SDavid du Colombier f->xoffset -= SZ_LONG;
6096891d857SDavid du Colombier f->type = ot;
6106891d857SDavid du Colombier }
6116891d857SDavid du Colombier
6126891d857SDavid du Colombier void
fop(int as,int f1,int f2,Node * t)6137dd7cddfSDavid du Colombier fop(int as, int f1, int f2, Node *t)
6147dd7cddfSDavid du Colombier {
6157dd7cddfSDavid du Colombier Node nod1, nod2, nod3;
6167dd7cddfSDavid du Colombier
6177dd7cddfSDavid du Colombier nodreg(&nod1, t, NREG+f1);
6187dd7cddfSDavid du Colombier nodreg(&nod2, t, NREG+f2);
6197dd7cddfSDavid du Colombier regalloc(&nod3, t, t);
6207dd7cddfSDavid du Colombier gopcode(as, &nod1, &nod2, &nod3);
6217dd7cddfSDavid du Colombier gmove(&nod3, t);
6227dd7cddfSDavid du Colombier regfree(&nod3);
6237dd7cddfSDavid du Colombier }
6247dd7cddfSDavid du Colombier
625*40d01547SDavid du Colombier static void
floattofix(Node * f,Node * t)626*40d01547SDavid du Colombier floattofix(Node *f, Node *t)
627*40d01547SDavid du Colombier {
628*40d01547SDavid du Colombier Node nod, fxrat;
629*40d01547SDavid du Colombier
630*40d01547SDavid du Colombier regalloc(&nod, f, Z);
631*40d01547SDavid du Colombier regsalloc(&fxrat, &fconstnode);
632*40d01547SDavid du Colombier gins(AFCTIWZ, f, &nod);
633*40d01547SDavid du Colombier gins(AFMOVD, &nod, &fxrat);
634*40d01547SDavid du Colombier regfree(&nod);
635*40d01547SDavid du Colombier fxrat.type = nodrat->type;
636*40d01547SDavid du Colombier fxrat.etype = nodrat->etype;
637*40d01547SDavid du Colombier fxrat.xoffset += 4;
638*40d01547SDavid du Colombier gins(AMOVW, &fxrat, t);
639*40d01547SDavid du Colombier gmove(t, t);
640*40d01547SDavid du Colombier }
641*40d01547SDavid du Colombier
642*40d01547SDavid du Colombier static void
fixtofloat(Node * f,Node * t)643*40d01547SDavid du Colombier fixtofloat(Node *f, Node *t)
644*40d01547SDavid du Colombier {
645*40d01547SDavid du Colombier int a, ft, tt;
646*40d01547SDavid du Colombier Prog *p1;
647*40d01547SDavid du Colombier Node nod, fxc0, fxc1, fxc2, fxrat;
648*40d01547SDavid du Colombier
649*40d01547SDavid du Colombier ft = f->type->etype;
650*40d01547SDavid du Colombier tt = t->type->etype;
651*40d01547SDavid du Colombier
652*40d01547SDavid du Colombier /*
653*40d01547SDavid du Colombier * rat[0] = 0x43300000; rat[1] = f^0x80000000;
654*40d01547SDavid du Colombier * t = *(double*)rat - FREGCVI;
655*40d01547SDavid du Colombier * is-unsigned(t) => if(t<0) t += 2^32;
656*40d01547SDavid du Colombier * could be streamlined for int-to-float
657*40d01547SDavid du Colombier */
658*40d01547SDavid du Colombier regalloc(&fxc0, f, Z);
659*40d01547SDavid du Colombier regalloc(&fxc2, f, Z);
660*40d01547SDavid du Colombier regsalloc(&fxrat, &fconstnode); /* should be type float */
661*40d01547SDavid du Colombier gins(AMOVW, nodconst(0x43300000L), &fxc0);
662*40d01547SDavid du Colombier gins(AMOVW, f, &fxc2);
663*40d01547SDavid du Colombier gins(AMOVW, &fxc0, &fxrat);
664*40d01547SDavid du Colombier gins(AXOR, nodconst(0x80000000L), &fxc2);
665*40d01547SDavid du Colombier fxc1 = fxrat;
666*40d01547SDavid du Colombier fxc1.type = nodrat->type;
667*40d01547SDavid du Colombier fxc1.etype = nodrat->etype;
668*40d01547SDavid du Colombier fxc1.xoffset += SZ_LONG;
669*40d01547SDavid du Colombier gins(AMOVW, &fxc2, &fxc1);
670*40d01547SDavid du Colombier regfree(&fxc2);
671*40d01547SDavid du Colombier regfree(&fxc0);
672*40d01547SDavid du Colombier regalloc(&nod, t, t); /* should be type float */
673*40d01547SDavid du Colombier gins(AFMOVD, &fxrat, &nod);
674*40d01547SDavid du Colombier nodreg(&fxc1, t, NREG+FREGCVI);
675*40d01547SDavid du Colombier gins(AFSUB, &fxc1, &nod);
676*40d01547SDavid du Colombier a = AFMOVD;
677*40d01547SDavid du Colombier if(tt == TFLOAT)
678*40d01547SDavid du Colombier a = AFRSP;
679*40d01547SDavid du Colombier gins(a, &nod, t);
680*40d01547SDavid du Colombier regfree(&nod);
681*40d01547SDavid du Colombier if(ft == TULONG) {
682*40d01547SDavid du Colombier regalloc(&nod, t, Z);
683*40d01547SDavid du Colombier gins(AFCMPU, t, Z);
684*40d01547SDavid du Colombier p->to.type = D_FREG;
685*40d01547SDavid du Colombier p->to.reg = FREGZERO;
686*40d01547SDavid du Colombier gins(ABGE, Z, Z);
687*40d01547SDavid du Colombier p1 = p;
688*40d01547SDavid du Colombier if(tt == TFLOAT) {
689*40d01547SDavid du Colombier gins(AFMOVS, nodfconst(4294967296.), &nod);
690*40d01547SDavid du Colombier gins(AFADDS, &nod, t);
691*40d01547SDavid du Colombier } else {
692*40d01547SDavid du Colombier gins(AFMOVD, nodfconst(4294967296.), &nod);
693*40d01547SDavid du Colombier gins(AFADD, &nod, t);
694*40d01547SDavid du Colombier }
695*40d01547SDavid du Colombier patch(p1, pc);
696*40d01547SDavid du Colombier regfree(&nod);
697*40d01547SDavid du Colombier }
698*40d01547SDavid du Colombier }
699*40d01547SDavid du Colombier
7007dd7cddfSDavid du Colombier void
gmove(Node * f,Node * t)7017dd7cddfSDavid du Colombier gmove(Node *f, Node *t)
7027dd7cddfSDavid du Colombier {
7037dd7cddfSDavid du Colombier int ft, tt, a;
704*40d01547SDavid du Colombier Node nod;
7057dd7cddfSDavid du Colombier double d;
7067dd7cddfSDavid du Colombier
7077dd7cddfSDavid du Colombier ft = f->type->etype;
7087dd7cddfSDavid du Colombier tt = t->type->etype;
7097dd7cddfSDavid du Colombier
7107dd7cddfSDavid du Colombier if(ft == TDOUBLE && f->op == OCONST) {
7117dd7cddfSDavid du Colombier d = f->fconst;
7127dd7cddfSDavid du Colombier if(d == 0.0) {
7137dd7cddfSDavid du Colombier a = FREGZERO;
7147dd7cddfSDavid du Colombier goto ffreg;
7157dd7cddfSDavid du Colombier }
7167dd7cddfSDavid du Colombier if(d == 0.5) {
7177dd7cddfSDavid du Colombier a = FREGHALF;
7187dd7cddfSDavid du Colombier goto ffreg;
7197dd7cddfSDavid du Colombier }
7207dd7cddfSDavid du Colombier if(d == 1.0) {
7217dd7cddfSDavid du Colombier a = FREGONE;
7227dd7cddfSDavid du Colombier goto ffreg;
7237dd7cddfSDavid du Colombier }
7247dd7cddfSDavid du Colombier if(d == 2.0) {
7257dd7cddfSDavid du Colombier a = FREGTWO;
7267dd7cddfSDavid du Colombier goto ffreg;
7277dd7cddfSDavid du Colombier }
7287dd7cddfSDavid du Colombier if(d == -.5) {
7297dd7cddfSDavid du Colombier fop(OSUB, FREGHALF, FREGZERO, t);
7307dd7cddfSDavid du Colombier return;
7317dd7cddfSDavid du Colombier }
7327dd7cddfSDavid du Colombier if(d == -1.0) {
7337dd7cddfSDavid du Colombier fop(OSUB, FREGONE, FREGZERO, t);
7347dd7cddfSDavid du Colombier return;
7357dd7cddfSDavid du Colombier }
7367dd7cddfSDavid du Colombier if(d == -2.0) {
7377dd7cddfSDavid du Colombier fop(OSUB, FREGTWO, FREGZERO, t);
7387dd7cddfSDavid du Colombier return;
7397dd7cddfSDavid du Colombier }
7407dd7cddfSDavid du Colombier if(d == 1.5) {
7417dd7cddfSDavid du Colombier fop(OADD, FREGONE, FREGHALF, t);
7427dd7cddfSDavid du Colombier return;
7437dd7cddfSDavid du Colombier }
7447dd7cddfSDavid du Colombier if(d == 2.5) {
7457dd7cddfSDavid du Colombier fop(OADD, FREGTWO, FREGHALF, t);
7467dd7cddfSDavid du Colombier return;
7477dd7cddfSDavid du Colombier }
7487dd7cddfSDavid du Colombier if(d == 3.0) {
7497dd7cddfSDavid du Colombier fop(OADD, FREGTWO, FREGONE, t);
7507dd7cddfSDavid du Colombier return;
7517dd7cddfSDavid du Colombier }
7527dd7cddfSDavid du Colombier }
7537dd7cddfSDavid du Colombier if(ft == TFLOAT && f->op == OCONST) {
7547dd7cddfSDavid du Colombier d = f->fconst;
7557dd7cddfSDavid du Colombier if(d == 0) {
7567dd7cddfSDavid du Colombier a = FREGZERO;
7577dd7cddfSDavid du Colombier ffreg:
7587dd7cddfSDavid du Colombier nodreg(&nod, f, NREG+a);
7597dd7cddfSDavid du Colombier gmove(&nod, t);
7607dd7cddfSDavid du Colombier return;
7617dd7cddfSDavid du Colombier }
7627dd7cddfSDavid du Colombier }
7636891d857SDavid du Colombier if((ft == TVLONG || ft == TUVLONG) && f->op == OCONST && t->op == OREGPAIR) {
7646891d857SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
7656891d857SDavid du Colombier gmove(nod32const(f->vconst>>32), t->left);
7666891d857SDavid du Colombier else
7676891d857SDavid du Colombier gmove(nod32const(f->vconst), t->left);
7686891d857SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
7696891d857SDavid du Colombier gmove(nod32const(f->vconst), t->right);
7706891d857SDavid du Colombier else
7716891d857SDavid du Colombier gmove(nod32const(f->vconst>>32), t->right);
7726891d857SDavid du Colombier return;
7736891d857SDavid du Colombier }
7747dd7cddfSDavid du Colombier /*
7757dd7cddfSDavid du Colombier * a load --
7767dd7cddfSDavid du Colombier * put it into a register then
7777dd7cddfSDavid du Colombier * worry what to do with it.
7787dd7cddfSDavid du Colombier */
7797dd7cddfSDavid du Colombier if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
7807dd7cddfSDavid du Colombier switch(ft) {
7817dd7cddfSDavid du Colombier default:
7827dd7cddfSDavid du Colombier a = AMOVW;
7837dd7cddfSDavid du Colombier break;
7847dd7cddfSDavid du Colombier case TFLOAT:
7857dd7cddfSDavid du Colombier a = AFMOVS;
7867dd7cddfSDavid du Colombier break;
7877dd7cddfSDavid du Colombier case TDOUBLE:
7887dd7cddfSDavid du Colombier a = AFMOVD;
7897dd7cddfSDavid du Colombier break;
7907dd7cddfSDavid du Colombier case TCHAR:
7917dd7cddfSDavid du Colombier a = AMOVB;
7927dd7cddfSDavid du Colombier break;
7937dd7cddfSDavid du Colombier case TUCHAR:
7947dd7cddfSDavid du Colombier a = AMOVBZ;
7957dd7cddfSDavid du Colombier break;
7967dd7cddfSDavid du Colombier case TSHORT:
7977dd7cddfSDavid du Colombier a = AMOVH;
7987dd7cddfSDavid du Colombier break;
7997dd7cddfSDavid du Colombier case TUSHORT:
8007dd7cddfSDavid du Colombier a = AMOVHZ;
8017dd7cddfSDavid du Colombier break;
8027dd7cddfSDavid du Colombier }
8036891d857SDavid du Colombier if(typev[ft]) {
804*40d01547SDavid du Colombier if(typev[tt] || typefd[tt]) {
8056891d857SDavid du Colombier regalloc(&nod, f, t);
8066891d857SDavid du Colombier /* low order first, because its value will be used first */
8076891d857SDavid du Colombier f->xoffset += SZ_LONG;
8086891d857SDavid du Colombier gins(AMOVW, f, nod.right);
8096891d857SDavid du Colombier f->xoffset -= SZ_LONG;
8106891d857SDavid du Colombier gins(AMOVW, f, nod.left);
8116891d857SDavid du Colombier } else {
8126891d857SDavid du Colombier /* assumed not float or double */
8136891d857SDavid du Colombier regalloc(&nod, ®node, t);
8146891d857SDavid du Colombier f->xoffset += SZ_LONG;
8156891d857SDavid du Colombier gins(AMOVW, f, &nod);
8166891d857SDavid du Colombier f->xoffset -= SZ_LONG;
8176891d857SDavid du Colombier }
8186891d857SDavid du Colombier } else {
8197dd7cddfSDavid du Colombier regalloc(&nod, f, t);
8207dd7cddfSDavid du Colombier gins(a, f, &nod);
8216891d857SDavid du Colombier }
8227dd7cddfSDavid du Colombier gmove(&nod, t);
8237dd7cddfSDavid du Colombier regfree(&nod);
8247dd7cddfSDavid du Colombier return;
8257dd7cddfSDavid du Colombier }
8267dd7cddfSDavid du Colombier
8277dd7cddfSDavid du Colombier /*
8287dd7cddfSDavid du Colombier * a store --
8297dd7cddfSDavid du Colombier * put it into a register then
8307dd7cddfSDavid du Colombier * store it.
8317dd7cddfSDavid du Colombier */
8327dd7cddfSDavid du Colombier if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
8337dd7cddfSDavid du Colombier switch(tt) {
8347dd7cddfSDavid du Colombier default:
8357dd7cddfSDavid du Colombier a = AMOVW;
8367dd7cddfSDavid du Colombier break;
8377dd7cddfSDavid du Colombier case TUCHAR:
838375daca8SDavid du Colombier a = AMOVBZ;
839375daca8SDavid du Colombier break;
8407dd7cddfSDavid du Colombier case TCHAR:
8417dd7cddfSDavid du Colombier a = AMOVB;
8427dd7cddfSDavid du Colombier break;
8437dd7cddfSDavid du Colombier case TUSHORT:
844375daca8SDavid du Colombier a = AMOVHZ;
845375daca8SDavid du Colombier break;
8467dd7cddfSDavid du Colombier case TSHORT:
8477dd7cddfSDavid du Colombier a = AMOVH;
8487dd7cddfSDavid du Colombier break;
8497dd7cddfSDavid du Colombier case TFLOAT:
8507dd7cddfSDavid du Colombier a = AFMOVS;
8517dd7cddfSDavid du Colombier break;
8527dd7cddfSDavid du Colombier case TDOUBLE:
8537dd7cddfSDavid du Colombier a = AFMOVD;
8547dd7cddfSDavid du Colombier break;
8557dd7cddfSDavid du Colombier }
856375daca8SDavid du Colombier if(R0ISZERO && !typefd[ft] && vconst(f) == 0) {
8577dd7cddfSDavid du Colombier gins(a, f, t);
8586891d857SDavid du Colombier if(typev[tt]) {
8596891d857SDavid du Colombier t->xoffset += SZ_LONG;
8606891d857SDavid du Colombier gins(a, f, t);
8616891d857SDavid du Colombier t->xoffset -= SZ_LONG;
8626891d857SDavid du Colombier }
8637dd7cddfSDavid du Colombier return;
8647dd7cddfSDavid du Colombier }
8657dd7cddfSDavid du Colombier if(ft == tt)
8667dd7cddfSDavid du Colombier regalloc(&nod, t, f);
8677dd7cddfSDavid du Colombier else
8687dd7cddfSDavid du Colombier regalloc(&nod, t, Z);
8697dd7cddfSDavid du Colombier gmove(f, &nod);
8706891d857SDavid du Colombier if(typev[tt]) {
8716891d857SDavid du Colombier t->xoffset += SZ_LONG;
8726891d857SDavid du Colombier gins(a, nod.right, t);
8736891d857SDavid du Colombier t->xoffset -= SZ_LONG;
8746891d857SDavid du Colombier gins(a, nod.left, t);
8756891d857SDavid du Colombier } else
8767dd7cddfSDavid du Colombier gins(a, &nod, t);
8777dd7cddfSDavid du Colombier regfree(&nod);
8787dd7cddfSDavid du Colombier return;
8797dd7cddfSDavid du Colombier }
8807dd7cddfSDavid du Colombier
8817dd7cddfSDavid du Colombier /*
8827dd7cddfSDavid du Colombier * type x type cross table
8837dd7cddfSDavid du Colombier */
8847dd7cddfSDavid du Colombier a = AGOK;
8857dd7cddfSDavid du Colombier switch(ft) {
8867dd7cddfSDavid du Colombier case TDOUBLE:
8877dd7cddfSDavid du Colombier case TFLOAT:
8887dd7cddfSDavid du Colombier switch(tt) {
8897dd7cddfSDavid du Colombier case TDOUBLE:
8907dd7cddfSDavid du Colombier a = AFMOVD;
8917dd7cddfSDavid du Colombier if(ft == TFLOAT)
8927dd7cddfSDavid du Colombier a = AFMOVS; /* AFMOVSD */
8937dd7cddfSDavid du Colombier break;
8947dd7cddfSDavid du Colombier case TFLOAT:
8957dd7cddfSDavid du Colombier a = AFRSP;
8967dd7cddfSDavid du Colombier if(ft == TFLOAT)
8977dd7cddfSDavid du Colombier a = AFMOVS;
8987dd7cddfSDavid du Colombier break;
8997dd7cddfSDavid du Colombier case TINT:
9007dd7cddfSDavid du Colombier case TUINT:
9017dd7cddfSDavid du Colombier case TLONG:
9027dd7cddfSDavid du Colombier case TULONG:
9037dd7cddfSDavid du Colombier case TIND:
9047dd7cddfSDavid du Colombier case TSHORT:
9057dd7cddfSDavid du Colombier case TUSHORT:
9067dd7cddfSDavid du Colombier case TCHAR:
9077dd7cddfSDavid du Colombier case TUCHAR:
9087dd7cddfSDavid du Colombier /* BUG: not right for unsigned long */
909*40d01547SDavid du Colombier floattofix(f, t);
910*40d01547SDavid du Colombier return;
911*40d01547SDavid du Colombier case TVLONG:
912*40d01547SDavid du Colombier case TUVLONG:
913*40d01547SDavid du Colombier diag(f, "unimplemented double->vlong");
9147dd7cddfSDavid du Colombier return;
9157dd7cddfSDavid du Colombier }
9167dd7cddfSDavid du Colombier break;
9177dd7cddfSDavid du Colombier case TINT:
9187dd7cddfSDavid du Colombier case TUINT:
9197dd7cddfSDavid du Colombier case TLONG:
9207dd7cddfSDavid du Colombier case TULONG:
9217dd7cddfSDavid du Colombier case TIND:
9227dd7cddfSDavid du Colombier switch(tt) {
9237dd7cddfSDavid du Colombier case TDOUBLE:
9247dd7cddfSDavid du Colombier case TFLOAT:
925*40d01547SDavid du Colombier fixtofloat(f, t);
926*40d01547SDavid du Colombier return;
9277dd7cddfSDavid du Colombier case TINT:
9287dd7cddfSDavid du Colombier case TUINT:
9297dd7cddfSDavid du Colombier case TLONG:
9307dd7cddfSDavid du Colombier case TULONG:
9317dd7cddfSDavid du Colombier case TIND:
9327dd7cddfSDavid du Colombier case TSHORT:
9337dd7cddfSDavid du Colombier case TUSHORT:
9347dd7cddfSDavid du Colombier case TCHAR:
9357dd7cddfSDavid du Colombier case TUCHAR:
9367dd7cddfSDavid du Colombier a = AMOVW;
9377dd7cddfSDavid du Colombier break;
9387dd7cddfSDavid du Colombier }
9397dd7cddfSDavid du Colombier break;
9407dd7cddfSDavid du Colombier case TSHORT:
9417dd7cddfSDavid du Colombier switch(tt) {
9427dd7cddfSDavid du Colombier case TDOUBLE:
9437dd7cddfSDavid du Colombier case TFLOAT:
944*40d01547SDavid du Colombier fixtofloat(f, t);
945*40d01547SDavid du Colombier return;
9467dd7cddfSDavid du Colombier case TINT:
9477dd7cddfSDavid du Colombier case TUINT:
9487dd7cddfSDavid du Colombier case TLONG:
9497dd7cddfSDavid du Colombier case TULONG:
9507dd7cddfSDavid du Colombier case TIND:
9517dd7cddfSDavid du Colombier a = AMOVH;
9527dd7cddfSDavid du Colombier break;
9537dd7cddfSDavid du Colombier case TSHORT:
9547dd7cddfSDavid du Colombier case TUSHORT:
9557dd7cddfSDavid du Colombier case TCHAR:
9567dd7cddfSDavid du Colombier case TUCHAR:
9577dd7cddfSDavid du Colombier a = AMOVW;
9587dd7cddfSDavid du Colombier break;
9597dd7cddfSDavid du Colombier }
9607dd7cddfSDavid du Colombier break;
9617dd7cddfSDavid du Colombier case TUSHORT:
9627dd7cddfSDavid du Colombier switch(tt) {
9637dd7cddfSDavid du Colombier case TDOUBLE:
9647dd7cddfSDavid du Colombier case TFLOAT:
965*40d01547SDavid du Colombier fixtofloat(f, t);
966*40d01547SDavid du Colombier return;
9677dd7cddfSDavid du Colombier case TINT:
9687dd7cddfSDavid du Colombier case TUINT:
9697dd7cddfSDavid du Colombier case TLONG:
9707dd7cddfSDavid du Colombier case TULONG:
9717dd7cddfSDavid du Colombier case TIND:
9727dd7cddfSDavid du Colombier a = AMOVHZ;
9737dd7cddfSDavid du Colombier break;
9747dd7cddfSDavid du Colombier case TSHORT:
9757dd7cddfSDavid du Colombier case TUSHORT:
9767dd7cddfSDavid du Colombier case TCHAR:
9777dd7cddfSDavid du Colombier case TUCHAR:
9787dd7cddfSDavid du Colombier a = AMOVW;
9797dd7cddfSDavid du Colombier break;
9807dd7cddfSDavid du Colombier }
9817dd7cddfSDavid du Colombier break;
9827dd7cddfSDavid du Colombier case TCHAR:
9837dd7cddfSDavid du Colombier switch(tt) {
9847dd7cddfSDavid du Colombier case TDOUBLE:
9857dd7cddfSDavid du Colombier case TFLOAT:
986*40d01547SDavid du Colombier fixtofloat(f, t);
987*40d01547SDavid du Colombier return;
9887dd7cddfSDavid du Colombier case TINT:
9897dd7cddfSDavid du Colombier case TUINT:
9907dd7cddfSDavid du Colombier case TLONG:
9917dd7cddfSDavid du Colombier case TULONG:
9927dd7cddfSDavid du Colombier case TIND:
9937dd7cddfSDavid du Colombier case TSHORT:
9947dd7cddfSDavid du Colombier case TUSHORT:
9957dd7cddfSDavid du Colombier a = AMOVB;
9967dd7cddfSDavid du Colombier break;
9977dd7cddfSDavid du Colombier case TCHAR:
9987dd7cddfSDavid du Colombier case TUCHAR:
9997dd7cddfSDavid du Colombier a = AMOVW;
10007dd7cddfSDavid du Colombier break;
10017dd7cddfSDavid du Colombier }
10027dd7cddfSDavid du Colombier break;
10037dd7cddfSDavid du Colombier case TUCHAR:
10047dd7cddfSDavid du Colombier switch(tt) {
10057dd7cddfSDavid du Colombier case TDOUBLE:
10067dd7cddfSDavid du Colombier case TFLOAT:
1007*40d01547SDavid du Colombier fixtofloat(f, t);
10087dd7cddfSDavid du Colombier return;
10097dd7cddfSDavid du Colombier case TINT:
10107dd7cddfSDavid du Colombier case TUINT:
10117dd7cddfSDavid du Colombier case TLONG:
10127dd7cddfSDavid du Colombier case TULONG:
10137dd7cddfSDavid du Colombier case TIND:
10147dd7cddfSDavid du Colombier case TSHORT:
10157dd7cddfSDavid du Colombier case TUSHORT:
10167dd7cddfSDavid du Colombier a = AMOVBZ;
10177dd7cddfSDavid du Colombier break;
10187dd7cddfSDavid du Colombier case TCHAR:
10197dd7cddfSDavid du Colombier case TUCHAR:
10207dd7cddfSDavid du Colombier a = AMOVW;
10217dd7cddfSDavid du Colombier break;
10227dd7cddfSDavid du Colombier }
10237dd7cddfSDavid du Colombier break;
10246891d857SDavid du Colombier case TVLONG:
10256891d857SDavid du Colombier case TUVLONG:
10266891d857SDavid du Colombier switch(tt) {
10276891d857SDavid du Colombier case TVLONG:
10286891d857SDavid du Colombier case TUVLONG:
10296891d857SDavid du Colombier a = AMOVW;
10306891d857SDavid du Colombier break;
10316891d857SDavid du Colombier }
10326891d857SDavid du Colombier break;
10337dd7cddfSDavid du Colombier }
10347dd7cddfSDavid du Colombier if(a == AGOK)
10357dd7cddfSDavid du Colombier diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
10367dd7cddfSDavid du Colombier if(a == AMOVW || a == AFMOVS || a == AFMOVD)
10377dd7cddfSDavid du Colombier if(samaddr(f, t))
10387dd7cddfSDavid du Colombier return;
10396891d857SDavid du Colombier if(typev[ft]) {
10406891d857SDavid du Colombier if(f->op != OREGPAIR || t->op != OREGPAIR)
10416891d857SDavid du Colombier diag(Z, "bad vlong in gmove (%O->%O)", f->op, t->op);
10426891d857SDavid du Colombier gins(a, f->left, t->left);
10436891d857SDavid du Colombier gins(a, f->right, t->right);
10446891d857SDavid du Colombier } else
10457dd7cddfSDavid du Colombier gins(a, f, t);
10467dd7cddfSDavid du Colombier }
10477dd7cddfSDavid du Colombier
10487dd7cddfSDavid du Colombier void
gins(int a,Node * f,Node * t)10497dd7cddfSDavid du Colombier gins(int a, Node *f, Node *t)
10507dd7cddfSDavid du Colombier {
10517dd7cddfSDavid du Colombier
10527dd7cddfSDavid du Colombier nextpc();
10537dd7cddfSDavid du Colombier p->as = a;
10547dd7cddfSDavid du Colombier if(f != Z)
10557dd7cddfSDavid du Colombier naddr(f, &p->from);
10567dd7cddfSDavid du Colombier if(t != Z)
10577dd7cddfSDavid du Colombier naddr(t, &p->to);
10587dd7cddfSDavid du Colombier if(debug['g'])
10597dd7cddfSDavid du Colombier print("%P\n", p);
10607dd7cddfSDavid du Colombier }
10617dd7cddfSDavid du Colombier
10627dd7cddfSDavid du Colombier void
gins3(int a,Node * f1,Node * f2,Node * t)10636891d857SDavid du Colombier gins3(int a, Node *f1, Node *f2, Node *t)
10646891d857SDavid du Colombier {
10656891d857SDavid du Colombier Adr ta;
10666891d857SDavid du Colombier
10676891d857SDavid du Colombier nextpc();
10686891d857SDavid du Colombier p->as = a;
10696891d857SDavid du Colombier if(f1 != Z)
10706891d857SDavid du Colombier naddr(f1, &p->from);
10716891d857SDavid du Colombier if(f2 != Z && (f2->op != OREGISTER || !samaddr(f2, t))) {
10726891d857SDavid du Colombier ta = zprog.from; /* TO DO */
10736891d857SDavid du Colombier naddr(f2, &ta);
10746891d857SDavid du Colombier p->reg = ta.reg;
10756891d857SDavid du Colombier if(ta.type == D_CONST && ta.offset == 0) {
10766891d857SDavid du Colombier if(R0ISZERO)
10776891d857SDavid du Colombier p->reg = REGZERO;
10786891d857SDavid du Colombier else
10796891d857SDavid du Colombier diag(Z, "REGZERO in gins3 %A", a);
10806891d857SDavid du Colombier }else if(ta.type == D_CONST)
10816891d857SDavid du Colombier p->from3 = ta;
10826891d857SDavid du Colombier }
10836891d857SDavid du Colombier if(t != Z)
10846891d857SDavid du Colombier naddr(t, &p->to);
10856891d857SDavid du Colombier if(debug['g'])
10866891d857SDavid du Colombier print("%P\n", p);
10876891d857SDavid du Colombier }
10886891d857SDavid du Colombier
10896891d857SDavid du Colombier void
gins4(int a,Node * f1,Node * f2,Node * f3,Node * t)10906891d857SDavid du Colombier gins4(int a, Node *f1, Node *f2, Node *f3, Node *t)
10916891d857SDavid du Colombier {
10926891d857SDavid du Colombier Adr ta;
10936891d857SDavid du Colombier
10946891d857SDavid du Colombier nextpc();
10956891d857SDavid du Colombier p->as = a;
10966891d857SDavid du Colombier naddr(f1, &p->from);
10976891d857SDavid du Colombier if(f2->op != OREGISTER && (f2->op != OCONST || vconst(f2) != 0))
10986891d857SDavid du Colombier diag(f2, "invalid gins4");
10996891d857SDavid du Colombier naddr(f2, &ta);
11006891d857SDavid du Colombier p->reg = ta.reg;
11016891d857SDavid du Colombier if(ta.type == D_CONST && ta.offset == 0)
11026891d857SDavid du Colombier p->reg = REGZERO;
11036891d857SDavid du Colombier naddr(f3, &p->from3);
11046891d857SDavid du Colombier naddr(t, &p->to);
11056891d857SDavid du Colombier if(debug['g'])
11066891d857SDavid du Colombier print("%P\n", p);
11076891d857SDavid du Colombier }
11086891d857SDavid du Colombier
11096891d857SDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)11107dd7cddfSDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
11117dd7cddfSDavid du Colombier {
11126891d857SDavid du Colombier int a, et, uns;
11137dd7cddfSDavid du Colombier
11146891d857SDavid du Colombier if(o == OAS) {
11157dd7cddfSDavid du Colombier gmove(f1, t);
11167dd7cddfSDavid du Colombier return;
11176891d857SDavid du Colombier }
11186891d857SDavid du Colombier et = TLONG;
11196891d857SDavid du Colombier if(f1 != Z && f1->type != T) {
11206891d857SDavid du Colombier if(f1->op == OCONST && t != Z && t->type != T)
11216891d857SDavid du Colombier et = t->type->etype;
11226891d857SDavid du Colombier else
11236891d857SDavid du Colombier et = f1->type->etype;
11246891d857SDavid du Colombier }
11256891d857SDavid du Colombier if((typev[et] || t->type != T && typev[t->type->etype]) && o != OFUNC) {
11266891d857SDavid du Colombier gopcode64(o, f1, f2, t);
11276891d857SDavid du Colombier return;
11286891d857SDavid du Colombier }
11296891d857SDavid du Colombier uns = 0;
11306891d857SDavid du Colombier a = AGOK;
11316891d857SDavid du Colombier switch(o) {
11327dd7cddfSDavid du Colombier
11337dd7cddfSDavid du Colombier case OASADD:
11347dd7cddfSDavid du Colombier case OADD:
11357dd7cddfSDavid du Colombier a = AADD;
11367dd7cddfSDavid du Colombier if(et == TFLOAT)
11377dd7cddfSDavid du Colombier a = AFADDS;
11387dd7cddfSDavid du Colombier else
11395ede6b93SDavid du Colombier if(et == TDOUBLE)
11407dd7cddfSDavid du Colombier a = AFADD;
11417dd7cddfSDavid du Colombier break;
11427dd7cddfSDavid du Colombier
11437dd7cddfSDavid du Colombier case OASSUB:
11447dd7cddfSDavid du Colombier case OSUB:
11457dd7cddfSDavid du Colombier a = ASUB;
11467dd7cddfSDavid du Colombier if(et == TFLOAT)
11477dd7cddfSDavid du Colombier a = AFSUBS;
11487dd7cddfSDavid du Colombier else
11495ede6b93SDavid du Colombier if(et == TDOUBLE)
11507dd7cddfSDavid du Colombier a = AFSUB;
11517dd7cddfSDavid du Colombier break;
11527dd7cddfSDavid du Colombier
11537dd7cddfSDavid du Colombier case OASOR:
11547dd7cddfSDavid du Colombier case OOR:
11557dd7cddfSDavid du Colombier a = AOR;
11567dd7cddfSDavid du Colombier break;
11577dd7cddfSDavid du Colombier
11587dd7cddfSDavid du Colombier case OASAND:
11597dd7cddfSDavid du Colombier case OAND:
11607dd7cddfSDavid du Colombier a = AAND;
11617dd7cddfSDavid du Colombier if(f1->op == OCONST)
11627dd7cddfSDavid du Colombier a = AANDCC;
11637dd7cddfSDavid du Colombier break;
11647dd7cddfSDavid du Colombier
11657dd7cddfSDavid du Colombier case OASXOR:
11667dd7cddfSDavid du Colombier case OXOR:
11677dd7cddfSDavid du Colombier a = AXOR;
11687dd7cddfSDavid du Colombier break;
11697dd7cddfSDavid du Colombier
11707dd7cddfSDavid du Colombier case OASLSHR:
11717dd7cddfSDavid du Colombier case OLSHR:
11727dd7cddfSDavid du Colombier a = ASRW;
11737dd7cddfSDavid du Colombier break;
11747dd7cddfSDavid du Colombier
11757dd7cddfSDavid du Colombier case OASASHR:
11767dd7cddfSDavid du Colombier case OASHR:
11777dd7cddfSDavid du Colombier a = ASRAW;
11787dd7cddfSDavid du Colombier break;
11797dd7cddfSDavid du Colombier
11807dd7cddfSDavid du Colombier case OASASHL:
11817dd7cddfSDavid du Colombier case OASHL:
11826891d857SDavid du Colombier a = ASLW;
11837dd7cddfSDavid du Colombier break;
11847dd7cddfSDavid du Colombier
11857dd7cddfSDavid du Colombier case OFUNC:
11867dd7cddfSDavid du Colombier a = ABL;
11877dd7cddfSDavid du Colombier break;
11887dd7cddfSDavid du Colombier
11897dd7cddfSDavid du Colombier case OASLMUL:
11907dd7cddfSDavid du Colombier case OLMUL:
11917dd7cddfSDavid du Colombier case OASMUL:
11927dd7cddfSDavid du Colombier case OMUL:
11937dd7cddfSDavid du Colombier if(et == TFLOAT) {
11947dd7cddfSDavid du Colombier a = AFMULS;
11957dd7cddfSDavid du Colombier break;
11967dd7cddfSDavid du Colombier } else
11975ede6b93SDavid du Colombier if(et == TDOUBLE) {
11987dd7cddfSDavid du Colombier a = AFMUL;
11997dd7cddfSDavid du Colombier break;
12007dd7cddfSDavid du Colombier }
12017dd7cddfSDavid du Colombier a = AMULLW;
12027dd7cddfSDavid du Colombier break;
12037dd7cddfSDavid du Colombier
12047dd7cddfSDavid du Colombier case OASDIV:
12057dd7cddfSDavid du Colombier case ODIV:
12067dd7cddfSDavid du Colombier if(et == TFLOAT) {
12077dd7cddfSDavid du Colombier a = AFDIVS;
12087dd7cddfSDavid du Colombier break;
12097dd7cddfSDavid du Colombier } else
12105ede6b93SDavid du Colombier if(et == TDOUBLE) {
12117dd7cddfSDavid du Colombier a = AFDIV;
12127dd7cddfSDavid du Colombier break;
12137dd7cddfSDavid du Colombier }
12147dd7cddfSDavid du Colombier a = ADIVW;
12157dd7cddfSDavid du Colombier break;
12167dd7cddfSDavid du Colombier
12177dd7cddfSDavid du Colombier case OASMOD:
12187dd7cddfSDavid du Colombier case OMOD:
12197dd7cddfSDavid du Colombier a = AREM;
12207dd7cddfSDavid du Colombier break;
12217dd7cddfSDavid du Colombier
12227dd7cddfSDavid du Colombier case OASLMOD:
12237dd7cddfSDavid du Colombier case OLMOD:
12247dd7cddfSDavid du Colombier a = AREMU;
12257dd7cddfSDavid du Colombier break;
12267dd7cddfSDavid du Colombier
12277dd7cddfSDavid du Colombier case OASLDIV:
12287dd7cddfSDavid du Colombier case OLDIV:
12297dd7cddfSDavid du Colombier a = ADIVWU;
12307dd7cddfSDavid du Colombier break;
12317dd7cddfSDavid du Colombier
12327dd7cddfSDavid du Colombier case OCOM:
12337dd7cddfSDavid du Colombier a = ANOR;
12347dd7cddfSDavid du Colombier break;
12357dd7cddfSDavid du Colombier
12367dd7cddfSDavid du Colombier case ONEG:
12377dd7cddfSDavid du Colombier a = ANEG;
12385ede6b93SDavid du Colombier if(et == TFLOAT || et == TDOUBLE)
12397dd7cddfSDavid du Colombier a = AFNEG;
12407dd7cddfSDavid du Colombier break;
12417dd7cddfSDavid du Colombier
12427dd7cddfSDavid du Colombier case OEQ:
12437dd7cddfSDavid du Colombier a = ABEQ;
12446891d857SDavid du Colombier if(t->op == OCONST && t->vconst >= (1<<15))
12456891d857SDavid du Colombier goto cmpu;
12467dd7cddfSDavid du Colombier goto cmp;
12477dd7cddfSDavid du Colombier
12487dd7cddfSDavid du Colombier case ONE:
12497dd7cddfSDavid du Colombier a = ABNE;
12506891d857SDavid du Colombier if(t->op == OCONST && t->vconst >= (1<<15))
12516891d857SDavid du Colombier goto cmpu;
12527dd7cddfSDavid du Colombier goto cmp;
12537dd7cddfSDavid du Colombier
12547dd7cddfSDavid du Colombier case OLT:
12557dd7cddfSDavid du Colombier a = ABLT;
12567dd7cddfSDavid du Colombier goto cmp;
12577dd7cddfSDavid du Colombier
12587dd7cddfSDavid du Colombier case OLE:
12597dd7cddfSDavid du Colombier a = ABLE;
12607dd7cddfSDavid du Colombier goto cmp;
12617dd7cddfSDavid du Colombier
12627dd7cddfSDavid du Colombier case OGE:
12637dd7cddfSDavid du Colombier a = ABGE;
12647dd7cddfSDavid du Colombier goto cmp;
12657dd7cddfSDavid du Colombier
12667dd7cddfSDavid du Colombier case OGT:
12677dd7cddfSDavid du Colombier a = ABGT;
12687dd7cddfSDavid du Colombier goto cmp;
12697dd7cddfSDavid du Colombier
12707dd7cddfSDavid du Colombier case OLO:
12717dd7cddfSDavid du Colombier a = ABLT;
12727dd7cddfSDavid du Colombier goto cmpu;
12737dd7cddfSDavid du Colombier
12747dd7cddfSDavid du Colombier case OLS:
12757dd7cddfSDavid du Colombier a = ABLE;
12767dd7cddfSDavid du Colombier goto cmpu;
12777dd7cddfSDavid du Colombier
12787dd7cddfSDavid du Colombier case OHS:
12797dd7cddfSDavid du Colombier a = ABGE;
12807dd7cddfSDavid du Colombier goto cmpu;
12817dd7cddfSDavid du Colombier
12827dd7cddfSDavid du Colombier case OHI:
12837dd7cddfSDavid du Colombier a = ABGT;
12847dd7cddfSDavid du Colombier goto cmpu;
12857dd7cddfSDavid du Colombier
12867dd7cddfSDavid du Colombier cmpu:
12877dd7cddfSDavid du Colombier uns = 1;
12887dd7cddfSDavid du Colombier cmp:
12897dd7cddfSDavid du Colombier nextpc();
12907dd7cddfSDavid du Colombier p->as = uns? ACMPU: ACMP;
12917dd7cddfSDavid du Colombier if(et == TFLOAT)
12927dd7cddfSDavid du Colombier p->as = AFCMPU;
12937dd7cddfSDavid du Colombier else
12945ede6b93SDavid du Colombier if(et == TDOUBLE)
12957dd7cddfSDavid du Colombier p->as = AFCMPU;
12967dd7cddfSDavid du Colombier if(f1 != Z)
12977dd7cddfSDavid du Colombier naddr(f1, &p->from);
12987dd7cddfSDavid du Colombier if(t != Z)
12997dd7cddfSDavid du Colombier naddr(t, &p->to);
13007dd7cddfSDavid du Colombier if(f1 == Z || t == Z || f2 != Z)
13017dd7cddfSDavid du Colombier diag(Z, "bad cmp in gopcode %O", o);
13027dd7cddfSDavid du Colombier if(debug['g'])
13037dd7cddfSDavid du Colombier print("%P\n", p);
13047dd7cddfSDavid du Colombier f1 = Z;
13057dd7cddfSDavid du Colombier f2 = Z;
13067dd7cddfSDavid du Colombier t = Z;
13077dd7cddfSDavid du Colombier break;
13087dd7cddfSDavid du Colombier }
13097dd7cddfSDavid du Colombier if(a == AGOK)
13107dd7cddfSDavid du Colombier diag(Z, "bad in gopcode %O", o);
13116891d857SDavid du Colombier gins3(a, f1, f2, t);
13126891d857SDavid du Colombier }
13136891d857SDavid du Colombier
13146891d857SDavid du Colombier static void
gopcode64(int o,Node * f1,Node * f2,Node * t)13156891d857SDavid du Colombier gopcode64(int o, Node *f1, Node *f2, Node *t)
13166891d857SDavid du Colombier {
13176891d857SDavid du Colombier int a1, a2;
13186891d857SDavid du Colombier Node nod, nod1, nod2, sh;
13196891d857SDavid du Colombier ulong m;
13206891d857SDavid du Colombier Prog *p1;
13216891d857SDavid du Colombier
13226891d857SDavid du Colombier if(t->op != OREGPAIR || f2 != Z && f2->op != OREGPAIR) {
13236891d857SDavid du Colombier diag(Z, "bad f2/dest in gopcode64 %O", o);
13246891d857SDavid du Colombier return;
13256891d857SDavid du Colombier }
13266891d857SDavid du Colombier if(f1->op != OCONST &&
13276891d857SDavid du Colombier (typev[f1->type->etype] && f1->op != OREGPAIR || !typev[f1->type->etype] && f1->op != OREGISTER)) {
13286891d857SDavid du Colombier diag(Z, "bad f1[%O] in gopcode64 %O", f1->op, o);
13296891d857SDavid du Colombier return;
13306891d857SDavid du Colombier }
13316891d857SDavid du Colombier /* a1 for low-order, a2 for high-order */
13326891d857SDavid du Colombier a1 = AGOK;
13336891d857SDavid du Colombier a2 = AGOK;
13346891d857SDavid du Colombier switch(o) {
13356891d857SDavid du Colombier case OASADD:
13366891d857SDavid du Colombier case OADD:
13376891d857SDavid du Colombier if(f1->op == OCONST && sconst(f1)) {
13386891d857SDavid du Colombier if(f2 == Z)
13396891d857SDavid du Colombier f2 = t;
13406891d857SDavid du Colombier gins3(AADDC, f1, f2->right, t->right);
13416891d857SDavid du Colombier if((f1->vconst>>32) == 0)
13426891d857SDavid du Colombier gins(AADDZE, f2->left, t->left);
13436891d857SDavid du Colombier else if((f1->vconst>>32) == -1)
13446891d857SDavid du Colombier gins(AADDME, f2->left, t->left);
1345375daca8SDavid du Colombier else
13466891d857SDavid du Colombier diag(t, "odd vlong ADD: %lld", f1->vconst);
13476891d857SDavid du Colombier return;
13486891d857SDavid du Colombier }
13496891d857SDavid du Colombier a1 = AADDC;
13506891d857SDavid du Colombier a2 = AADDE;
13516891d857SDavid du Colombier break;
13526891d857SDavid du Colombier
13536891d857SDavid du Colombier case OASSUB:
13546891d857SDavid du Colombier case OSUB:
13556891d857SDavid du Colombier a1 = ASUBC;
13566891d857SDavid du Colombier a2 = ASUBE;
13576891d857SDavid du Colombier break;
13586891d857SDavid du Colombier
13596891d857SDavid du Colombier case OASOR:
13606891d857SDavid du Colombier case OOR:
13616891d857SDavid du Colombier if(f1->op == OCONST) {
13626891d857SDavid du Colombier gori64(AOR, f1, f2, t);
13636891d857SDavid du Colombier return;
13646891d857SDavid du Colombier }
13656891d857SDavid du Colombier a1 = a2 = AOR;
13666891d857SDavid du Colombier break;
13676891d857SDavid du Colombier
13686891d857SDavid du Colombier case OASAND:
13696891d857SDavid du Colombier case OAND:
13706891d857SDavid du Colombier if(f1->op == OCONST) {
13716891d857SDavid du Colombier gandi64(AANDCC, f1, f2, t);
13726891d857SDavid du Colombier return;
13736891d857SDavid du Colombier }
13746891d857SDavid du Colombier a1 = a2 = AAND;
13756891d857SDavid du Colombier break;
13766891d857SDavid du Colombier
13776891d857SDavid du Colombier case OASXOR:
13786891d857SDavid du Colombier case OXOR:
13796891d857SDavid du Colombier if(f1->op == OCONST) {
13806891d857SDavid du Colombier gori64(AXOR, f1, f2, t);
13816891d857SDavid du Colombier return;
13826891d857SDavid du Colombier }
13836891d857SDavid du Colombier a1 = a2 = AXOR;
13846891d857SDavid du Colombier break;
13856891d857SDavid du Colombier
13866891d857SDavid du Colombier case OASLSHR:
13876891d857SDavid du Colombier case OLSHR:
13886891d857SDavid du Colombier if(f2 == Z)
13896891d857SDavid du Colombier f2 = t;
13906891d857SDavid du Colombier if(f1->op == OCONST) {
13916891d857SDavid du Colombier if(f1->vconst >= 32) {
13926891d857SDavid du Colombier if(f1->vconst == 32)
13936891d857SDavid du Colombier gmove(f2->left, t->right);
13946891d857SDavid du Colombier else if(f1->vconst < 64)
13956891d857SDavid du Colombier gins3(ASRW, nodconst(f1->vconst-32), f2->left, t->right);
13966891d857SDavid du Colombier else
13976891d857SDavid du Colombier gmove(nodconst(0), t->right);
13986891d857SDavid du Colombier gmove(nodconst(0), t->left);
13996891d857SDavid du Colombier return;
14006891d857SDavid du Colombier }
14016891d857SDavid du Colombier if(f1->vconst <= 0) {
14026891d857SDavid du Colombier if(f2 != t)
14036891d857SDavid du Colombier gmove(f2, t);
14046891d857SDavid du Colombier return;
14056891d857SDavid du Colombier }
14066891d857SDavid du Colombier sh = *nodconst(32 - f1->vconst);
14076891d857SDavid du Colombier m = 0xFFFFFFFFUL >> f1->vconst;
14086891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
14096891d857SDavid du Colombier gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
14106891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->left, nodconst(m), t->left);
14116891d857SDavid du Colombier return;
14126891d857SDavid du Colombier }
14136891d857SDavid du Colombier regalloc(&nod, ®node, Z);
14146891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
14156891d857SDavid du Colombier gins3(ASRW, f1, f2->right, t->right);
14166891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
14176891d857SDavid du Colombier gins3(ASLW, &nod, f2->left, &nod1);
14186891d857SDavid du Colombier gins(AOR, &nod1, t->right);
14196891d857SDavid du Colombier gins3(AADD, nodconst(-32), f1, &nod);
14206891d857SDavid du Colombier gins3(ASRW, &nod, f2->left, &nod1);
14216891d857SDavid du Colombier gins(AOR, &nod1, t->right);
14226891d857SDavid du Colombier gins3(ASRW, f1, f2->left, t->left);
14236891d857SDavid du Colombier regfree(&nod);
14246891d857SDavid du Colombier regfree(&nod1);
14256891d857SDavid du Colombier return;
14266891d857SDavid du Colombier
14276891d857SDavid du Colombier case OASASHR:
14286891d857SDavid du Colombier case OASHR:
14296891d857SDavid du Colombier if(f2 == Z)
14306891d857SDavid du Colombier f2 = t;
14316891d857SDavid du Colombier if(f1->op == OCONST) {
14326891d857SDavid du Colombier if(f1->vconst >= 32) {
14336891d857SDavid du Colombier if(f1->vconst == 32)
14346891d857SDavid du Colombier gmove(f2->left, t->right);
14356891d857SDavid du Colombier else if(f1->vconst < 64)
14366891d857SDavid du Colombier gins3(ASRAW, nodconst(f1->vconst-32), f2->left, t->right);
14376891d857SDavid du Colombier gins3(ASRAW, nodconst(31), f2->left, t->left);
14386891d857SDavid du Colombier if(f1->vconst >= 64) {
14396891d857SDavid du Colombier gmove(t->left, t->right);
14406891d857SDavid du Colombier return;
14416891d857SDavid du Colombier }
14426891d857SDavid du Colombier return;
14436891d857SDavid du Colombier }
14446891d857SDavid du Colombier if(f1->vconst <= 0) {
14456891d857SDavid du Colombier if(f2 != t)
14466891d857SDavid du Colombier gmove(f2, t);
14476891d857SDavid du Colombier return;
14486891d857SDavid du Colombier }
14496891d857SDavid du Colombier sh = *nodconst(32 - f1->vconst);
14506891d857SDavid du Colombier m = 0xFFFFFFFFUL >> f1->vconst;
14516891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
14526891d857SDavid du Colombier gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
14536891d857SDavid du Colombier gins3(ASRAW, &sh, f2->left, t->left);
14546891d857SDavid du Colombier return;
14556891d857SDavid du Colombier }
14566891d857SDavid du Colombier regalloc(&nod, ®node, Z);
14576891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
14586891d857SDavid du Colombier gins3(ASRW, f1, f2->right, t->right);
14596891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
14606891d857SDavid du Colombier gins3(ASLW, &nod, f2->left, &nod1);
14616891d857SDavid du Colombier gins(AOR, &nod1, t->right);
14626891d857SDavid du Colombier gins3(AADDCCC, nodconst(-32), f1, &nod);
14636891d857SDavid du Colombier gins3(ASRAW, &nod, f2->left, &nod1);
14646891d857SDavid du Colombier gins(ABLE, Z, Z);
14656891d857SDavid du Colombier p1 = p;
14666891d857SDavid du Colombier gins(AMOVW, &nod1, t->right);
14676891d857SDavid du Colombier patch(p1, pc);
14686891d857SDavid du Colombier gins3(ASRAW, f1, f2->left, t->left);
14696891d857SDavid du Colombier regfree(&nod);
14706891d857SDavid du Colombier regfree(&nod1);
14716891d857SDavid du Colombier return;
14726891d857SDavid du Colombier
14736891d857SDavid du Colombier case OASASHL:
14746891d857SDavid du Colombier case OASHL:
14756891d857SDavid du Colombier if(f2 == Z)
14766891d857SDavid du Colombier f2 = t;
14776891d857SDavid du Colombier if(f1->op == OCONST) {
14786891d857SDavid du Colombier if(f1->vconst >= 32) {
14796891d857SDavid du Colombier if(f1->vconst == 32)
14806891d857SDavid du Colombier gmove(f2->right, t->left);
14816891d857SDavid du Colombier else if(f1->vconst >= 64)
14826891d857SDavid du Colombier gmove(nodconst(0), t->left);
14836891d857SDavid du Colombier else
14846891d857SDavid du Colombier gins3(ASLW, nodconst(f1->vconst-32), f2->right, t->left);
14856891d857SDavid du Colombier gmove(nodconst(0), t->right);
14866891d857SDavid du Colombier return;
14876891d857SDavid du Colombier }
14886891d857SDavid du Colombier if(f1->vconst <= 0) {
14896891d857SDavid du Colombier if(f2 != t)
14906891d857SDavid du Colombier gmove(f2, t);
14916891d857SDavid du Colombier return;
14926891d857SDavid du Colombier }
14936891d857SDavid du Colombier m = 0xFFFFFFFFUL << f1->vconst;
14946891d857SDavid du Colombier gins4(ARLWNM, f1, f2->left, nodconst(m), t->left);
14956891d857SDavid du Colombier gins4(ARLWMI, f1, f2->right, nodconst(~m), t->left);
14966891d857SDavid du Colombier gins4(ARLWNM, f1, f2->right, nodconst(m), t->right);
14976891d857SDavid du Colombier return;
14986891d857SDavid du Colombier }
14996891d857SDavid du Colombier regalloc(&nod, ®node, Z);
15006891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
15016891d857SDavid du Colombier gins3(ASLW, f1, f2->left, t->left);
15026891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
15036891d857SDavid du Colombier gins3(ASRW, &nod, f2->right, &nod1);
15046891d857SDavid du Colombier gins(AOR, &nod1, t->left);
15056891d857SDavid du Colombier gins3(AADD, nodconst(-32), f1, &nod);
15066891d857SDavid du Colombier gins3(ASLW, &nod, f2->right, &nod1);
15076891d857SDavid du Colombier gins(AOR, &nod1, t->left);
15086891d857SDavid du Colombier gins3(ASLW, f1, f2->right, t->right);
15096891d857SDavid du Colombier regfree(&nod);
15106891d857SDavid du Colombier regfree(&nod1);
15116891d857SDavid du Colombier return;
15126891d857SDavid du Colombier
15136891d857SDavid du Colombier case OASLMUL:
15146891d857SDavid du Colombier case OLMUL:
15156891d857SDavid du Colombier case OASMUL:
15166891d857SDavid du Colombier case OMUL:
15176891d857SDavid du Colombier if(f2 == Z)
15186891d857SDavid du Colombier f2 = t;
15196891d857SDavid du Colombier regalloc(&nod, ®node, Z);
15206891d857SDavid du Colombier gins3(AMULLW, f1->right, f2->right, &nod); /* lo(f2.low*f1.low) */
15216891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
15221ebfca79SDavid du Colombier gins3(AMULHWU, f1->right, f2->right, &nod1); /* hi(f2.low*f1.low) */
15236891d857SDavid du Colombier regalloc(&nod2, ®node, Z);
15246891d857SDavid du Colombier gins3(AMULLW, f2->right, f1->left, &nod2); /* lo(f2.low*f1.high) */
15256891d857SDavid du Colombier gins(AADD, &nod2, &nod1);
15261ebfca79SDavid du Colombier gins3(AMULLW, f1->right, f2->left, &nod2); /* lo(f2.high*f1.low) */
15276891d857SDavid du Colombier gins(AADD, &nod2, &nod1);
15286891d857SDavid du Colombier regfree(&nod2);
15296891d857SDavid du Colombier gmove(&nod, t->right);
15306891d857SDavid du Colombier gmove(&nod1, t->left);
15316891d857SDavid du Colombier regfree(&nod);
15326891d857SDavid du Colombier regfree(&nod1);
15336891d857SDavid du Colombier return;
15346891d857SDavid du Colombier
15356891d857SDavid du Colombier case OCOM:
15366891d857SDavid du Colombier a1 = a2 = ANOR;
15376891d857SDavid du Colombier break;
15386891d857SDavid du Colombier
15396891d857SDavid du Colombier case ONEG:
15406891d857SDavid du Colombier gins3(ASUBC, t->right, nodconst(0), t->right);
15416891d857SDavid du Colombier gins(ASUBZE, t->left, t->left);
15426891d857SDavid du Colombier return;
15436891d857SDavid du Colombier }
15446891d857SDavid du Colombier if(a1 == AGOK || a2 == AGOK)
15456891d857SDavid du Colombier diag(Z, "bad in gopcode64 %O", o);
15466891d857SDavid du Colombier if(f1->op == OCONST) {
15476891d857SDavid du Colombier if(f2 != Z & f2 != t)
15486891d857SDavid du Colombier diag(Z, "bad const in gopcode64 %O", o);
15496891d857SDavid du Colombier gins(a1, nod32const(f1->vconst), t->right);
15506891d857SDavid du Colombier gins(a2, nod32const(f1->vconst>>32), t->left);
15516891d857SDavid du Colombier } else {
15526891d857SDavid du Colombier if(f2 != Z && f2 != t) {
15536891d857SDavid du Colombier gins3(a1, f1->right, f2->right, t->right);
15546891d857SDavid du Colombier gins3(a2, f1->left, f2->left, t->left);
15556891d857SDavid du Colombier } else {
15566891d857SDavid du Colombier gins(a1, f1->right, t->right);
15576891d857SDavid du Colombier gins(a2, f1->left, t->left);
1558375daca8SDavid du Colombier }
15597dd7cddfSDavid du Colombier }
15607dd7cddfSDavid du Colombier }
15617dd7cddfSDavid du Colombier
samaddr(Node * f,Node * t)15627dd7cddfSDavid du Colombier samaddr(Node *f, Node *t)
15637dd7cddfSDavid du Colombier {
15647dd7cddfSDavid du Colombier
15657dd7cddfSDavid du Colombier if(f->op != t->op)
15667dd7cddfSDavid du Colombier return 0;
15677dd7cddfSDavid du Colombier switch(f->op) {
15687dd7cddfSDavid du Colombier
15697dd7cddfSDavid du Colombier case OREGISTER:
15707dd7cddfSDavid du Colombier if(f->reg != t->reg)
15717dd7cddfSDavid du Colombier break;
15727dd7cddfSDavid du Colombier return 1;
15736891d857SDavid du Colombier
15746891d857SDavid du Colombier case OREGPAIR:
15756891d857SDavid du Colombier return samaddr(f->left, t->left) && samaddr(f->right, t->right);
15767dd7cddfSDavid du Colombier }
15777dd7cddfSDavid du Colombier return 0;
15787dd7cddfSDavid du Colombier }
15797dd7cddfSDavid du Colombier
15806891d857SDavid du Colombier static void
gori64(int a,Node * f1,Node * f2,Node * t)15816891d857SDavid du Colombier gori64(int a, Node *f1, Node *f2, Node *t)
15826891d857SDavid du Colombier {
15836891d857SDavid du Colombier ulong lo, hi;
15846891d857SDavid du Colombier
15856891d857SDavid du Colombier if(f2 == Z)
15866891d857SDavid du Colombier f2 = t;
15876891d857SDavid du Colombier lo = f1->vconst & MASK(32);
15886891d857SDavid du Colombier hi = (f1->vconst >> 32) & MASK(32);
15896891d857SDavid du Colombier if(lo & 0xFFFF)
15906891d857SDavid du Colombier gins3(a, nodconst(lo & 0xFFFF), f2->right, t->right);
15916891d857SDavid du Colombier if((lo >> 16) != 0)
15926891d857SDavid du Colombier gins3(a, nodconst(lo & 0xFFFF0000UL), f2->right, t->right);
15936891d857SDavid du Colombier if(hi & 0xFFFF)
15946891d857SDavid du Colombier gins3(a, nodconst(hi & 0xFFFF), f2->left, t->left);
15956891d857SDavid du Colombier if((hi >> 16) != 0)
15966891d857SDavid du Colombier gins3(a, nodconst(hi & 0xFFFF0000UL), f2->left, t->left);
15976891d857SDavid du Colombier }
15986891d857SDavid du Colombier
15996891d857SDavid du Colombier static void
gandi64(int a,Node * f1,Node * f2,Node * t)16006891d857SDavid du Colombier gandi64(int a, Node *f1, Node *f2, Node *t)
16016891d857SDavid du Colombier {
16026891d857SDavid du Colombier ulong lo, hi;
16036891d857SDavid du Colombier
16046891d857SDavid du Colombier if(f2 == Z)
16056891d857SDavid du Colombier f2 = t;
16066891d857SDavid du Colombier lo = f1->vconst & MASK(32);
16076891d857SDavid du Colombier hi = (f1->vconst >> 32) & MASK(32);
16086891d857SDavid du Colombier if(lo == 0)
16096891d857SDavid du Colombier gins(AMOVW, nodconst(0), t->right);
16106891d857SDavid du Colombier else
16116891d857SDavid du Colombier gins3(a, nodconst(lo), f2->right, t->right);
16126891d857SDavid du Colombier if(hi == 0)
16136891d857SDavid du Colombier gins(AMOVW, nodconst(0), t->left);
16146891d857SDavid du Colombier else
16156891d857SDavid du Colombier gins3(a, nodconst(hi), f2->left, t->left);
16166891d857SDavid du Colombier }
16176891d857SDavid du Colombier
16187dd7cddfSDavid du Colombier void
gbranch(int o)16197dd7cddfSDavid du Colombier gbranch(int o)
16207dd7cddfSDavid du Colombier {
16217dd7cddfSDavid du Colombier int a;
16227dd7cddfSDavid du Colombier
16237dd7cddfSDavid du Colombier a = AGOK;
16247dd7cddfSDavid du Colombier switch(o) {
16257dd7cddfSDavid du Colombier case ORETURN:
16267dd7cddfSDavid du Colombier a = ARETURN;
16277dd7cddfSDavid du Colombier break;
16287dd7cddfSDavid du Colombier case OGOTO:
16297dd7cddfSDavid du Colombier a = ABR;
16307dd7cddfSDavid du Colombier break;
16317dd7cddfSDavid du Colombier }
16327dd7cddfSDavid du Colombier nextpc();
16337dd7cddfSDavid du Colombier if(a == AGOK) {
16347dd7cddfSDavid du Colombier diag(Z, "bad in gbranch %O", o);
16357dd7cddfSDavid du Colombier nextpc();
16367dd7cddfSDavid du Colombier }
16377dd7cddfSDavid du Colombier p->as = a;
16387dd7cddfSDavid du Colombier }
16397dd7cddfSDavid du Colombier
16407dd7cddfSDavid du Colombier void
patch(Prog * op,long pc)16417dd7cddfSDavid du Colombier patch(Prog *op, long pc)
16427dd7cddfSDavid du Colombier {
16437dd7cddfSDavid du Colombier
16447dd7cddfSDavid du Colombier op->to.offset = pc;
16457dd7cddfSDavid du Colombier op->to.type = D_BRANCH;
16467dd7cddfSDavid du Colombier }
16477dd7cddfSDavid du Colombier
16487dd7cddfSDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)16497dd7cddfSDavid du Colombier gpseudo(int a, Sym *s, Node *n)
16507dd7cddfSDavid du Colombier {
16517dd7cddfSDavid du Colombier
16527dd7cddfSDavid du Colombier nextpc();
16537dd7cddfSDavid du Colombier p->as = a;
16547dd7cddfSDavid du Colombier p->from.type = D_OREG;
16557dd7cddfSDavid du Colombier p->from.sym = s;
16565ede6b93SDavid du Colombier if(a == ATEXT)
1657e288d156SDavid du Colombier p->reg = (profileflg ? 0 : NOPROF);
16587dd7cddfSDavid du Colombier p->from.name = D_EXTERN;
16597dd7cddfSDavid du Colombier if(s->class == CSTATIC)
16607dd7cddfSDavid du Colombier p->from.name = D_STATIC;
16617dd7cddfSDavid du Colombier naddr(n, &p->to);
16627dd7cddfSDavid du Colombier if(a == ADATA || a == AGLOBL)
16637dd7cddfSDavid du Colombier pc--;
16647dd7cddfSDavid du Colombier }
16657dd7cddfSDavid du Colombier
16667dd7cddfSDavid du Colombier int
sval(long v)16677dd7cddfSDavid du Colombier sval(long v)
16687dd7cddfSDavid du Colombier {
16697dd7cddfSDavid du Colombier
16707dd7cddfSDavid du Colombier if(v >= -(1<<15) && v < (1<<15))
16717dd7cddfSDavid du Colombier return 1;
16727dd7cddfSDavid du Colombier return 0;
16737dd7cddfSDavid du Colombier }
16747dd7cddfSDavid du Colombier
16757dd7cddfSDavid du Colombier int
sconst(Node * n)16767dd7cddfSDavid du Colombier sconst(Node *n)
16777dd7cddfSDavid du Colombier {
16787dd7cddfSDavid du Colombier vlong vv;
16797dd7cddfSDavid du Colombier
16807dd7cddfSDavid du Colombier if(n->op == OCONST) {
16817dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
16827dd7cddfSDavid du Colombier vv = n->vconst;
1683375daca8SDavid du Colombier if(vv >= -(((vlong)1)<<15) && vv < (((vlong)1)<<15))
16847dd7cddfSDavid du Colombier return 1;
16857dd7cddfSDavid du Colombier }
16867dd7cddfSDavid du Colombier }
16877dd7cddfSDavid du Colombier return 0;
16887dd7cddfSDavid du Colombier }
16897dd7cddfSDavid du Colombier
16907dd7cddfSDavid du Colombier int
uconst(Node * n)16917dd7cddfSDavid du Colombier uconst(Node *n)
16927dd7cddfSDavid du Colombier {
16937dd7cddfSDavid du Colombier vlong vv;
16947dd7cddfSDavid du Colombier
16957dd7cddfSDavid du Colombier if(n->op == OCONST) {
16967dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
16977dd7cddfSDavid du Colombier vv = n->vconst;
1698375daca8SDavid du Colombier if(vv >= 0 && vv < (((vlong)1)<<16))
16997dd7cddfSDavid du Colombier return 1;
17007dd7cddfSDavid du Colombier }
17017dd7cddfSDavid du Colombier }
17027dd7cddfSDavid du Colombier return 0;
17037dd7cddfSDavid du Colombier }
17047dd7cddfSDavid du Colombier
17057dd7cddfSDavid du Colombier long
exreg(Type * t)17067dd7cddfSDavid du Colombier exreg(Type *t)
17077dd7cddfSDavid du Colombier {
17087dd7cddfSDavid du Colombier long o;
17097dd7cddfSDavid du Colombier
17107dd7cddfSDavid du Colombier if(typechlp[t->etype]) {
17117dd7cddfSDavid du Colombier if(exregoffset <= 3)
17127dd7cddfSDavid du Colombier return 0;
17137dd7cddfSDavid du Colombier o = exregoffset;
17147dd7cddfSDavid du Colombier exregoffset--;
17157dd7cddfSDavid du Colombier return o;
17167dd7cddfSDavid du Colombier }
17177dd7cddfSDavid du Colombier if(typefd[t->etype]) {
17187dd7cddfSDavid du Colombier if(exfregoffset <= 16)
17197dd7cddfSDavid du Colombier return 0;
17207dd7cddfSDavid du Colombier o = exfregoffset + NREG;
17217dd7cddfSDavid du Colombier exfregoffset--;
17227dd7cddfSDavid du Colombier return o;
17237dd7cddfSDavid du Colombier }
17247dd7cddfSDavid du Colombier return 0;
17257dd7cddfSDavid du Colombier }
17267dd7cddfSDavid du Colombier
17277dd7cddfSDavid du Colombier schar ewidth[NTYPE] =
17287dd7cddfSDavid du Colombier {
17297dd7cddfSDavid du Colombier -1, /* [TXXX] */
17307dd7cddfSDavid du Colombier SZ_CHAR, /* [TCHAR] */
17317dd7cddfSDavid du Colombier SZ_CHAR, /* [TUCHAR] */
17327dd7cddfSDavid du Colombier SZ_SHORT, /* [TSHORT] */
17337dd7cddfSDavid du Colombier SZ_SHORT, /* [TUSHORT] */
17347dd7cddfSDavid du Colombier SZ_INT, /* [TINT] */
17357dd7cddfSDavid du Colombier SZ_INT, /* [TUINT] */
17367dd7cddfSDavid du Colombier SZ_LONG, /* [TLONG] */
17377dd7cddfSDavid du Colombier SZ_LONG, /* [TULONG] */
17387dd7cddfSDavid du Colombier SZ_VLONG, /* [TVLONG] */
17397dd7cddfSDavid du Colombier SZ_VLONG, /* [TUVLONG] */
17407dd7cddfSDavid du Colombier SZ_FLOAT, /* [TFLOAT] */
17417dd7cddfSDavid du Colombier SZ_DOUBLE, /* [TDOUBLE] */
17427dd7cddfSDavid du Colombier SZ_IND, /* [TIND] */
17437dd7cddfSDavid du Colombier 0, /* [TFUNC] */
17447dd7cddfSDavid du Colombier -1, /* [TARRAY] */
17457dd7cddfSDavid du Colombier 0, /* [TVOID] */
17467dd7cddfSDavid du Colombier -1, /* [TSTRUCT] */
17477dd7cddfSDavid du Colombier -1, /* [TUNION] */
17487dd7cddfSDavid du Colombier SZ_INT, /* [TENUM] */
17497dd7cddfSDavid du Colombier };
17507dd7cddfSDavid du Colombier long ncast[NTYPE] =
17517dd7cddfSDavid du Colombier {
17527dd7cddfSDavid du Colombier 0, /* [TXXX] */
17537dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TCHAR] */
17547dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TUCHAR] */
17557dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TSHORT] */
17567dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TUSHORT] */
17577dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
17587dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
17597dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
17607dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
17617dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TVLONG] */
17627dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TUVLONG] */
17637dd7cddfSDavid du Colombier BFLOAT, /* [TFLOAT] */
17647dd7cddfSDavid du Colombier BDOUBLE, /* [TDOUBLE] */
17657dd7cddfSDavid du Colombier BLONG|BULONG|BIND, /* [TIND] */
17667dd7cddfSDavid du Colombier 0, /* [TFUNC] */
17677dd7cddfSDavid du Colombier 0, /* [TARRAY] */
17687dd7cddfSDavid du Colombier 0, /* [TVOID] */
17697dd7cddfSDavid du Colombier BSTRUCT, /* [TSTRUCT] */
17707dd7cddfSDavid du Colombier BUNION, /* [TUNION] */
17717dd7cddfSDavid du Colombier 0, /* [TENUM] */
17727dd7cddfSDavid du Colombier };
1773