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;
18*3a276d32SDavid 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
31*3a276d32SDavid du Colombier typeswitch = typechlv;
32*3a276d32SDavid 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
6257dd7cddfSDavid du Colombier void
gmove(Node * f,Node * t)6267dd7cddfSDavid du Colombier gmove(Node *f, Node *t)
6277dd7cddfSDavid du Colombier {
6287dd7cddfSDavid du Colombier int ft, tt, a;
629375daca8SDavid du Colombier Node nod, fxc0, fxc1, fxc2, fxrat;
6307dd7cddfSDavid du Colombier Prog *p1;
6317dd7cddfSDavid du Colombier double d;
6327dd7cddfSDavid du Colombier
6337dd7cddfSDavid du Colombier ft = f->type->etype;
6347dd7cddfSDavid du Colombier tt = t->type->etype;
6357dd7cddfSDavid du Colombier
6367dd7cddfSDavid du Colombier if(ft == TDOUBLE && f->op == OCONST) {
6377dd7cddfSDavid du Colombier d = f->fconst;
6387dd7cddfSDavid du Colombier if(d == 0.0) {
6397dd7cddfSDavid du Colombier a = FREGZERO;
6407dd7cddfSDavid du Colombier goto ffreg;
6417dd7cddfSDavid du Colombier }
6427dd7cddfSDavid du Colombier if(d == 0.5) {
6437dd7cddfSDavid du Colombier a = FREGHALF;
6447dd7cddfSDavid du Colombier goto ffreg;
6457dd7cddfSDavid du Colombier }
6467dd7cddfSDavid du Colombier if(d == 1.0) {
6477dd7cddfSDavid du Colombier a = FREGONE;
6487dd7cddfSDavid du Colombier goto ffreg;
6497dd7cddfSDavid du Colombier }
6507dd7cddfSDavid du Colombier if(d == 2.0) {
6517dd7cddfSDavid du Colombier a = FREGTWO;
6527dd7cddfSDavid du Colombier goto ffreg;
6537dd7cddfSDavid du Colombier }
6547dd7cddfSDavid du Colombier if(d == -.5) {
6557dd7cddfSDavid du Colombier fop(OSUB, FREGHALF, FREGZERO, t);
6567dd7cddfSDavid du Colombier return;
6577dd7cddfSDavid du Colombier }
6587dd7cddfSDavid du Colombier if(d == -1.0) {
6597dd7cddfSDavid du Colombier fop(OSUB, FREGONE, FREGZERO, t);
6607dd7cddfSDavid du Colombier return;
6617dd7cddfSDavid du Colombier }
6627dd7cddfSDavid du Colombier if(d == -2.0) {
6637dd7cddfSDavid du Colombier fop(OSUB, FREGTWO, FREGZERO, t);
6647dd7cddfSDavid du Colombier return;
6657dd7cddfSDavid du Colombier }
6667dd7cddfSDavid du Colombier if(d == 1.5) {
6677dd7cddfSDavid du Colombier fop(OADD, FREGONE, FREGHALF, t);
6687dd7cddfSDavid du Colombier return;
6697dd7cddfSDavid du Colombier }
6707dd7cddfSDavid du Colombier if(d == 2.5) {
6717dd7cddfSDavid du Colombier fop(OADD, FREGTWO, FREGHALF, t);
6727dd7cddfSDavid du Colombier return;
6737dd7cddfSDavid du Colombier }
6747dd7cddfSDavid du Colombier if(d == 3.0) {
6757dd7cddfSDavid du Colombier fop(OADD, FREGTWO, FREGONE, t);
6767dd7cddfSDavid du Colombier return;
6777dd7cddfSDavid du Colombier }
6787dd7cddfSDavid du Colombier }
6797dd7cddfSDavid du Colombier if(ft == TFLOAT && f->op == OCONST) {
6807dd7cddfSDavid du Colombier d = f->fconst;
6817dd7cddfSDavid du Colombier if(d == 0) {
6827dd7cddfSDavid du Colombier a = FREGZERO;
6837dd7cddfSDavid du Colombier ffreg:
6847dd7cddfSDavid du Colombier nodreg(&nod, f, NREG+a);
6857dd7cddfSDavid du Colombier gmove(&nod, t);
6867dd7cddfSDavid du Colombier return;
6877dd7cddfSDavid du Colombier }
6887dd7cddfSDavid du Colombier }
6896891d857SDavid du Colombier if((ft == TVLONG || ft == TUVLONG) && f->op == OCONST && t->op == OREGPAIR) {
6906891d857SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
6916891d857SDavid du Colombier gmove(nod32const(f->vconst>>32), t->left);
6926891d857SDavid du Colombier else
6936891d857SDavid du Colombier gmove(nod32const(f->vconst), t->left);
6946891d857SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
6956891d857SDavid du Colombier gmove(nod32const(f->vconst), t->right);
6966891d857SDavid du Colombier else
6976891d857SDavid du Colombier gmove(nod32const(f->vconst>>32), t->right);
6986891d857SDavid du Colombier return;
6996891d857SDavid du Colombier }
7007dd7cddfSDavid du Colombier /*
7017dd7cddfSDavid du Colombier * a load --
7027dd7cddfSDavid du Colombier * put it into a register then
7037dd7cddfSDavid du Colombier * worry what to do with it.
7047dd7cddfSDavid du Colombier */
7057dd7cddfSDavid du Colombier if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
7067dd7cddfSDavid du Colombier switch(ft) {
7077dd7cddfSDavid du Colombier default:
7087dd7cddfSDavid du Colombier a = AMOVW;
7097dd7cddfSDavid du Colombier break;
7107dd7cddfSDavid du Colombier case TFLOAT:
7117dd7cddfSDavid du Colombier a = AFMOVS;
7127dd7cddfSDavid du Colombier break;
7137dd7cddfSDavid du Colombier case TDOUBLE:
7147dd7cddfSDavid du Colombier a = AFMOVD;
7157dd7cddfSDavid du Colombier break;
7167dd7cddfSDavid du Colombier case TCHAR:
7177dd7cddfSDavid du Colombier a = AMOVB;
7187dd7cddfSDavid du Colombier break;
7197dd7cddfSDavid du Colombier case TUCHAR:
7207dd7cddfSDavid du Colombier a = AMOVBZ;
7217dd7cddfSDavid du Colombier break;
7227dd7cddfSDavid du Colombier case TSHORT:
7237dd7cddfSDavid du Colombier a = AMOVH;
7247dd7cddfSDavid du Colombier break;
7257dd7cddfSDavid du Colombier case TUSHORT:
7267dd7cddfSDavid du Colombier a = AMOVHZ;
7277dd7cddfSDavid du Colombier break;
7287dd7cddfSDavid du Colombier }
7296891d857SDavid du Colombier if(typev[ft]) {
7306891d857SDavid du Colombier if(typev[tt]) {
7316891d857SDavid du Colombier regalloc(&nod, f, t);
7326891d857SDavid du Colombier /* low order first, because its value will be used first */
7336891d857SDavid du Colombier f->xoffset += SZ_LONG;
7346891d857SDavid du Colombier gins(AMOVW, f, nod.right);
7356891d857SDavid du Colombier f->xoffset -= SZ_LONG;
7366891d857SDavid du Colombier gins(AMOVW, f, nod.left);
7376891d857SDavid du Colombier } else {
7386891d857SDavid du Colombier /* assumed not float or double */
7396891d857SDavid du Colombier regalloc(&nod, ®node, t);
7406891d857SDavid du Colombier f->xoffset += SZ_LONG;
7416891d857SDavid du Colombier gins(AMOVW, f, &nod);
7426891d857SDavid du Colombier f->xoffset -= SZ_LONG;
7436891d857SDavid du Colombier }
7446891d857SDavid du Colombier } else {
7457dd7cddfSDavid du Colombier regalloc(&nod, f, t);
7467dd7cddfSDavid du Colombier gins(a, f, &nod);
7476891d857SDavid du Colombier }
7487dd7cddfSDavid du Colombier gmove(&nod, t);
7497dd7cddfSDavid du Colombier regfree(&nod);
7507dd7cddfSDavid du Colombier return;
7517dd7cddfSDavid du Colombier }
7527dd7cddfSDavid du Colombier
7537dd7cddfSDavid du Colombier /*
7547dd7cddfSDavid du Colombier * a store --
7557dd7cddfSDavid du Colombier * put it into a register then
7567dd7cddfSDavid du Colombier * store it.
7577dd7cddfSDavid du Colombier */
7587dd7cddfSDavid du Colombier if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
7597dd7cddfSDavid du Colombier switch(tt) {
7607dd7cddfSDavid du Colombier default:
7617dd7cddfSDavid du Colombier a = AMOVW;
7627dd7cddfSDavid du Colombier break;
7637dd7cddfSDavid du Colombier case TUCHAR:
764375daca8SDavid du Colombier a = AMOVBZ;
765375daca8SDavid du Colombier break;
7667dd7cddfSDavid du Colombier case TCHAR:
7677dd7cddfSDavid du Colombier a = AMOVB;
7687dd7cddfSDavid du Colombier break;
7697dd7cddfSDavid du Colombier case TUSHORT:
770375daca8SDavid du Colombier a = AMOVHZ;
771375daca8SDavid du Colombier break;
7727dd7cddfSDavid du Colombier case TSHORT:
7737dd7cddfSDavid du Colombier a = AMOVH;
7747dd7cddfSDavid du Colombier break;
7757dd7cddfSDavid du Colombier case TFLOAT:
7767dd7cddfSDavid du Colombier a = AFMOVS;
7777dd7cddfSDavid du Colombier break;
7787dd7cddfSDavid du Colombier case TDOUBLE:
7797dd7cddfSDavid du Colombier a = AFMOVD;
7807dd7cddfSDavid du Colombier break;
7817dd7cddfSDavid du Colombier }
782375daca8SDavid du Colombier if(R0ISZERO && !typefd[ft] && vconst(f) == 0) {
7837dd7cddfSDavid du Colombier gins(a, f, t);
7846891d857SDavid du Colombier if(typev[tt]) {
7856891d857SDavid du Colombier t->xoffset += SZ_LONG;
7866891d857SDavid du Colombier gins(a, f, t);
7876891d857SDavid du Colombier t->xoffset -= SZ_LONG;
7886891d857SDavid du Colombier }
7897dd7cddfSDavid du Colombier return;
7907dd7cddfSDavid du Colombier }
7917dd7cddfSDavid du Colombier if(ft == tt)
7927dd7cddfSDavid du Colombier regalloc(&nod, t, f);
7937dd7cddfSDavid du Colombier else
7947dd7cddfSDavid du Colombier regalloc(&nod, t, Z);
7957dd7cddfSDavid du Colombier gmove(f, &nod);
7966891d857SDavid du Colombier if(typev[tt]) {
7976891d857SDavid du Colombier t->xoffset += SZ_LONG;
7986891d857SDavid du Colombier gins(a, nod.right, t);
7996891d857SDavid du Colombier t->xoffset -= SZ_LONG;
8006891d857SDavid du Colombier gins(a, nod.left, t);
8016891d857SDavid du Colombier } else
8027dd7cddfSDavid du Colombier gins(a, &nod, t);
8037dd7cddfSDavid du Colombier regfree(&nod);
8047dd7cddfSDavid du Colombier return;
8057dd7cddfSDavid du Colombier }
8067dd7cddfSDavid du Colombier
8077dd7cddfSDavid du Colombier /*
8087dd7cddfSDavid du Colombier * type x type cross table
8097dd7cddfSDavid du Colombier */
8107dd7cddfSDavid du Colombier a = AGOK;
8117dd7cddfSDavid du Colombier switch(ft) {
8127dd7cddfSDavid du Colombier case TDOUBLE:
8137dd7cddfSDavid du Colombier case TFLOAT:
8147dd7cddfSDavid du Colombier switch(tt) {
8157dd7cddfSDavid du Colombier case TDOUBLE:
8167dd7cddfSDavid du Colombier a = AFMOVD;
8177dd7cddfSDavid du Colombier if(ft == TFLOAT)
8187dd7cddfSDavid du Colombier a = AFMOVS; /* AFMOVSD */
8197dd7cddfSDavid du Colombier break;
8207dd7cddfSDavid du Colombier case TFLOAT:
8217dd7cddfSDavid du Colombier a = AFRSP;
8227dd7cddfSDavid du Colombier if(ft == TFLOAT)
8237dd7cddfSDavid du Colombier a = AFMOVS;
8247dd7cddfSDavid du Colombier break;
8257dd7cddfSDavid du Colombier case TINT:
8267dd7cddfSDavid du Colombier case TUINT:
8277dd7cddfSDavid du Colombier case TLONG:
8287dd7cddfSDavid du Colombier case TULONG:
8297dd7cddfSDavid du Colombier case TIND:
8307dd7cddfSDavid du Colombier case TSHORT:
8317dd7cddfSDavid du Colombier case TUSHORT:
8327dd7cddfSDavid du Colombier case TCHAR:
8337dd7cddfSDavid du Colombier case TUCHAR:
8347dd7cddfSDavid du Colombier /* BUG: not right for unsigned long */
8357dd7cddfSDavid du Colombier regalloc(&nod, f, Z); /* should be type float */
8366891d857SDavid du Colombier regsalloc(&fxrat, &fconstnode);
8377dd7cddfSDavid du Colombier gins(AFCTIWZ, f, &nod);
838375daca8SDavid du Colombier gins(AFMOVD, &nod, &fxrat);
8397dd7cddfSDavid du Colombier regfree(&nod);
840375daca8SDavid du Colombier fxrat.type = nodrat->type;
841375daca8SDavid du Colombier fxrat.etype = nodrat->etype;
842375daca8SDavid du Colombier fxrat.xoffset += 4;
843375daca8SDavid du Colombier gins(AMOVW, &fxrat, t);
8447dd7cddfSDavid du Colombier gmove(t, t);
8457dd7cddfSDavid du Colombier return;
8467dd7cddfSDavid du Colombier }
8477dd7cddfSDavid du Colombier break;
8487dd7cddfSDavid du Colombier case TINT:
8497dd7cddfSDavid du Colombier case TUINT:
8507dd7cddfSDavid du Colombier case TLONG:
8517dd7cddfSDavid du Colombier case TULONG:
8527dd7cddfSDavid du Colombier case TIND:
8537dd7cddfSDavid du Colombier switch(tt) {
8547dd7cddfSDavid du Colombier case TDOUBLE:
8557dd7cddfSDavid du Colombier case TFLOAT:
8567dd7cddfSDavid du Colombier goto fxtofl;
8577dd7cddfSDavid du Colombier case TINT:
8587dd7cddfSDavid du Colombier case TUINT:
8597dd7cddfSDavid du Colombier case TLONG:
8607dd7cddfSDavid du Colombier case TULONG:
8617dd7cddfSDavid du Colombier case TIND:
8627dd7cddfSDavid du Colombier case TSHORT:
8637dd7cddfSDavid du Colombier case TUSHORT:
8647dd7cddfSDavid du Colombier case TCHAR:
8657dd7cddfSDavid du Colombier case TUCHAR:
8667dd7cddfSDavid du Colombier a = AMOVW;
8677dd7cddfSDavid du Colombier break;
8687dd7cddfSDavid du Colombier }
8697dd7cddfSDavid du Colombier break;
8707dd7cddfSDavid du Colombier case TSHORT:
8717dd7cddfSDavid du Colombier switch(tt) {
8727dd7cddfSDavid du Colombier case TDOUBLE:
8737dd7cddfSDavid du Colombier case TFLOAT:
8747dd7cddfSDavid du Colombier goto fxtofl;
8757dd7cddfSDavid du Colombier case TINT:
8767dd7cddfSDavid du Colombier case TUINT:
8777dd7cddfSDavid du Colombier case TLONG:
8787dd7cddfSDavid du Colombier case TULONG:
8797dd7cddfSDavid du Colombier case TIND:
8807dd7cddfSDavid du Colombier a = AMOVH;
8817dd7cddfSDavid du Colombier break;
8827dd7cddfSDavid du Colombier case TSHORT:
8837dd7cddfSDavid du Colombier case TUSHORT:
8847dd7cddfSDavid du Colombier case TCHAR:
8857dd7cddfSDavid du Colombier case TUCHAR:
8867dd7cddfSDavid du Colombier a = AMOVW;
8877dd7cddfSDavid du Colombier break;
8887dd7cddfSDavid du Colombier }
8897dd7cddfSDavid du Colombier break;
8907dd7cddfSDavid du Colombier case TUSHORT:
8917dd7cddfSDavid du Colombier switch(tt) {
8927dd7cddfSDavid du Colombier case TDOUBLE:
8937dd7cddfSDavid du Colombier case TFLOAT:
8947dd7cddfSDavid du Colombier goto fxtofl;
8957dd7cddfSDavid du Colombier case TINT:
8967dd7cddfSDavid du Colombier case TUINT:
8977dd7cddfSDavid du Colombier case TLONG:
8987dd7cddfSDavid du Colombier case TULONG:
8997dd7cddfSDavid du Colombier case TIND:
9007dd7cddfSDavid du Colombier a = AMOVHZ;
9017dd7cddfSDavid du Colombier break;
9027dd7cddfSDavid du Colombier case TSHORT:
9037dd7cddfSDavid du Colombier case TUSHORT:
9047dd7cddfSDavid du Colombier case TCHAR:
9057dd7cddfSDavid du Colombier case TUCHAR:
9067dd7cddfSDavid du Colombier a = AMOVW;
9077dd7cddfSDavid du Colombier break;
9087dd7cddfSDavid du Colombier }
9097dd7cddfSDavid du Colombier break;
9107dd7cddfSDavid du Colombier case TCHAR:
9117dd7cddfSDavid du Colombier switch(tt) {
9127dd7cddfSDavid du Colombier case TDOUBLE:
9137dd7cddfSDavid du Colombier case TFLOAT:
9147dd7cddfSDavid du Colombier goto fxtofl;
9157dd7cddfSDavid du Colombier case TINT:
9167dd7cddfSDavid du Colombier case TUINT:
9177dd7cddfSDavid du Colombier case TLONG:
9187dd7cddfSDavid du Colombier case TULONG:
9197dd7cddfSDavid du Colombier case TIND:
9207dd7cddfSDavid du Colombier case TSHORT:
9217dd7cddfSDavid du Colombier case TUSHORT:
9227dd7cddfSDavid du Colombier a = AMOVB;
9237dd7cddfSDavid du Colombier break;
9247dd7cddfSDavid du Colombier case TCHAR:
9257dd7cddfSDavid du Colombier case TUCHAR:
9267dd7cddfSDavid du Colombier a = AMOVW;
9277dd7cddfSDavid du Colombier break;
9287dd7cddfSDavid du Colombier }
9297dd7cddfSDavid du Colombier break;
9307dd7cddfSDavid du Colombier case TUCHAR:
9317dd7cddfSDavid du Colombier switch(tt) {
9327dd7cddfSDavid du Colombier case TDOUBLE:
9337dd7cddfSDavid du Colombier case TFLOAT:
9347dd7cddfSDavid du Colombier fxtofl:
9357dd7cddfSDavid du Colombier /*
9367dd7cddfSDavid du Colombier * rat[0] = 0x43300000; rat[1] = f^0x80000000;
9377dd7cddfSDavid du Colombier * t = *(double*)rat - FREGCVI;
9387dd7cddfSDavid du Colombier * is-unsigned(t) => if(t<0) t += 2^32;
9397dd7cddfSDavid du Colombier * could be streamlined for int-to-float
9407dd7cddfSDavid du Colombier */
9417dd7cddfSDavid du Colombier regalloc(&fxc0, f, Z);
9427dd7cddfSDavid du Colombier regalloc(&fxc2, f, Z);
9436891d857SDavid du Colombier regsalloc(&fxrat, &fconstnode); /* should be type float */
9447dd7cddfSDavid du Colombier gins(AMOVW, nodconst(0x43300000L), &fxc0);
9457dd7cddfSDavid du Colombier gins(AMOVW, f, &fxc2);
946375daca8SDavid du Colombier gins(AMOVW, &fxc0, &fxrat);
9477dd7cddfSDavid du Colombier gins(AXOR, nodconst(0x80000000L), &fxc2);
948375daca8SDavid du Colombier fxc1 = fxrat;
949375daca8SDavid du Colombier fxc1.type = nodrat->type;
950375daca8SDavid du Colombier fxc1.etype = nodrat->etype;
9517dd7cddfSDavid du Colombier fxc1.xoffset += SZ_LONG;
9527dd7cddfSDavid du Colombier gins(AMOVW, &fxc2, &fxc1);
9537dd7cddfSDavid du Colombier regfree(&fxc2);
9547dd7cddfSDavid du Colombier regfree(&fxc0);
9557dd7cddfSDavid du Colombier regalloc(&nod, t, t); /* should be type float */
956375daca8SDavid du Colombier gins(AFMOVD, &fxrat, &nod);
9577dd7cddfSDavid du Colombier nodreg(&fxc1, t, NREG+FREGCVI);
9587dd7cddfSDavid du Colombier gins(AFSUB, &fxc1, &nod);
9597dd7cddfSDavid du Colombier a = AFMOVD;
9607dd7cddfSDavid du Colombier if(tt == TFLOAT)
9617dd7cddfSDavid du Colombier a = AFRSP;
9627dd7cddfSDavid du Colombier gins(a, &nod, t);
9637dd7cddfSDavid du Colombier regfree(&nod);
9647dd7cddfSDavid du Colombier if(ft == TULONG) {
9657dd7cddfSDavid du Colombier regalloc(&nod, t, Z);
9667dd7cddfSDavid du Colombier if(tt == TFLOAT) {
9677dd7cddfSDavid du Colombier gins(AFCMPU, t, Z);
9687dd7cddfSDavid du Colombier p->to.type = D_FREG;
9697dd7cddfSDavid du Colombier p->to.reg = FREGZERO;
9707dd7cddfSDavid du Colombier gins(ABGE, Z, Z);
9717dd7cddfSDavid du Colombier p1 = p;
9727dd7cddfSDavid du Colombier gins(AFMOVS, nodfconst(4294967296.), &nod);
9737dd7cddfSDavid du Colombier gins(AFADDS, &nod, t);
9747dd7cddfSDavid du Colombier } else {
9757dd7cddfSDavid du Colombier gins(AFCMPU, t, Z);
9767dd7cddfSDavid du Colombier p->to.type = D_FREG;
9777dd7cddfSDavid du Colombier p->to.reg = FREGZERO;
9787dd7cddfSDavid du Colombier gins(ABGE, Z, Z);
9797dd7cddfSDavid du Colombier p1 = p;
9807dd7cddfSDavid du Colombier gins(AFMOVD, nodfconst(4294967296.), &nod);
9817dd7cddfSDavid du Colombier gins(AFADD, &nod, t);
9827dd7cddfSDavid du Colombier }
9837dd7cddfSDavid du Colombier patch(p1, pc);
9847dd7cddfSDavid du Colombier regfree(&nod);
9857dd7cddfSDavid du Colombier }
9867dd7cddfSDavid du Colombier return;
9877dd7cddfSDavid du Colombier case TINT:
9887dd7cddfSDavid du Colombier case TUINT:
9897dd7cddfSDavid du Colombier case TLONG:
9907dd7cddfSDavid du Colombier case TULONG:
9917dd7cddfSDavid du Colombier case TIND:
9927dd7cddfSDavid du Colombier case TSHORT:
9937dd7cddfSDavid du Colombier case TUSHORT:
9947dd7cddfSDavid du Colombier a = AMOVBZ;
9957dd7cddfSDavid du Colombier break;
9967dd7cddfSDavid du Colombier case TCHAR:
9977dd7cddfSDavid du Colombier case TUCHAR:
9987dd7cddfSDavid du Colombier a = AMOVW;
9997dd7cddfSDavid du Colombier break;
10007dd7cddfSDavid du Colombier }
10017dd7cddfSDavid du Colombier break;
10026891d857SDavid du Colombier case TVLONG:
10036891d857SDavid du Colombier case TUVLONG:
10046891d857SDavid du Colombier switch(tt) {
10056891d857SDavid du Colombier case TVLONG:
10066891d857SDavid du Colombier case TUVLONG:
10076891d857SDavid du Colombier a = AMOVW;
10086891d857SDavid du Colombier break;
10096891d857SDavid du Colombier }
10106891d857SDavid du Colombier break;
10117dd7cddfSDavid du Colombier }
10127dd7cddfSDavid du Colombier if(a == AGOK)
10137dd7cddfSDavid du Colombier diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
10147dd7cddfSDavid du Colombier if(a == AMOVW || a == AFMOVS || a == AFMOVD)
10157dd7cddfSDavid du Colombier if(samaddr(f, t))
10167dd7cddfSDavid du Colombier return;
10176891d857SDavid du Colombier if(typev[ft]) {
10186891d857SDavid du Colombier if(f->op != OREGPAIR || t->op != OREGPAIR)
10196891d857SDavid du Colombier diag(Z, "bad vlong in gmove (%O->%O)", f->op, t->op);
10206891d857SDavid du Colombier gins(a, f->left, t->left);
10216891d857SDavid du Colombier gins(a, f->right, t->right);
10226891d857SDavid du Colombier } else
10237dd7cddfSDavid du Colombier gins(a, f, t);
10247dd7cddfSDavid du Colombier }
10257dd7cddfSDavid du Colombier
10267dd7cddfSDavid du Colombier void
gins(int a,Node * f,Node * t)10277dd7cddfSDavid du Colombier gins(int a, Node *f, Node *t)
10287dd7cddfSDavid du Colombier {
10297dd7cddfSDavid du Colombier
10307dd7cddfSDavid du Colombier nextpc();
10317dd7cddfSDavid du Colombier p->as = a;
10327dd7cddfSDavid du Colombier if(f != Z)
10337dd7cddfSDavid du Colombier naddr(f, &p->from);
10347dd7cddfSDavid du Colombier if(t != Z)
10357dd7cddfSDavid du Colombier naddr(t, &p->to);
10367dd7cddfSDavid du Colombier if(debug['g'])
10377dd7cddfSDavid du Colombier print("%P\n", p);
10387dd7cddfSDavid du Colombier }
10397dd7cddfSDavid du Colombier
10407dd7cddfSDavid du Colombier void
gins3(int a,Node * f1,Node * f2,Node * t)10416891d857SDavid du Colombier gins3(int a, Node *f1, Node *f2, Node *t)
10426891d857SDavid du Colombier {
10436891d857SDavid du Colombier Adr ta;
10446891d857SDavid du Colombier
10456891d857SDavid du Colombier nextpc();
10466891d857SDavid du Colombier p->as = a;
10476891d857SDavid du Colombier if(f1 != Z)
10486891d857SDavid du Colombier naddr(f1, &p->from);
10496891d857SDavid du Colombier if(f2 != Z && (f2->op != OREGISTER || !samaddr(f2, t))) {
10506891d857SDavid du Colombier ta = zprog.from; /* TO DO */
10516891d857SDavid du Colombier naddr(f2, &ta);
10526891d857SDavid du Colombier p->reg = ta.reg;
10536891d857SDavid du Colombier if(ta.type == D_CONST && ta.offset == 0) {
10546891d857SDavid du Colombier if(R0ISZERO)
10556891d857SDavid du Colombier p->reg = REGZERO;
10566891d857SDavid du Colombier else
10576891d857SDavid du Colombier diag(Z, "REGZERO in gins3 %A", a);
10586891d857SDavid du Colombier }else if(ta.type == D_CONST)
10596891d857SDavid du Colombier p->from3 = ta;
10606891d857SDavid du Colombier }
10616891d857SDavid du Colombier if(t != Z)
10626891d857SDavid du Colombier naddr(t, &p->to);
10636891d857SDavid du Colombier if(debug['g'])
10646891d857SDavid du Colombier print("%P\n", p);
10656891d857SDavid du Colombier }
10666891d857SDavid du Colombier
10676891d857SDavid du Colombier void
gins4(int a,Node * f1,Node * f2,Node * f3,Node * t)10686891d857SDavid du Colombier gins4(int a, Node *f1, Node *f2, Node *f3, Node *t)
10696891d857SDavid du Colombier {
10706891d857SDavid du Colombier Adr ta;
10716891d857SDavid du Colombier
10726891d857SDavid du Colombier nextpc();
10736891d857SDavid du Colombier p->as = a;
10746891d857SDavid du Colombier naddr(f1, &p->from);
10756891d857SDavid du Colombier if(f2->op != OREGISTER && (f2->op != OCONST || vconst(f2) != 0))
10766891d857SDavid du Colombier diag(f2, "invalid gins4");
10776891d857SDavid du Colombier naddr(f2, &ta);
10786891d857SDavid du Colombier p->reg = ta.reg;
10796891d857SDavid du Colombier if(ta.type == D_CONST && ta.offset == 0)
10806891d857SDavid du Colombier p->reg = REGZERO;
10816891d857SDavid du Colombier naddr(f3, &p->from3);
10826891d857SDavid du Colombier naddr(t, &p->to);
10836891d857SDavid du Colombier if(debug['g'])
10846891d857SDavid du Colombier print("%P\n", p);
10856891d857SDavid du Colombier }
10866891d857SDavid du Colombier
10876891d857SDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)10887dd7cddfSDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
10897dd7cddfSDavid du Colombier {
10906891d857SDavid du Colombier int a, et, uns;
10917dd7cddfSDavid du Colombier
10926891d857SDavid du Colombier if(o == OAS) {
10937dd7cddfSDavid du Colombier gmove(f1, t);
10947dd7cddfSDavid du Colombier return;
10956891d857SDavid du Colombier }
10966891d857SDavid du Colombier et = TLONG;
10976891d857SDavid du Colombier if(f1 != Z && f1->type != T) {
10986891d857SDavid du Colombier if(f1->op == OCONST && t != Z && t->type != T)
10996891d857SDavid du Colombier et = t->type->etype;
11006891d857SDavid du Colombier else
11016891d857SDavid du Colombier et = f1->type->etype;
11026891d857SDavid du Colombier }
11036891d857SDavid du Colombier if((typev[et] || t->type != T && typev[t->type->etype]) && o != OFUNC) {
11046891d857SDavid du Colombier gopcode64(o, f1, f2, t);
11056891d857SDavid du Colombier return;
11066891d857SDavid du Colombier }
11076891d857SDavid du Colombier uns = 0;
11086891d857SDavid du Colombier a = AGOK;
11096891d857SDavid du Colombier switch(o) {
11107dd7cddfSDavid du Colombier
11117dd7cddfSDavid du Colombier case OASADD:
11127dd7cddfSDavid du Colombier case OADD:
11137dd7cddfSDavid du Colombier a = AADD;
11147dd7cddfSDavid du Colombier if(et == TFLOAT)
11157dd7cddfSDavid du Colombier a = AFADDS;
11167dd7cddfSDavid du Colombier else
11175ede6b93SDavid du Colombier if(et == TDOUBLE)
11187dd7cddfSDavid du Colombier a = AFADD;
11197dd7cddfSDavid du Colombier break;
11207dd7cddfSDavid du Colombier
11217dd7cddfSDavid du Colombier case OASSUB:
11227dd7cddfSDavid du Colombier case OSUB:
11237dd7cddfSDavid du Colombier a = ASUB;
11247dd7cddfSDavid du Colombier if(et == TFLOAT)
11257dd7cddfSDavid du Colombier a = AFSUBS;
11267dd7cddfSDavid du Colombier else
11275ede6b93SDavid du Colombier if(et == TDOUBLE)
11287dd7cddfSDavid du Colombier a = AFSUB;
11297dd7cddfSDavid du Colombier break;
11307dd7cddfSDavid du Colombier
11317dd7cddfSDavid du Colombier case OASOR:
11327dd7cddfSDavid du Colombier case OOR:
11337dd7cddfSDavid du Colombier a = AOR;
11347dd7cddfSDavid du Colombier break;
11357dd7cddfSDavid du Colombier
11367dd7cddfSDavid du Colombier case OASAND:
11377dd7cddfSDavid du Colombier case OAND:
11387dd7cddfSDavid du Colombier a = AAND;
11397dd7cddfSDavid du Colombier if(f1->op == OCONST)
11407dd7cddfSDavid du Colombier a = AANDCC;
11417dd7cddfSDavid du Colombier break;
11427dd7cddfSDavid du Colombier
11437dd7cddfSDavid du Colombier case OASXOR:
11447dd7cddfSDavid du Colombier case OXOR:
11457dd7cddfSDavid du Colombier a = AXOR;
11467dd7cddfSDavid du Colombier break;
11477dd7cddfSDavid du Colombier
11487dd7cddfSDavid du Colombier case OASLSHR:
11497dd7cddfSDavid du Colombier case OLSHR:
11507dd7cddfSDavid du Colombier a = ASRW;
11517dd7cddfSDavid du Colombier break;
11527dd7cddfSDavid du Colombier
11537dd7cddfSDavid du Colombier case OASASHR:
11547dd7cddfSDavid du Colombier case OASHR:
11557dd7cddfSDavid du Colombier a = ASRAW;
11567dd7cddfSDavid du Colombier break;
11577dd7cddfSDavid du Colombier
11587dd7cddfSDavid du Colombier case OASASHL:
11597dd7cddfSDavid du Colombier case OASHL:
11606891d857SDavid du Colombier a = ASLW;
11617dd7cddfSDavid du Colombier break;
11627dd7cddfSDavid du Colombier
11637dd7cddfSDavid du Colombier case OFUNC:
11647dd7cddfSDavid du Colombier a = ABL;
11657dd7cddfSDavid du Colombier break;
11667dd7cddfSDavid du Colombier
11677dd7cddfSDavid du Colombier case OASLMUL:
11687dd7cddfSDavid du Colombier case OLMUL:
11697dd7cddfSDavid du Colombier case OASMUL:
11707dd7cddfSDavid du Colombier case OMUL:
11717dd7cddfSDavid du Colombier if(et == TFLOAT) {
11727dd7cddfSDavid du Colombier a = AFMULS;
11737dd7cddfSDavid du Colombier break;
11747dd7cddfSDavid du Colombier } else
11755ede6b93SDavid du Colombier if(et == TDOUBLE) {
11767dd7cddfSDavid du Colombier a = AFMUL;
11777dd7cddfSDavid du Colombier break;
11787dd7cddfSDavid du Colombier }
11797dd7cddfSDavid du Colombier a = AMULLW;
11807dd7cddfSDavid du Colombier break;
11817dd7cddfSDavid du Colombier
11827dd7cddfSDavid du Colombier case OASDIV:
11837dd7cddfSDavid du Colombier case ODIV:
11847dd7cddfSDavid du Colombier if(et == TFLOAT) {
11857dd7cddfSDavid du Colombier a = AFDIVS;
11867dd7cddfSDavid du Colombier break;
11877dd7cddfSDavid du Colombier } else
11885ede6b93SDavid du Colombier if(et == TDOUBLE) {
11897dd7cddfSDavid du Colombier a = AFDIV;
11907dd7cddfSDavid du Colombier break;
11917dd7cddfSDavid du Colombier }
11927dd7cddfSDavid du Colombier a = ADIVW;
11937dd7cddfSDavid du Colombier break;
11947dd7cddfSDavid du Colombier
11957dd7cddfSDavid du Colombier case OASMOD:
11967dd7cddfSDavid du Colombier case OMOD:
11977dd7cddfSDavid du Colombier a = AREM;
11987dd7cddfSDavid du Colombier break;
11997dd7cddfSDavid du Colombier
12007dd7cddfSDavid du Colombier case OASLMOD:
12017dd7cddfSDavid du Colombier case OLMOD:
12027dd7cddfSDavid du Colombier a = AREMU;
12037dd7cddfSDavid du Colombier break;
12047dd7cddfSDavid du Colombier
12057dd7cddfSDavid du Colombier case OASLDIV:
12067dd7cddfSDavid du Colombier case OLDIV:
12077dd7cddfSDavid du Colombier a = ADIVWU;
12087dd7cddfSDavid du Colombier break;
12097dd7cddfSDavid du Colombier
12107dd7cddfSDavid du Colombier case OCOM:
12117dd7cddfSDavid du Colombier a = ANOR;
12127dd7cddfSDavid du Colombier break;
12137dd7cddfSDavid du Colombier
12147dd7cddfSDavid du Colombier case ONEG:
12157dd7cddfSDavid du Colombier a = ANEG;
12165ede6b93SDavid du Colombier if(et == TFLOAT || et == TDOUBLE)
12177dd7cddfSDavid du Colombier a = AFNEG;
12187dd7cddfSDavid du Colombier break;
12197dd7cddfSDavid du Colombier
12207dd7cddfSDavid du Colombier case OEQ:
12217dd7cddfSDavid du Colombier a = ABEQ;
12226891d857SDavid du Colombier if(t->op == OCONST && t->vconst >= (1<<15))
12236891d857SDavid du Colombier goto cmpu;
12247dd7cddfSDavid du Colombier goto cmp;
12257dd7cddfSDavid du Colombier
12267dd7cddfSDavid du Colombier case ONE:
12277dd7cddfSDavid du Colombier a = ABNE;
12286891d857SDavid du Colombier if(t->op == OCONST && t->vconst >= (1<<15))
12296891d857SDavid du Colombier goto cmpu;
12307dd7cddfSDavid du Colombier goto cmp;
12317dd7cddfSDavid du Colombier
12327dd7cddfSDavid du Colombier case OLT:
12337dd7cddfSDavid du Colombier a = ABLT;
12347dd7cddfSDavid du Colombier goto cmp;
12357dd7cddfSDavid du Colombier
12367dd7cddfSDavid du Colombier case OLE:
12377dd7cddfSDavid du Colombier a = ABLE;
12387dd7cddfSDavid du Colombier goto cmp;
12397dd7cddfSDavid du Colombier
12407dd7cddfSDavid du Colombier case OGE:
12417dd7cddfSDavid du Colombier a = ABGE;
12427dd7cddfSDavid du Colombier goto cmp;
12437dd7cddfSDavid du Colombier
12447dd7cddfSDavid du Colombier case OGT:
12457dd7cddfSDavid du Colombier a = ABGT;
12467dd7cddfSDavid du Colombier goto cmp;
12477dd7cddfSDavid du Colombier
12487dd7cddfSDavid du Colombier case OLO:
12497dd7cddfSDavid du Colombier a = ABLT;
12507dd7cddfSDavid du Colombier goto cmpu;
12517dd7cddfSDavid du Colombier
12527dd7cddfSDavid du Colombier case OLS:
12537dd7cddfSDavid du Colombier a = ABLE;
12547dd7cddfSDavid du Colombier goto cmpu;
12557dd7cddfSDavid du Colombier
12567dd7cddfSDavid du Colombier case OHS:
12577dd7cddfSDavid du Colombier a = ABGE;
12587dd7cddfSDavid du Colombier goto cmpu;
12597dd7cddfSDavid du Colombier
12607dd7cddfSDavid du Colombier case OHI:
12617dd7cddfSDavid du Colombier a = ABGT;
12627dd7cddfSDavid du Colombier goto cmpu;
12637dd7cddfSDavid du Colombier
12647dd7cddfSDavid du Colombier cmpu:
12657dd7cddfSDavid du Colombier uns = 1;
12667dd7cddfSDavid du Colombier cmp:
12677dd7cddfSDavid du Colombier nextpc();
12687dd7cddfSDavid du Colombier p->as = uns? ACMPU: ACMP;
12697dd7cddfSDavid du Colombier if(et == TFLOAT)
12707dd7cddfSDavid du Colombier p->as = AFCMPU;
12717dd7cddfSDavid du Colombier else
12725ede6b93SDavid du Colombier if(et == TDOUBLE)
12737dd7cddfSDavid du Colombier p->as = AFCMPU;
12747dd7cddfSDavid du Colombier if(f1 != Z)
12757dd7cddfSDavid du Colombier naddr(f1, &p->from);
12767dd7cddfSDavid du Colombier if(t != Z)
12777dd7cddfSDavid du Colombier naddr(t, &p->to);
12787dd7cddfSDavid du Colombier if(f1 == Z || t == Z || f2 != Z)
12797dd7cddfSDavid du Colombier diag(Z, "bad cmp in gopcode %O", o);
12807dd7cddfSDavid du Colombier if(debug['g'])
12817dd7cddfSDavid du Colombier print("%P\n", p);
12827dd7cddfSDavid du Colombier f1 = Z;
12837dd7cddfSDavid du Colombier f2 = Z;
12847dd7cddfSDavid du Colombier t = Z;
12857dd7cddfSDavid du Colombier break;
12867dd7cddfSDavid du Colombier }
12877dd7cddfSDavid du Colombier if(a == AGOK)
12887dd7cddfSDavid du Colombier diag(Z, "bad in gopcode %O", o);
12896891d857SDavid du Colombier gins3(a, f1, f2, t);
12906891d857SDavid du Colombier }
12916891d857SDavid du Colombier
12926891d857SDavid du Colombier static void
gopcode64(int o,Node * f1,Node * f2,Node * t)12936891d857SDavid du Colombier gopcode64(int o, Node *f1, Node *f2, Node *t)
12946891d857SDavid du Colombier {
12956891d857SDavid du Colombier int a1, a2;
12966891d857SDavid du Colombier Node nod, nod1, nod2, sh;
12976891d857SDavid du Colombier ulong m;
12986891d857SDavid du Colombier Prog *p1;
12996891d857SDavid du Colombier
13006891d857SDavid du Colombier if(t->op != OREGPAIR || f2 != Z && f2->op != OREGPAIR) {
13016891d857SDavid du Colombier diag(Z, "bad f2/dest in gopcode64 %O", o);
13026891d857SDavid du Colombier return;
13036891d857SDavid du Colombier }
13046891d857SDavid du Colombier if(f1->op != OCONST &&
13056891d857SDavid du Colombier (typev[f1->type->etype] && f1->op != OREGPAIR || !typev[f1->type->etype] && f1->op != OREGISTER)) {
13066891d857SDavid du Colombier diag(Z, "bad f1[%O] in gopcode64 %O", f1->op, o);
13076891d857SDavid du Colombier return;
13086891d857SDavid du Colombier }
13096891d857SDavid du Colombier /* a1 for low-order, a2 for high-order */
13106891d857SDavid du Colombier a1 = AGOK;
13116891d857SDavid du Colombier a2 = AGOK;
13126891d857SDavid du Colombier switch(o) {
13136891d857SDavid du Colombier case OASADD:
13146891d857SDavid du Colombier case OADD:
13156891d857SDavid du Colombier if(f1->op == OCONST && sconst(f1)) {
13166891d857SDavid du Colombier if(f2 == Z)
13176891d857SDavid du Colombier f2 = t;
13186891d857SDavid du Colombier gins3(AADDC, f1, f2->right, t->right);
13196891d857SDavid du Colombier if((f1->vconst>>32) == 0)
13206891d857SDavid du Colombier gins(AADDZE, f2->left, t->left);
13216891d857SDavid du Colombier else if((f1->vconst>>32) == -1)
13226891d857SDavid du Colombier gins(AADDME, f2->left, t->left);
1323375daca8SDavid du Colombier else
13246891d857SDavid du Colombier diag(t, "odd vlong ADD: %lld", f1->vconst);
13256891d857SDavid du Colombier return;
13266891d857SDavid du Colombier }
13276891d857SDavid du Colombier a1 = AADDC;
13286891d857SDavid du Colombier a2 = AADDE;
13296891d857SDavid du Colombier break;
13306891d857SDavid du Colombier
13316891d857SDavid du Colombier case OASSUB:
13326891d857SDavid du Colombier case OSUB:
13336891d857SDavid du Colombier a1 = ASUBC;
13346891d857SDavid du Colombier a2 = ASUBE;
13356891d857SDavid du Colombier break;
13366891d857SDavid du Colombier
13376891d857SDavid du Colombier case OASOR:
13386891d857SDavid du Colombier case OOR:
13396891d857SDavid du Colombier if(f1->op == OCONST) {
13406891d857SDavid du Colombier gori64(AOR, f1, f2, t);
13416891d857SDavid du Colombier return;
13426891d857SDavid du Colombier }
13436891d857SDavid du Colombier a1 = a2 = AOR;
13446891d857SDavid du Colombier break;
13456891d857SDavid du Colombier
13466891d857SDavid du Colombier case OASAND:
13476891d857SDavid du Colombier case OAND:
13486891d857SDavid du Colombier if(f1->op == OCONST) {
13496891d857SDavid du Colombier gandi64(AANDCC, f1, f2, t);
13506891d857SDavid du Colombier return;
13516891d857SDavid du Colombier }
13526891d857SDavid du Colombier a1 = a2 = AAND;
13536891d857SDavid du Colombier break;
13546891d857SDavid du Colombier
13556891d857SDavid du Colombier case OASXOR:
13566891d857SDavid du Colombier case OXOR:
13576891d857SDavid du Colombier if(f1->op == OCONST) {
13586891d857SDavid du Colombier gori64(AXOR, f1, f2, t);
13596891d857SDavid du Colombier return;
13606891d857SDavid du Colombier }
13616891d857SDavid du Colombier a1 = a2 = AXOR;
13626891d857SDavid du Colombier break;
13636891d857SDavid du Colombier
13646891d857SDavid du Colombier case OASLSHR:
13656891d857SDavid du Colombier case OLSHR:
13666891d857SDavid du Colombier if(f2 == Z)
13676891d857SDavid du Colombier f2 = t;
13686891d857SDavid du Colombier if(f1->op == OCONST) {
13696891d857SDavid du Colombier if(f1->vconst >= 32) {
13706891d857SDavid du Colombier if(f1->vconst == 32)
13716891d857SDavid du Colombier gmove(f2->left, t->right);
13726891d857SDavid du Colombier else if(f1->vconst < 64)
13736891d857SDavid du Colombier gins3(ASRW, nodconst(f1->vconst-32), f2->left, t->right);
13746891d857SDavid du Colombier else
13756891d857SDavid du Colombier gmove(nodconst(0), t->right);
13766891d857SDavid du Colombier gmove(nodconst(0), t->left);
13776891d857SDavid du Colombier return;
13786891d857SDavid du Colombier }
13796891d857SDavid du Colombier if(f1->vconst <= 0) {
13806891d857SDavid du Colombier if(f2 != t)
13816891d857SDavid du Colombier gmove(f2, t);
13826891d857SDavid du Colombier return;
13836891d857SDavid du Colombier }
13846891d857SDavid du Colombier sh = *nodconst(32 - f1->vconst);
13856891d857SDavid du Colombier m = 0xFFFFFFFFUL >> f1->vconst;
13866891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
13876891d857SDavid du Colombier gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
13886891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->left, nodconst(m), t->left);
13896891d857SDavid du Colombier return;
13906891d857SDavid du Colombier }
13916891d857SDavid du Colombier regalloc(&nod, ®node, Z);
13926891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
13936891d857SDavid du Colombier gins3(ASRW, f1, f2->right, t->right);
13946891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
13956891d857SDavid du Colombier gins3(ASLW, &nod, f2->left, &nod1);
13966891d857SDavid du Colombier gins(AOR, &nod1, t->right);
13976891d857SDavid du Colombier gins3(AADD, nodconst(-32), f1, &nod);
13986891d857SDavid du Colombier gins3(ASRW, &nod, f2->left, &nod1);
13996891d857SDavid du Colombier gins(AOR, &nod1, t->right);
14006891d857SDavid du Colombier gins3(ASRW, f1, f2->left, t->left);
14016891d857SDavid du Colombier regfree(&nod);
14026891d857SDavid du Colombier regfree(&nod1);
14036891d857SDavid du Colombier return;
14046891d857SDavid du Colombier
14056891d857SDavid du Colombier case OASASHR:
14066891d857SDavid du Colombier case OASHR:
14076891d857SDavid du Colombier if(f2 == Z)
14086891d857SDavid du Colombier f2 = t;
14096891d857SDavid du Colombier if(f1->op == OCONST) {
14106891d857SDavid du Colombier if(f1->vconst >= 32) {
14116891d857SDavid du Colombier if(f1->vconst == 32)
14126891d857SDavid du Colombier gmove(f2->left, t->right);
14136891d857SDavid du Colombier else if(f1->vconst < 64)
14146891d857SDavid du Colombier gins3(ASRAW, nodconst(f1->vconst-32), f2->left, t->right);
14156891d857SDavid du Colombier gins3(ASRAW, nodconst(31), f2->left, t->left);
14166891d857SDavid du Colombier if(f1->vconst >= 64) {
14176891d857SDavid du Colombier gmove(t->left, t->right);
14186891d857SDavid du Colombier return;
14196891d857SDavid du Colombier }
14206891d857SDavid du Colombier return;
14216891d857SDavid du Colombier }
14226891d857SDavid du Colombier if(f1->vconst <= 0) {
14236891d857SDavid du Colombier if(f2 != t)
14246891d857SDavid du Colombier gmove(f2, t);
14256891d857SDavid du Colombier return;
14266891d857SDavid du Colombier }
14276891d857SDavid du Colombier sh = *nodconst(32 - f1->vconst);
14286891d857SDavid du Colombier m = 0xFFFFFFFFUL >> f1->vconst;
14296891d857SDavid du Colombier gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
14306891d857SDavid du Colombier gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
14316891d857SDavid du Colombier gins3(ASRAW, &sh, f2->left, t->left);
14326891d857SDavid du Colombier return;
14336891d857SDavid du Colombier }
14346891d857SDavid du Colombier regalloc(&nod, ®node, Z);
14356891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
14366891d857SDavid du Colombier gins3(ASRW, f1, f2->right, t->right);
14376891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
14386891d857SDavid du Colombier gins3(ASLW, &nod, f2->left, &nod1);
14396891d857SDavid du Colombier gins(AOR, &nod1, t->right);
14406891d857SDavid du Colombier gins3(AADDCCC, nodconst(-32), f1, &nod);
14416891d857SDavid du Colombier gins3(ASRAW, &nod, f2->left, &nod1);
14426891d857SDavid du Colombier gins(ABLE, Z, Z);
14436891d857SDavid du Colombier p1 = p;
14446891d857SDavid du Colombier gins(AMOVW, &nod1, t->right);
14456891d857SDavid du Colombier patch(p1, pc);
14466891d857SDavid du Colombier gins3(ASRAW, f1, f2->left, t->left);
14476891d857SDavid du Colombier regfree(&nod);
14486891d857SDavid du Colombier regfree(&nod1);
14496891d857SDavid du Colombier return;
14506891d857SDavid du Colombier
14516891d857SDavid du Colombier case OASASHL:
14526891d857SDavid du Colombier case OASHL:
14536891d857SDavid du Colombier if(f2 == Z)
14546891d857SDavid du Colombier f2 = t;
14556891d857SDavid du Colombier if(f1->op == OCONST) {
14566891d857SDavid du Colombier if(f1->vconst >= 32) {
14576891d857SDavid du Colombier if(f1->vconst == 32)
14586891d857SDavid du Colombier gmove(f2->right, t->left);
14596891d857SDavid du Colombier else if(f1->vconst >= 64)
14606891d857SDavid du Colombier gmove(nodconst(0), t->left);
14616891d857SDavid du Colombier else
14626891d857SDavid du Colombier gins3(ASLW, nodconst(f1->vconst-32), f2->right, t->left);
14636891d857SDavid du Colombier gmove(nodconst(0), t->right);
14646891d857SDavid du Colombier return;
14656891d857SDavid du Colombier }
14666891d857SDavid du Colombier if(f1->vconst <= 0) {
14676891d857SDavid du Colombier if(f2 != t)
14686891d857SDavid du Colombier gmove(f2, t);
14696891d857SDavid du Colombier return;
14706891d857SDavid du Colombier }
14716891d857SDavid du Colombier m = 0xFFFFFFFFUL << f1->vconst;
14726891d857SDavid du Colombier gins4(ARLWNM, f1, f2->left, nodconst(m), t->left);
14736891d857SDavid du Colombier gins4(ARLWMI, f1, f2->right, nodconst(~m), t->left);
14746891d857SDavid du Colombier gins4(ARLWNM, f1, f2->right, nodconst(m), t->right);
14756891d857SDavid du Colombier return;
14766891d857SDavid du Colombier }
14776891d857SDavid du Colombier regalloc(&nod, ®node, Z);
14786891d857SDavid du Colombier gins3(ASUBC, f1, nodconst(32), &nod);
14796891d857SDavid du Colombier gins3(ASLW, f1, f2->left, t->left);
14806891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
14816891d857SDavid du Colombier gins3(ASRW, &nod, f2->right, &nod1);
14826891d857SDavid du Colombier gins(AOR, &nod1, t->left);
14836891d857SDavid du Colombier gins3(AADD, nodconst(-32), f1, &nod);
14846891d857SDavid du Colombier gins3(ASLW, &nod, f2->right, &nod1);
14856891d857SDavid du Colombier gins(AOR, &nod1, t->left);
14866891d857SDavid du Colombier gins3(ASLW, f1, f2->right, t->right);
14876891d857SDavid du Colombier regfree(&nod);
14886891d857SDavid du Colombier regfree(&nod1);
14896891d857SDavid du Colombier return;
14906891d857SDavid du Colombier
14916891d857SDavid du Colombier case OASLMUL:
14926891d857SDavid du Colombier case OLMUL:
14936891d857SDavid du Colombier case OASMUL:
14946891d857SDavid du Colombier case OMUL:
14956891d857SDavid du Colombier if(f2 == Z)
14966891d857SDavid du Colombier f2 = t;
14976891d857SDavid du Colombier regalloc(&nod, ®node, Z);
14986891d857SDavid du Colombier gins3(AMULLW, f1->right, f2->right, &nod); /* lo(f2.low*f1.low) */
14996891d857SDavid du Colombier regalloc(&nod1, ®node, Z);
15001ebfca79SDavid du Colombier gins3(AMULHWU, f1->right, f2->right, &nod1); /* hi(f2.low*f1.low) */
15016891d857SDavid du Colombier regalloc(&nod2, ®node, Z);
15026891d857SDavid du Colombier gins3(AMULLW, f2->right, f1->left, &nod2); /* lo(f2.low*f1.high) */
15036891d857SDavid du Colombier gins(AADD, &nod2, &nod1);
15041ebfca79SDavid du Colombier gins3(AMULLW, f1->right, f2->left, &nod2); /* lo(f2.high*f1.low) */
15056891d857SDavid du Colombier gins(AADD, &nod2, &nod1);
15066891d857SDavid du Colombier regfree(&nod2);
15076891d857SDavid du Colombier gmove(&nod, t->right);
15086891d857SDavid du Colombier gmove(&nod1, t->left);
15096891d857SDavid du Colombier regfree(&nod);
15106891d857SDavid du Colombier regfree(&nod1);
15116891d857SDavid du Colombier return;
15126891d857SDavid du Colombier
15136891d857SDavid du Colombier case OCOM:
15146891d857SDavid du Colombier a1 = a2 = ANOR;
15156891d857SDavid du Colombier break;
15166891d857SDavid du Colombier
15176891d857SDavid du Colombier case ONEG:
15186891d857SDavid du Colombier gins3(ASUBC, t->right, nodconst(0), t->right);
15196891d857SDavid du Colombier gins(ASUBZE, t->left, t->left);
15206891d857SDavid du Colombier return;
15216891d857SDavid du Colombier }
15226891d857SDavid du Colombier if(a1 == AGOK || a2 == AGOK)
15236891d857SDavid du Colombier diag(Z, "bad in gopcode64 %O", o);
15246891d857SDavid du Colombier if(f1->op == OCONST) {
15256891d857SDavid du Colombier if(f2 != Z & f2 != t)
15266891d857SDavid du Colombier diag(Z, "bad const in gopcode64 %O", o);
15276891d857SDavid du Colombier gins(a1, nod32const(f1->vconst), t->right);
15286891d857SDavid du Colombier gins(a2, nod32const(f1->vconst>>32), t->left);
15296891d857SDavid du Colombier } else {
15306891d857SDavid du Colombier if(f2 != Z && f2 != t) {
15316891d857SDavid du Colombier gins3(a1, f1->right, f2->right, t->right);
15326891d857SDavid du Colombier gins3(a2, f1->left, f2->left, t->left);
15336891d857SDavid du Colombier } else {
15346891d857SDavid du Colombier gins(a1, f1->right, t->right);
15356891d857SDavid du Colombier gins(a2, f1->left, t->left);
1536375daca8SDavid du Colombier }
15377dd7cddfSDavid du Colombier }
15387dd7cddfSDavid du Colombier }
15397dd7cddfSDavid du Colombier
samaddr(Node * f,Node * t)15407dd7cddfSDavid du Colombier samaddr(Node *f, Node *t)
15417dd7cddfSDavid du Colombier {
15427dd7cddfSDavid du Colombier
15437dd7cddfSDavid du Colombier if(f->op != t->op)
15447dd7cddfSDavid du Colombier return 0;
15457dd7cddfSDavid du Colombier switch(f->op) {
15467dd7cddfSDavid du Colombier
15477dd7cddfSDavid du Colombier case OREGISTER:
15487dd7cddfSDavid du Colombier if(f->reg != t->reg)
15497dd7cddfSDavid du Colombier break;
15507dd7cddfSDavid du Colombier return 1;
15516891d857SDavid du Colombier
15526891d857SDavid du Colombier case OREGPAIR:
15536891d857SDavid du Colombier return samaddr(f->left, t->left) && samaddr(f->right, t->right);
15547dd7cddfSDavid du Colombier }
15557dd7cddfSDavid du Colombier return 0;
15567dd7cddfSDavid du Colombier }
15577dd7cddfSDavid du Colombier
15586891d857SDavid du Colombier static void
gori64(int a,Node * f1,Node * f2,Node * t)15596891d857SDavid du Colombier gori64(int a, Node *f1, Node *f2, Node *t)
15606891d857SDavid du Colombier {
15616891d857SDavid du Colombier ulong lo, hi;
15626891d857SDavid du Colombier
15636891d857SDavid du Colombier if(f2 == Z)
15646891d857SDavid du Colombier f2 = t;
15656891d857SDavid du Colombier lo = f1->vconst & MASK(32);
15666891d857SDavid du Colombier hi = (f1->vconst >> 32) & MASK(32);
15676891d857SDavid du Colombier if(lo & 0xFFFF)
15686891d857SDavid du Colombier gins3(a, nodconst(lo & 0xFFFF), f2->right, t->right);
15696891d857SDavid du Colombier if((lo >> 16) != 0)
15706891d857SDavid du Colombier gins3(a, nodconst(lo & 0xFFFF0000UL), f2->right, t->right);
15716891d857SDavid du Colombier if(hi & 0xFFFF)
15726891d857SDavid du Colombier gins3(a, nodconst(hi & 0xFFFF), f2->left, t->left);
15736891d857SDavid du Colombier if((hi >> 16) != 0)
15746891d857SDavid du Colombier gins3(a, nodconst(hi & 0xFFFF0000UL), f2->left, t->left);
15756891d857SDavid du Colombier }
15766891d857SDavid du Colombier
15776891d857SDavid du Colombier static void
gandi64(int a,Node * f1,Node * f2,Node * t)15786891d857SDavid du Colombier gandi64(int a, Node *f1, Node *f2, Node *t)
15796891d857SDavid du Colombier {
15806891d857SDavid du Colombier ulong lo, hi;
15816891d857SDavid du Colombier
15826891d857SDavid du Colombier if(f2 == Z)
15836891d857SDavid du Colombier f2 = t;
15846891d857SDavid du Colombier lo = f1->vconst & MASK(32);
15856891d857SDavid du Colombier hi = (f1->vconst >> 32) & MASK(32);
15866891d857SDavid du Colombier if(lo == 0)
15876891d857SDavid du Colombier gins(AMOVW, nodconst(0), t->right);
15886891d857SDavid du Colombier else
15896891d857SDavid du Colombier gins3(a, nodconst(lo), f2->right, t->right);
15906891d857SDavid du Colombier if(hi == 0)
15916891d857SDavid du Colombier gins(AMOVW, nodconst(0), t->left);
15926891d857SDavid du Colombier else
15936891d857SDavid du Colombier gins3(a, nodconst(hi), f2->left, t->left);
15946891d857SDavid du Colombier }
15956891d857SDavid du Colombier
15967dd7cddfSDavid du Colombier void
gbranch(int o)15977dd7cddfSDavid du Colombier gbranch(int o)
15987dd7cddfSDavid du Colombier {
15997dd7cddfSDavid du Colombier int a;
16007dd7cddfSDavid du Colombier
16017dd7cddfSDavid du Colombier a = AGOK;
16027dd7cddfSDavid du Colombier switch(o) {
16037dd7cddfSDavid du Colombier case ORETURN:
16047dd7cddfSDavid du Colombier a = ARETURN;
16057dd7cddfSDavid du Colombier break;
16067dd7cddfSDavid du Colombier case OGOTO:
16077dd7cddfSDavid du Colombier a = ABR;
16087dd7cddfSDavid du Colombier break;
16097dd7cddfSDavid du Colombier }
16107dd7cddfSDavid du Colombier nextpc();
16117dd7cddfSDavid du Colombier if(a == AGOK) {
16127dd7cddfSDavid du Colombier diag(Z, "bad in gbranch %O", o);
16137dd7cddfSDavid du Colombier nextpc();
16147dd7cddfSDavid du Colombier }
16157dd7cddfSDavid du Colombier p->as = a;
16167dd7cddfSDavid du Colombier }
16177dd7cddfSDavid du Colombier
16187dd7cddfSDavid du Colombier void
patch(Prog * op,long pc)16197dd7cddfSDavid du Colombier patch(Prog *op, long pc)
16207dd7cddfSDavid du Colombier {
16217dd7cddfSDavid du Colombier
16227dd7cddfSDavid du Colombier op->to.offset = pc;
16237dd7cddfSDavid du Colombier op->to.type = D_BRANCH;
16247dd7cddfSDavid du Colombier }
16257dd7cddfSDavid du Colombier
16267dd7cddfSDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)16277dd7cddfSDavid du Colombier gpseudo(int a, Sym *s, Node *n)
16287dd7cddfSDavid du Colombier {
16297dd7cddfSDavid du Colombier
16307dd7cddfSDavid du Colombier nextpc();
16317dd7cddfSDavid du Colombier p->as = a;
16327dd7cddfSDavid du Colombier p->from.type = D_OREG;
16337dd7cddfSDavid du Colombier p->from.sym = s;
16345ede6b93SDavid du Colombier if(a == ATEXT)
1635e288d156SDavid du Colombier p->reg = (profileflg ? 0 : NOPROF);
16367dd7cddfSDavid du Colombier p->from.name = D_EXTERN;
16377dd7cddfSDavid du Colombier if(s->class == CSTATIC)
16387dd7cddfSDavid du Colombier p->from.name = D_STATIC;
16397dd7cddfSDavid du Colombier naddr(n, &p->to);
16407dd7cddfSDavid du Colombier if(a == ADATA || a == AGLOBL)
16417dd7cddfSDavid du Colombier pc--;
16427dd7cddfSDavid du Colombier }
16437dd7cddfSDavid du Colombier
16447dd7cddfSDavid du Colombier int
sval(long v)16457dd7cddfSDavid du Colombier sval(long v)
16467dd7cddfSDavid du Colombier {
16477dd7cddfSDavid du Colombier
16487dd7cddfSDavid du Colombier if(v >= -(1<<15) && v < (1<<15))
16497dd7cddfSDavid du Colombier return 1;
16507dd7cddfSDavid du Colombier return 0;
16517dd7cddfSDavid du Colombier }
16527dd7cddfSDavid du Colombier
16537dd7cddfSDavid du Colombier int
sconst(Node * n)16547dd7cddfSDavid du Colombier sconst(Node *n)
16557dd7cddfSDavid du Colombier {
16567dd7cddfSDavid du Colombier vlong vv;
16577dd7cddfSDavid du Colombier
16587dd7cddfSDavid du Colombier if(n->op == OCONST) {
16597dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
16607dd7cddfSDavid du Colombier vv = n->vconst;
1661375daca8SDavid du Colombier if(vv >= -(((vlong)1)<<15) && vv < (((vlong)1)<<15))
16627dd7cddfSDavid du Colombier return 1;
16637dd7cddfSDavid du Colombier }
16647dd7cddfSDavid du Colombier }
16657dd7cddfSDavid du Colombier return 0;
16667dd7cddfSDavid du Colombier }
16677dd7cddfSDavid du Colombier
16687dd7cddfSDavid du Colombier int
uconst(Node * n)16697dd7cddfSDavid du Colombier uconst(Node *n)
16707dd7cddfSDavid du Colombier {
16717dd7cddfSDavid du Colombier vlong vv;
16727dd7cddfSDavid du Colombier
16737dd7cddfSDavid du Colombier if(n->op == OCONST) {
16747dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
16757dd7cddfSDavid du Colombier vv = n->vconst;
1676375daca8SDavid du Colombier if(vv >= 0 && vv < (((vlong)1)<<16))
16777dd7cddfSDavid du Colombier return 1;
16787dd7cddfSDavid du Colombier }
16797dd7cddfSDavid du Colombier }
16807dd7cddfSDavid du Colombier return 0;
16817dd7cddfSDavid du Colombier }
16827dd7cddfSDavid du Colombier
16837dd7cddfSDavid du Colombier long
exreg(Type * t)16847dd7cddfSDavid du Colombier exreg(Type *t)
16857dd7cddfSDavid du Colombier {
16867dd7cddfSDavid du Colombier long o;
16877dd7cddfSDavid du Colombier
16887dd7cddfSDavid du Colombier if(typechlp[t->etype]) {
16897dd7cddfSDavid du Colombier if(exregoffset <= 3)
16907dd7cddfSDavid du Colombier return 0;
16917dd7cddfSDavid du Colombier o = exregoffset;
16927dd7cddfSDavid du Colombier exregoffset--;
16937dd7cddfSDavid du Colombier return o;
16947dd7cddfSDavid du Colombier }
16957dd7cddfSDavid du Colombier if(typefd[t->etype]) {
16967dd7cddfSDavid du Colombier if(exfregoffset <= 16)
16977dd7cddfSDavid du Colombier return 0;
16987dd7cddfSDavid du Colombier o = exfregoffset + NREG;
16997dd7cddfSDavid du Colombier exfregoffset--;
17007dd7cddfSDavid du Colombier return o;
17017dd7cddfSDavid du Colombier }
17027dd7cddfSDavid du Colombier return 0;
17037dd7cddfSDavid du Colombier }
17047dd7cddfSDavid du Colombier
17057dd7cddfSDavid du Colombier schar ewidth[NTYPE] =
17067dd7cddfSDavid du Colombier {
17077dd7cddfSDavid du Colombier -1, /* [TXXX] */
17087dd7cddfSDavid du Colombier SZ_CHAR, /* [TCHAR] */
17097dd7cddfSDavid du Colombier SZ_CHAR, /* [TUCHAR] */
17107dd7cddfSDavid du Colombier SZ_SHORT, /* [TSHORT] */
17117dd7cddfSDavid du Colombier SZ_SHORT, /* [TUSHORT] */
17127dd7cddfSDavid du Colombier SZ_INT, /* [TINT] */
17137dd7cddfSDavid du Colombier SZ_INT, /* [TUINT] */
17147dd7cddfSDavid du Colombier SZ_LONG, /* [TLONG] */
17157dd7cddfSDavid du Colombier SZ_LONG, /* [TULONG] */
17167dd7cddfSDavid du Colombier SZ_VLONG, /* [TVLONG] */
17177dd7cddfSDavid du Colombier SZ_VLONG, /* [TUVLONG] */
17187dd7cddfSDavid du Colombier SZ_FLOAT, /* [TFLOAT] */
17197dd7cddfSDavid du Colombier SZ_DOUBLE, /* [TDOUBLE] */
17207dd7cddfSDavid du Colombier SZ_IND, /* [TIND] */
17217dd7cddfSDavid du Colombier 0, /* [TFUNC] */
17227dd7cddfSDavid du Colombier -1, /* [TARRAY] */
17237dd7cddfSDavid du Colombier 0, /* [TVOID] */
17247dd7cddfSDavid du Colombier -1, /* [TSTRUCT] */
17257dd7cddfSDavid du Colombier -1, /* [TUNION] */
17267dd7cddfSDavid du Colombier SZ_INT, /* [TENUM] */
17277dd7cddfSDavid du Colombier };
17287dd7cddfSDavid du Colombier long ncast[NTYPE] =
17297dd7cddfSDavid du Colombier {
17307dd7cddfSDavid du Colombier 0, /* [TXXX] */
17317dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TCHAR] */
17327dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TUCHAR] */
17337dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TSHORT] */
17347dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TUSHORT] */
17357dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
17367dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
17377dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
17387dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
17397dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TVLONG] */
17407dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TUVLONG] */
17417dd7cddfSDavid du Colombier BFLOAT, /* [TFLOAT] */
17427dd7cddfSDavid du Colombier BDOUBLE, /* [TDOUBLE] */
17437dd7cddfSDavid du Colombier BLONG|BULONG|BIND, /* [TIND] */
17447dd7cddfSDavid du Colombier 0, /* [TFUNC] */
17457dd7cddfSDavid du Colombier 0, /* [TARRAY] */
17467dd7cddfSDavid du Colombier 0, /* [TVOID] */
17477dd7cddfSDavid du Colombier BSTRUCT, /* [TSTRUCT] */
17487dd7cddfSDavid du Colombier BUNION, /* [TUNION] */
17497dd7cddfSDavid du Colombier 0, /* [TENUM] */
17507dd7cddfSDavid du Colombier };
1751