17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier
351480713SDavid du Colombier static char resvreg[nelem(reg)];
451480713SDavid du Colombier
57dd7cddfSDavid du Colombier void
ginit(void)67dd7cddfSDavid du Colombier ginit(void)
77dd7cddfSDavid du Colombier {
87dd7cddfSDavid du Colombier Type *t;
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier thechar = '5';
117dd7cddfSDavid du Colombier thestring = "arm";
127dd7cddfSDavid du Colombier exregoffset = REGEXT;
137dd7cddfSDavid du Colombier exfregoffset = FREGEXT;
147dd7cddfSDavid du Colombier listinit();
157dd7cddfSDavid du Colombier nstring = 0;
167dd7cddfSDavid du Colombier mnstring = 0;
177dd7cddfSDavid du Colombier nrathole = 0;
187dd7cddfSDavid du Colombier pc = 0;
197dd7cddfSDavid du Colombier breakpc = -1;
207dd7cddfSDavid du Colombier continpc = -1;
217dd7cddfSDavid du Colombier cases = C;
227dd7cddfSDavid du Colombier firstp = P;
237dd7cddfSDavid du Colombier lastp = P;
247dd7cddfSDavid du Colombier tfield = types[TLONG];
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier zprog.link = P;
277dd7cddfSDavid du Colombier zprog.as = AGOK;
287dd7cddfSDavid du Colombier zprog.reg = NREG;
297dd7cddfSDavid du Colombier zprog.from.type = D_NONE;
307dd7cddfSDavid du Colombier zprog.from.name = D_NONE;
317dd7cddfSDavid du Colombier zprog.from.reg = NREG;
327dd7cddfSDavid du Colombier zprog.to = zprog.from;
337dd7cddfSDavid du Colombier zprog.scond = 0xE;
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier regnode.op = OREGISTER;
367dd7cddfSDavid du Colombier regnode.class = CEXREG;
377dd7cddfSDavid du Colombier regnode.reg = REGTMP;
387dd7cddfSDavid du Colombier regnode.complex = 0;
397dd7cddfSDavid du Colombier regnode.addable = 11;
407dd7cddfSDavid du Colombier regnode.type = types[TLONG];
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier constnode.op = OCONST;
437dd7cddfSDavid du Colombier constnode.class = CXXX;
447dd7cddfSDavid du Colombier constnode.complex = 0;
457dd7cddfSDavid du Colombier constnode.addable = 20;
467dd7cddfSDavid du Colombier constnode.type = types[TLONG];
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier fconstnode.op = OCONST;
497dd7cddfSDavid du Colombier fconstnode.class = CXXX;
507dd7cddfSDavid du Colombier fconstnode.complex = 0;
517dd7cddfSDavid du Colombier fconstnode.addable = 20;
527dd7cddfSDavid du Colombier fconstnode.type = types[TDOUBLE];
537dd7cddfSDavid du Colombier
547dd7cddfSDavid du Colombier nodsafe = new(ONAME, Z, Z);
557dd7cddfSDavid du Colombier nodsafe->sym = slookup(".safe");
567dd7cddfSDavid du Colombier nodsafe->type = types[TINT];
577dd7cddfSDavid du Colombier nodsafe->etype = types[TINT]->etype;
587dd7cddfSDavid du Colombier nodsafe->class = CAUTO;
597dd7cddfSDavid du Colombier complex(nodsafe);
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier t = typ(TARRAY, types[TCHAR]);
627dd7cddfSDavid du Colombier symrathole = slookup(".rathole");
637dd7cddfSDavid du Colombier symrathole->class = CGLOBL;
647dd7cddfSDavid du Colombier symrathole->type = t;
657dd7cddfSDavid du Colombier
667dd7cddfSDavid du Colombier nodrat = new(ONAME, Z, Z);
677dd7cddfSDavid du Colombier nodrat->sym = symrathole;
687dd7cddfSDavid du Colombier nodrat->type = types[TIND];
697dd7cddfSDavid du Colombier nodrat->etype = TVOID;
707dd7cddfSDavid du Colombier nodrat->class = CGLOBL;
717dd7cddfSDavid du Colombier complex(nodrat);
727dd7cddfSDavid du Colombier nodrat->type = t;
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier nodret = new(ONAME, Z, Z);
757dd7cddfSDavid du Colombier nodret->sym = slookup(".ret");
767dd7cddfSDavid du Colombier nodret->type = types[TIND];
777dd7cddfSDavid du Colombier nodret->etype = TIND;
787dd7cddfSDavid du Colombier nodret->class = CPARAM;
797dd7cddfSDavid du Colombier nodret = new(OIND, nodret, Z);
807dd7cddfSDavid du Colombier complex(nodret);
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier com64init();
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier memset(reg, 0, sizeof(reg));
8551480713SDavid du Colombier /* don't allocate */
8651480713SDavid du Colombier reg[REGTMP] = 1;
8751480713SDavid du Colombier reg[REGSB] = 1;
8851480713SDavid du Colombier reg[REGSP] = 1;
8951480713SDavid du Colombier reg[REGLINK] = 1;
9051480713SDavid du Colombier reg[REGPC] = 1;
9151480713SDavid du Colombier /* keep two external registers */
9251480713SDavid du Colombier reg[REGEXT] = 1;
9351480713SDavid du Colombier reg[REGEXT-1] = 1;
9451480713SDavid du Colombier memmove(resvreg, reg, sizeof(reg));
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier void
gclean(void)987dd7cddfSDavid du Colombier gclean(void)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier int i;
1017dd7cddfSDavid du Colombier Sym *s;
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier for(i=0; i<NREG; i++)
10451480713SDavid du Colombier if(reg[i] && !resvreg[i])
1057dd7cddfSDavid du Colombier diag(Z, "reg %d left allocated", i);
1067dd7cddfSDavid du Colombier for(i=NREG; i<NREG+NFREG; i++)
10751480713SDavid du Colombier if(reg[i] && !resvreg[i])
1087dd7cddfSDavid du Colombier diag(Z, "freg %d left allocated", i-NREG);
1097dd7cddfSDavid du Colombier while(mnstring)
1107dd7cddfSDavid du Colombier outstring("", 1L);
1117dd7cddfSDavid du Colombier symstring->type->width = nstring;
1127dd7cddfSDavid du Colombier symrathole->type->width = nrathole;
1137dd7cddfSDavid du Colombier for(i=0; i<NHASH; i++)
1147dd7cddfSDavid du Colombier for(s = hash[i]; s != S; s = s->link) {
1157dd7cddfSDavid du Colombier if(s->type == T)
1167dd7cddfSDavid du Colombier continue;
1177dd7cddfSDavid du Colombier if(s->type->width == 0)
1187dd7cddfSDavid du Colombier continue;
1197dd7cddfSDavid du Colombier if(s->class != CGLOBL && s->class != CSTATIC)
1207dd7cddfSDavid du Colombier continue;
1217dd7cddfSDavid du Colombier if(s->type == types[TENUM])
1227dd7cddfSDavid du Colombier continue;
1237dd7cddfSDavid du Colombier gpseudo(AGLOBL, s, nodconst(s->type->width));
1247dd7cddfSDavid du Colombier }
1257dd7cddfSDavid du Colombier nextpc();
1267dd7cddfSDavid du Colombier p->as = AEND;
1277dd7cddfSDavid du Colombier outcode();
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier void
nextpc(void)1317dd7cddfSDavid du Colombier nextpc(void)
1327dd7cddfSDavid du Colombier {
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier p = alloc(sizeof(*p));
1357dd7cddfSDavid du Colombier *p = zprog;
1367dd7cddfSDavid du Colombier p->lineno = nearln;
1377dd7cddfSDavid du Colombier pc++;
1387dd7cddfSDavid du Colombier if(firstp == P) {
1397dd7cddfSDavid du Colombier firstp = p;
1407dd7cddfSDavid du Colombier lastp = p;
1417dd7cddfSDavid du Colombier return;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier lastp->link = p;
1447dd7cddfSDavid du Colombier lastp = p;
1457dd7cddfSDavid du Colombier }
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)1487dd7cddfSDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
1497dd7cddfSDavid du Colombier {
1507dd7cddfSDavid du Colombier long regs;
1517dd7cddfSDavid du Colombier Node fnxargs[20], *fnxp;
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier regs = cursafe;
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier fnxp = fnxargs;
1567dd7cddfSDavid du Colombier garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier curarg = 0;
1597dd7cddfSDavid du Colombier fnxp = fnxargs;
1607dd7cddfSDavid du Colombier garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier cursafe = regs;
1637dd7cddfSDavid du Colombier }
1647dd7cddfSDavid du Colombier
1657dd7cddfSDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)1667dd7cddfSDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
1677dd7cddfSDavid du Colombier {
1687dd7cddfSDavid du Colombier Node nod;
1697dd7cddfSDavid du Colombier
1707dd7cddfSDavid du Colombier if(n == Z)
1717dd7cddfSDavid du Colombier return;
1727dd7cddfSDavid du Colombier if(n->op == OLIST) {
1737dd7cddfSDavid du Colombier garg1(n->left, tn1, tn2, f, fnxp);
1747dd7cddfSDavid du Colombier garg1(n->right, tn1, tn2, f, fnxp);
1757dd7cddfSDavid du Colombier return;
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier if(f == 0) {
1787dd7cddfSDavid du Colombier if(n->complex >= FNX) {
1797dd7cddfSDavid du Colombier regsalloc(*fnxp, n);
1807dd7cddfSDavid du Colombier nod = znode;
1817dd7cddfSDavid du Colombier nod.op = OAS;
1827dd7cddfSDavid du Colombier nod.left = *fnxp;
1837dd7cddfSDavid du Colombier nod.right = n;
1847dd7cddfSDavid du Colombier nod.type = n->type;
1854ac975e2SDavid du Colombier cgen(&nod, Z);
1867dd7cddfSDavid du Colombier (*fnxp)++;
1877dd7cddfSDavid du Colombier }
1887dd7cddfSDavid du Colombier return;
1897dd7cddfSDavid du Colombier }
1907dd7cddfSDavid du Colombier if(typesuv[n->type->etype]) {
1917dd7cddfSDavid du Colombier regaalloc(tn2, n);
1927dd7cddfSDavid du Colombier if(n->complex >= FNX) {
1937dd7cddfSDavid du Colombier sugen(*fnxp, tn2, n->type->width);
1947dd7cddfSDavid du Colombier (*fnxp)++;
1957dd7cddfSDavid du Colombier } else
1967dd7cddfSDavid du Colombier sugen(n, tn2, n->type->width);
1977dd7cddfSDavid du Colombier return;
1987dd7cddfSDavid du Colombier }
1997dd7cddfSDavid du Colombier if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
2007dd7cddfSDavid du Colombier regaalloc1(tn1, n);
2017dd7cddfSDavid du Colombier if(n->complex >= FNX) {
2024ac975e2SDavid du Colombier cgen(*fnxp, tn1);
2037dd7cddfSDavid du Colombier (*fnxp)++;
2047dd7cddfSDavid du Colombier } else
2054ac975e2SDavid du Colombier cgen(n, tn1);
2067dd7cddfSDavid du Colombier return;
2077dd7cddfSDavid du Colombier }
2087dd7cddfSDavid du Colombier regalloc(tn1, n, Z);
2097dd7cddfSDavid du Colombier if(n->complex >= FNX) {
2104ac975e2SDavid du Colombier cgen(*fnxp, tn1);
2117dd7cddfSDavid du Colombier (*fnxp)++;
2127dd7cddfSDavid du Colombier } else
2134ac975e2SDavid du Colombier cgen(n, tn1);
2147dd7cddfSDavid du Colombier regaalloc(tn2, n);
2157dd7cddfSDavid du Colombier gopcode(OAS, tn1, Z, tn2);
2167dd7cddfSDavid du Colombier regfree(tn1);
2177dd7cddfSDavid du Colombier }
2187dd7cddfSDavid du Colombier
2197dd7cddfSDavid du Colombier Node*
nodconst(long v)2207dd7cddfSDavid du Colombier nodconst(long v)
2217dd7cddfSDavid du Colombier {
2227dd7cddfSDavid du Colombier constnode.vconst = v;
2237dd7cddfSDavid du Colombier return &constnode;
2247dd7cddfSDavid du Colombier }
2257dd7cddfSDavid du Colombier
2267dd7cddfSDavid du Colombier Node*
nod32const(vlong v)2277dd7cddfSDavid du Colombier nod32const(vlong v)
2287dd7cddfSDavid du Colombier {
2297dd7cddfSDavid du Colombier constnode.vconst = v & MASK(32);
2307dd7cddfSDavid du Colombier return &constnode;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier Node*
nodfconst(double d)2347dd7cddfSDavid du Colombier nodfconst(double d)
2357dd7cddfSDavid du Colombier {
2367dd7cddfSDavid du Colombier fconstnode.fconst = d;
2377dd7cddfSDavid du Colombier return &fconstnode;
2387dd7cddfSDavid du Colombier }
2397dd7cddfSDavid du Colombier
2407dd7cddfSDavid du Colombier void
nodreg(Node * n,Node * nn,int reg)2417dd7cddfSDavid du Colombier nodreg(Node *n, Node *nn, int reg)
2427dd7cddfSDavid du Colombier {
2437dd7cddfSDavid du Colombier *n = regnode;
2447dd7cddfSDavid du Colombier n->reg = reg;
2457dd7cddfSDavid du Colombier n->type = nn->type;
2467dd7cddfSDavid du Colombier n->lineno = nn->lineno;
2477dd7cddfSDavid du Colombier }
2487dd7cddfSDavid du Colombier
2497dd7cddfSDavid du Colombier void
regret(Node * n,Node * nn)2507dd7cddfSDavid du Colombier regret(Node *n, Node *nn)
2517dd7cddfSDavid du Colombier {
2527dd7cddfSDavid du Colombier int r;
2537dd7cddfSDavid du Colombier
2547dd7cddfSDavid du Colombier r = REGRET;
2557dd7cddfSDavid du Colombier if(typefd[nn->type->etype])
2567dd7cddfSDavid du Colombier r = FREGRET+NREG;
2577dd7cddfSDavid du Colombier nodreg(n, nn, r);
2587dd7cddfSDavid du Colombier reg[r]++;
2597dd7cddfSDavid du Colombier }
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier int
tmpreg(void)2627dd7cddfSDavid du Colombier tmpreg(void)
2637dd7cddfSDavid du Colombier {
2647dd7cddfSDavid du Colombier int i;
2657dd7cddfSDavid du Colombier
2667dd7cddfSDavid du Colombier for(i=REGRET+1; i<NREG; i++)
2677dd7cddfSDavid du Colombier if(reg[i] == 0)
2687dd7cddfSDavid du Colombier return i;
2697dd7cddfSDavid du Colombier diag(Z, "out of fixed registers");
2707dd7cddfSDavid du Colombier return 0;
2717dd7cddfSDavid du Colombier }
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2747dd7cddfSDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2757dd7cddfSDavid du Colombier {
2767dd7cddfSDavid du Colombier int i, j;
277375daca8SDavid du Colombier static int lasti;
2787dd7cddfSDavid du Colombier
2797dd7cddfSDavid du Colombier switch(tn->type->etype) {
2807dd7cddfSDavid du Colombier case TCHAR:
2817dd7cddfSDavid du Colombier case TUCHAR:
2827dd7cddfSDavid du Colombier case TSHORT:
2837dd7cddfSDavid du Colombier case TUSHORT:
2847dd7cddfSDavid du Colombier case TINT:
2857dd7cddfSDavid du Colombier case TUINT:
2867dd7cddfSDavid du Colombier case TLONG:
2877dd7cddfSDavid du Colombier case TULONG:
2887dd7cddfSDavid du Colombier case TIND:
2897dd7cddfSDavid du Colombier if(o != Z && o->op == OREGISTER) {
2907dd7cddfSDavid du Colombier i = o->reg;
2917dd7cddfSDavid du Colombier if(i >= 0 && i < NREG)
2927dd7cddfSDavid du Colombier goto out;
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier j = lasti + REGRET+1;
2957dd7cddfSDavid du Colombier for(i=REGRET+1; i<NREG; i++) {
2967dd7cddfSDavid du Colombier if(j >= NREG)
2977dd7cddfSDavid du Colombier j = REGRET+1;
29851480713SDavid du Colombier if(reg[j] == 0 && resvreg[j] == 0) {
2997dd7cddfSDavid du Colombier i = j;
3007dd7cddfSDavid du Colombier goto out;
3017dd7cddfSDavid du Colombier }
3027dd7cddfSDavid du Colombier j++;
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier diag(tn, "out of fixed registers");
3057dd7cddfSDavid du Colombier goto err;
3067dd7cddfSDavid du Colombier
3077dd7cddfSDavid du Colombier case TFLOAT:
3087dd7cddfSDavid du Colombier case TDOUBLE:
3097dd7cddfSDavid du Colombier case TVLONG:
3107dd7cddfSDavid du Colombier if(o != Z && o->op == OREGISTER) {
3117dd7cddfSDavid du Colombier i = o->reg;
3127dd7cddfSDavid du Colombier if(i >= NREG && i < NREG+NFREG)
3137dd7cddfSDavid du Colombier goto out;
3147dd7cddfSDavid du Colombier }
3157dd7cddfSDavid du Colombier j = 0*2 + NREG;
31659cc4ca5SDavid du Colombier for(i=NREG; i<NREG+NFREG; i++) {
31759cc4ca5SDavid du Colombier if(j >= NREG+NFREG)
3187dd7cddfSDavid du Colombier j = NREG;
3197dd7cddfSDavid du Colombier if(reg[j] == 0) {
3207dd7cddfSDavid du Colombier i = j;
3217dd7cddfSDavid du Colombier goto out;
3227dd7cddfSDavid du Colombier }
3237dd7cddfSDavid du Colombier j++;
3247dd7cddfSDavid du Colombier }
3257dd7cddfSDavid du Colombier diag(tn, "out of float registers");
3267dd7cddfSDavid du Colombier goto err;
3277dd7cddfSDavid du Colombier }
3287dd7cddfSDavid du Colombier diag(tn, "unknown type in regalloc: %T", tn->type);
3297dd7cddfSDavid du Colombier err:
3307dd7cddfSDavid du Colombier nodreg(n, tn, 0);
3317dd7cddfSDavid du Colombier return;
3327dd7cddfSDavid du Colombier out:
3337dd7cddfSDavid du Colombier reg[i]++;
33451480713SDavid du Colombier lasti++;
3357dd7cddfSDavid du Colombier if(lasti >= 5)
3367dd7cddfSDavid du Colombier lasti = 0;
3377dd7cddfSDavid du Colombier nodreg(n, tn, i);
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier
3407dd7cddfSDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3417dd7cddfSDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3427dd7cddfSDavid du Colombier {
3437dd7cddfSDavid du Colombier Node nod;
3447dd7cddfSDavid du Colombier
3457dd7cddfSDavid du Colombier nod = *tn;
3467dd7cddfSDavid du Colombier nod.type = types[TIND];
3477dd7cddfSDavid du Colombier regalloc(n, &nod, o);
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier
3507dd7cddfSDavid du Colombier void
regfree(Node * n)3517dd7cddfSDavid du Colombier regfree(Node *n)
3527dd7cddfSDavid du Colombier {
3537dd7cddfSDavid du Colombier int i;
3547dd7cddfSDavid du Colombier
3557dd7cddfSDavid du Colombier i = 0;
3567dd7cddfSDavid du Colombier if(n->op != OREGISTER && n->op != OINDREG)
3577dd7cddfSDavid du Colombier goto err;
3587dd7cddfSDavid du Colombier i = n->reg;
3597dd7cddfSDavid du Colombier if(i < 0 || i >= sizeof(reg))
3607dd7cddfSDavid du Colombier goto err;
3617dd7cddfSDavid du Colombier if(reg[i] <= 0)
3627dd7cddfSDavid du Colombier goto err;
3637dd7cddfSDavid du Colombier reg[i]--;
3647dd7cddfSDavid du Colombier return;
3657dd7cddfSDavid du Colombier err:
3667dd7cddfSDavid du Colombier diag(n, "error in regfree: %d", i);
3677dd7cddfSDavid du Colombier }
3687dd7cddfSDavid du Colombier
3697dd7cddfSDavid du Colombier void
regsalloc(Node * n,Node * nn)3707dd7cddfSDavid du Colombier regsalloc(Node *n, Node *nn)
3717dd7cddfSDavid du Colombier {
3727dd7cddfSDavid du Colombier cursafe = align(cursafe, nn->type, Aaut3);
3737dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
3747dd7cddfSDavid du Colombier *n = *nodsafe;
3757dd7cddfSDavid du Colombier n->xoffset = -(stkoff + cursafe);
3767dd7cddfSDavid du Colombier n->type = nn->type;
3777dd7cddfSDavid du Colombier n->etype = nn->type->etype;
3787dd7cddfSDavid du Colombier n->lineno = nn->lineno;
3797dd7cddfSDavid du Colombier }
3807dd7cddfSDavid du Colombier
3817dd7cddfSDavid du Colombier void
regaalloc1(Node * n,Node * nn)3827dd7cddfSDavid du Colombier regaalloc1(Node *n, Node *nn)
3837dd7cddfSDavid du Colombier {
3847dd7cddfSDavid du Colombier nodreg(n, nn, REGARG);
3857dd7cddfSDavid du Colombier reg[REGARG]++;
3867dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
3877dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
3887dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
3897dd7cddfSDavid du Colombier }
3907dd7cddfSDavid du Colombier
3917dd7cddfSDavid du Colombier void
regaalloc(Node * n,Node * nn)3927dd7cddfSDavid du Colombier regaalloc(Node *n, Node *nn)
3937dd7cddfSDavid du Colombier {
3947dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg1);
3957dd7cddfSDavid du Colombier *n = *nn;
3967dd7cddfSDavid du Colombier n->op = OINDREG;
3977dd7cddfSDavid du Colombier n->reg = REGSP;
3987dd7cddfSDavid du Colombier n->xoffset = curarg + SZ_LONG;
3997dd7cddfSDavid du Colombier n->complex = 0;
4007dd7cddfSDavid du Colombier n->addable = 20;
4017dd7cddfSDavid du Colombier curarg = align(curarg, nn->type, Aarg2);
4027dd7cddfSDavid du Colombier maxargsafe = maxround(maxargsafe, cursafe+curarg);
4037dd7cddfSDavid du Colombier }
4047dd7cddfSDavid du Colombier
4057dd7cddfSDavid du Colombier void
regind(Node * n,Node * nn)4067dd7cddfSDavid du Colombier regind(Node *n, Node *nn)
4077dd7cddfSDavid du Colombier {
4087dd7cddfSDavid du Colombier
4097dd7cddfSDavid du Colombier if(n->op != OREGISTER) {
4107dd7cddfSDavid du Colombier diag(n, "regind not OREGISTER");
4117dd7cddfSDavid du Colombier return;
4127dd7cddfSDavid du Colombier }
4137dd7cddfSDavid du Colombier n->op = OINDREG;
4147dd7cddfSDavid du Colombier n->type = nn->type;
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier
4177dd7cddfSDavid du Colombier void
raddr(Node * n,Prog * p)4187dd7cddfSDavid du Colombier raddr(Node *n, Prog *p)
4197dd7cddfSDavid du Colombier {
4207dd7cddfSDavid du Colombier Adr a;
4217dd7cddfSDavid du Colombier
4227dd7cddfSDavid du Colombier naddr(n, &a);
4237dd7cddfSDavid du Colombier if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
4247dd7cddfSDavid du Colombier a.type = D_REG;
4257dd7cddfSDavid du Colombier a.reg = 0;
4267dd7cddfSDavid du Colombier }
4277dd7cddfSDavid du Colombier if(a.type != D_REG && a.type != D_FREG) {
4287dd7cddfSDavid du Colombier if(n)
4297dd7cddfSDavid du Colombier diag(n, "bad in raddr: %O", n->op);
4307dd7cddfSDavid du Colombier else
4317dd7cddfSDavid du Colombier diag(n, "bad in raddr: <null>");
4327dd7cddfSDavid du Colombier p->reg = NREG;
4337dd7cddfSDavid du Colombier } else
4347dd7cddfSDavid du Colombier p->reg = a.reg;
4357dd7cddfSDavid du Colombier }
4367dd7cddfSDavid du Colombier
4377dd7cddfSDavid du Colombier void
naddr(Node * n,Adr * a)4387dd7cddfSDavid du Colombier naddr(Node *n, Adr *a)
4397dd7cddfSDavid du Colombier {
4407dd7cddfSDavid du Colombier long v;
4417dd7cddfSDavid du Colombier
4427dd7cddfSDavid du Colombier a->type = D_NONE;
4437dd7cddfSDavid du Colombier if(n == Z)
4447dd7cddfSDavid du Colombier return;
4457dd7cddfSDavid du Colombier switch(n->op) {
4467dd7cddfSDavid du Colombier default:
4477dd7cddfSDavid du Colombier bad:
4487dd7cddfSDavid du Colombier diag(n, "bad in naddr: %O", n->op);
4497dd7cddfSDavid du Colombier break;
4507dd7cddfSDavid du Colombier
4517dd7cddfSDavid du Colombier case OREGISTER:
4527dd7cddfSDavid du Colombier a->type = D_REG;
4537dd7cddfSDavid du Colombier a->sym = S;
4547dd7cddfSDavid du Colombier a->reg = n->reg;
4557dd7cddfSDavid du Colombier if(a->reg >= NREG) {
4567dd7cddfSDavid du Colombier a->type = D_FREG;
4577dd7cddfSDavid du Colombier a->reg -= NREG;
4587dd7cddfSDavid du Colombier }
4597dd7cddfSDavid du Colombier break;
4607dd7cddfSDavid du Colombier
4617dd7cddfSDavid du Colombier case OIND:
4627dd7cddfSDavid du Colombier naddr(n->left, a);
4637dd7cddfSDavid du Colombier if(a->type == D_REG) {
4647dd7cddfSDavid du Colombier a->type = D_OREG;
4657dd7cddfSDavid du Colombier break;
4667dd7cddfSDavid du Colombier }
4677dd7cddfSDavid du Colombier if(a->type == D_CONST) {
4687dd7cddfSDavid du Colombier a->type = D_OREG;
4697dd7cddfSDavid du Colombier break;
4707dd7cddfSDavid du Colombier }
4717dd7cddfSDavid du Colombier goto bad;
4727dd7cddfSDavid du Colombier
4737dd7cddfSDavid du Colombier case OINDREG:
4747dd7cddfSDavid du Colombier a->type = D_OREG;
4757dd7cddfSDavid du Colombier a->sym = S;
4767dd7cddfSDavid du Colombier a->offset = n->xoffset;
4777dd7cddfSDavid du Colombier a->reg = n->reg;
4787dd7cddfSDavid du Colombier break;
4797dd7cddfSDavid du Colombier
4807dd7cddfSDavid du Colombier case ONAME:
4817dd7cddfSDavid du Colombier a->etype = n->etype;
4827dd7cddfSDavid du Colombier a->type = D_OREG;
4837dd7cddfSDavid du Colombier a->name = D_STATIC;
4847dd7cddfSDavid du Colombier a->sym = n->sym;
4857dd7cddfSDavid du Colombier a->offset = n->xoffset;
4867dd7cddfSDavid du Colombier if(n->class == CSTATIC)
4877dd7cddfSDavid du Colombier break;
4887dd7cddfSDavid du Colombier if(n->class == CEXTERN || n->class == CGLOBL) {
4897dd7cddfSDavid du Colombier a->name = D_EXTERN;
4907dd7cddfSDavid du Colombier break;
4917dd7cddfSDavid du Colombier }
4927dd7cddfSDavid du Colombier if(n->class == CAUTO) {
4937dd7cddfSDavid du Colombier a->name = D_AUTO;
4947dd7cddfSDavid du Colombier break;
4957dd7cddfSDavid du Colombier }
4967dd7cddfSDavid du Colombier if(n->class == CPARAM) {
4977dd7cddfSDavid du Colombier a->name = D_PARAM;
4987dd7cddfSDavid du Colombier break;
4997dd7cddfSDavid du Colombier }
5007dd7cddfSDavid du Colombier goto bad;
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier case OCONST:
5037dd7cddfSDavid du Colombier a->sym = S;
5047dd7cddfSDavid du Colombier a->reg = NREG;
5057dd7cddfSDavid du Colombier if(typefd[n->type->etype]) {
5067dd7cddfSDavid du Colombier a->type = D_FCONST;
5077dd7cddfSDavid du Colombier a->dval = n->fconst;
5087dd7cddfSDavid du Colombier } else {
5097dd7cddfSDavid du Colombier a->type = D_CONST;
5107dd7cddfSDavid du Colombier a->offset = n->vconst;
5117dd7cddfSDavid du Colombier }
5127dd7cddfSDavid du Colombier break;
5137dd7cddfSDavid du Colombier
5147dd7cddfSDavid du Colombier case OADDR:
5157dd7cddfSDavid du Colombier naddr(n->left, a);
5167dd7cddfSDavid du Colombier if(a->type == D_OREG) {
5177dd7cddfSDavid du Colombier a->type = D_CONST;
5187dd7cddfSDavid du Colombier break;
5197dd7cddfSDavid du Colombier }
5207dd7cddfSDavid du Colombier goto bad;
5217dd7cddfSDavid du Colombier
5227dd7cddfSDavid du Colombier case OADD:
5237dd7cddfSDavid du Colombier if(n->left->op == OCONST) {
5247dd7cddfSDavid du Colombier naddr(n->left, a);
5257dd7cddfSDavid du Colombier v = a->offset;
5267dd7cddfSDavid du Colombier naddr(n->right, a);
5277dd7cddfSDavid du Colombier } else {
5287dd7cddfSDavid du Colombier naddr(n->right, a);
5297dd7cddfSDavid du Colombier v = a->offset;
5307dd7cddfSDavid du Colombier naddr(n->left, a);
5317dd7cddfSDavid du Colombier }
5327dd7cddfSDavid du Colombier a->offset += v;
5337dd7cddfSDavid du Colombier break;
5347dd7cddfSDavid du Colombier
5357dd7cddfSDavid du Colombier }
5367dd7cddfSDavid du Colombier }
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier void
fop(int as,int f1,int f2,Node * t)5397dd7cddfSDavid du Colombier fop(int as, int f1, int f2, Node *t)
5407dd7cddfSDavid du Colombier {
5417dd7cddfSDavid du Colombier Node nod1, nod2, nod3;
5427dd7cddfSDavid du Colombier
5437dd7cddfSDavid du Colombier nodreg(&nod1, t, NREG+f1);
5447dd7cddfSDavid du Colombier nodreg(&nod2, t, NREG+f2);
5457dd7cddfSDavid du Colombier regalloc(&nod3, t, t);
5467dd7cddfSDavid du Colombier gopcode(as, &nod1, &nod2, &nod3);
5477dd7cddfSDavid du Colombier gmove(&nod3, t);
5487dd7cddfSDavid du Colombier regfree(&nod3);
5497dd7cddfSDavid du Colombier }
5507dd7cddfSDavid du Colombier
5517dd7cddfSDavid du Colombier void
gmovm(Node * f,Node * t,int w)55259cc4ca5SDavid du Colombier gmovm(Node *f, Node *t, int w)
55359cc4ca5SDavid du Colombier {
55459cc4ca5SDavid du Colombier gins(AMOVM, f, t);
55559cc4ca5SDavid du Colombier p->scond |= C_UBIT;
55659cc4ca5SDavid du Colombier if(w)
55759cc4ca5SDavid du Colombier p->scond |= C_WBIT;
55859cc4ca5SDavid du Colombier }
55959cc4ca5SDavid du Colombier
56059cc4ca5SDavid du Colombier void
gmove(Node * f,Node * t)5617dd7cddfSDavid du Colombier gmove(Node *f, Node *t)
5627dd7cddfSDavid du Colombier {
5637dd7cddfSDavid du Colombier int ft, tt, a;
5645efba406SDavid du Colombier Node nod, nod1;
5655efba406SDavid du Colombier Prog *p1;
5667dd7cddfSDavid du Colombier
5677dd7cddfSDavid du Colombier ft = f->type->etype;
5687dd7cddfSDavid du Colombier tt = t->type->etype;
5697dd7cddfSDavid du Colombier
5707dd7cddfSDavid du Colombier if(ft == TDOUBLE && f->op == OCONST) {
5717dd7cddfSDavid du Colombier }
5727dd7cddfSDavid du Colombier if(ft == TFLOAT && f->op == OCONST) {
5737dd7cddfSDavid du Colombier }
5747dd7cddfSDavid du Colombier
5757dd7cddfSDavid du Colombier /*
5767dd7cddfSDavid du Colombier * a load --
5777dd7cddfSDavid du Colombier * put it into a register then
5787dd7cddfSDavid du Colombier * worry what to do with it.
5797dd7cddfSDavid du Colombier */
5807dd7cddfSDavid du Colombier if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
5817dd7cddfSDavid du Colombier switch(ft) {
5827dd7cddfSDavid du Colombier default:
5837dd7cddfSDavid du Colombier a = AMOVW;
5847dd7cddfSDavid du Colombier break;
5857dd7cddfSDavid du Colombier case TFLOAT:
5867dd7cddfSDavid du Colombier a = AMOVF;
5877dd7cddfSDavid du Colombier break;
5887dd7cddfSDavid du Colombier case TDOUBLE:
5897dd7cddfSDavid du Colombier a = AMOVD;
5907dd7cddfSDavid du Colombier break;
5917dd7cddfSDavid du Colombier case TCHAR:
5927dd7cddfSDavid du Colombier a = AMOVB;
5937dd7cddfSDavid du Colombier break;
5947dd7cddfSDavid du Colombier case TUCHAR:
5957dd7cddfSDavid du Colombier a = AMOVBU;
5967dd7cddfSDavid du Colombier break;
5977dd7cddfSDavid du Colombier case TSHORT:
5987dd7cddfSDavid du Colombier a = AMOVH;
5997dd7cddfSDavid du Colombier break;
6007dd7cddfSDavid du Colombier case TUSHORT:
6017dd7cddfSDavid du Colombier a = AMOVHU;
6027dd7cddfSDavid du Colombier break;
6037dd7cddfSDavid du Colombier }
6047dd7cddfSDavid du Colombier if(typechlp[ft] && typeilp[tt])
6057dd7cddfSDavid du Colombier regalloc(&nod, t, t);
6067dd7cddfSDavid du Colombier else
6077dd7cddfSDavid du Colombier regalloc(&nod, f, t);
6087dd7cddfSDavid du Colombier gins(a, f, &nod);
6097dd7cddfSDavid du Colombier gmove(&nod, t);
6107dd7cddfSDavid du Colombier regfree(&nod);
6117dd7cddfSDavid du Colombier return;
6127dd7cddfSDavid du Colombier }
6137dd7cddfSDavid du Colombier
6147dd7cddfSDavid du Colombier /*
6157dd7cddfSDavid du Colombier * a store --
6167dd7cddfSDavid du Colombier * put it into a register then
6177dd7cddfSDavid du Colombier * store it.
6187dd7cddfSDavid du Colombier */
6197dd7cddfSDavid du Colombier if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
6207dd7cddfSDavid du Colombier switch(tt) {
6217dd7cddfSDavid du Colombier default:
6227dd7cddfSDavid du Colombier a = AMOVW;
6237dd7cddfSDavid du Colombier break;
6247dd7cddfSDavid du Colombier case TUCHAR:
625375daca8SDavid du Colombier a = AMOVBU;
626375daca8SDavid du Colombier break;
6277dd7cddfSDavid du Colombier case TCHAR:
6287dd7cddfSDavid du Colombier a = AMOVB;
6297dd7cddfSDavid du Colombier break;
6307dd7cddfSDavid du Colombier case TUSHORT:
631375daca8SDavid du Colombier a = AMOVHU;
632375daca8SDavid du Colombier break;
6337dd7cddfSDavid du Colombier case TSHORT:
6347dd7cddfSDavid du Colombier a = AMOVH;
6357dd7cddfSDavid du Colombier break;
6367dd7cddfSDavid du Colombier case TFLOAT:
6377dd7cddfSDavid du Colombier a = AMOVF;
6387dd7cddfSDavid du Colombier break;
6397dd7cddfSDavid du Colombier case TVLONG:
6407dd7cddfSDavid du Colombier case TDOUBLE:
6417dd7cddfSDavid du Colombier a = AMOVD;
6427dd7cddfSDavid du Colombier break;
6437dd7cddfSDavid du Colombier }
6447dd7cddfSDavid du Colombier if(ft == tt)
6457dd7cddfSDavid du Colombier regalloc(&nod, t, f);
6467dd7cddfSDavid du Colombier else
6477dd7cddfSDavid du Colombier regalloc(&nod, t, Z);
6487dd7cddfSDavid du Colombier gmove(f, &nod);
6497dd7cddfSDavid du Colombier gins(a, &nod, t);
6507dd7cddfSDavid du Colombier regfree(&nod);
6517dd7cddfSDavid du Colombier return;
6527dd7cddfSDavid du Colombier }
6537dd7cddfSDavid du Colombier
6547dd7cddfSDavid du Colombier /*
6557dd7cddfSDavid du Colombier * type x type cross table
6567dd7cddfSDavid du Colombier */
6577dd7cddfSDavid du Colombier a = AGOK;
6587dd7cddfSDavid du Colombier switch(ft) {
6597dd7cddfSDavid du Colombier case TDOUBLE:
6607dd7cddfSDavid du Colombier case TVLONG:
6617dd7cddfSDavid du Colombier case TFLOAT:
6627dd7cddfSDavid du Colombier switch(tt) {
6637dd7cddfSDavid du Colombier case TDOUBLE:
6647dd7cddfSDavid du Colombier case TVLONG:
6657dd7cddfSDavid du Colombier a = AMOVD;
6667dd7cddfSDavid du Colombier if(ft == TFLOAT)
6677dd7cddfSDavid du Colombier a = AMOVFD;
6687dd7cddfSDavid du Colombier break;
6697dd7cddfSDavid du Colombier case TFLOAT:
6707dd7cddfSDavid du Colombier a = AMOVDF;
6717dd7cddfSDavid du Colombier if(ft == TFLOAT)
6727dd7cddfSDavid du Colombier a = AMOVF;
6737dd7cddfSDavid du Colombier break;
6747dd7cddfSDavid du Colombier case TINT:
6757dd7cddfSDavid du Colombier case TUINT:
6767dd7cddfSDavid du Colombier case TLONG:
6777dd7cddfSDavid du Colombier case TULONG:
6787dd7cddfSDavid du Colombier case TIND:
6797dd7cddfSDavid du Colombier a = AMOVDW;
6807dd7cddfSDavid du Colombier if(ft == TFLOAT)
6817dd7cddfSDavid du Colombier a = AMOVFW;
6827dd7cddfSDavid du Colombier break;
6837dd7cddfSDavid du Colombier case TSHORT:
6847dd7cddfSDavid du Colombier case TUSHORT:
6857dd7cddfSDavid du Colombier case TCHAR:
6867dd7cddfSDavid du Colombier case TUCHAR:
6877dd7cddfSDavid du Colombier a = AMOVDW;
6887dd7cddfSDavid du Colombier if(ft == TFLOAT)
6897dd7cddfSDavid du Colombier a = AMOVFW;
6907dd7cddfSDavid du Colombier break;
6917dd7cddfSDavid du Colombier }
6927dd7cddfSDavid du Colombier break;
6937dd7cddfSDavid du Colombier case TUINT:
6947dd7cddfSDavid du Colombier case TULONG:
6955efba406SDavid du Colombier if(tt == TFLOAT || tt == TDOUBLE) {
6965efba406SDavid du Colombier // ugly and probably longer than necessary,
6975efba406SDavid du Colombier // but vfp has a single instruction for this,
6985efba406SDavid du Colombier // so hopefully it won't last long.
6995efba406SDavid du Colombier //
7005efba406SDavid du Colombier // tmp = f
7015efba406SDavid du Colombier // tmp1 = tmp & 0x80000000
7025efba406SDavid du Colombier // tmp ^= tmp1
7035efba406SDavid du Colombier // t = float(int32(tmp))
7045efba406SDavid du Colombier // if(tmp1)
7055efba406SDavid du Colombier // t += 2147483648.
7065efba406SDavid du Colombier //
7075efba406SDavid du Colombier regalloc(&nod, f, Z);
7085efba406SDavid du Colombier regalloc(&nod1, f, Z);
7095efba406SDavid du Colombier gins(AMOVW, f, &nod);
7105efba406SDavid du Colombier gins(AMOVW, &nod, &nod1);
7115efba406SDavid du Colombier gins(AAND, nodconst(0x80000000), &nod1);
7125efba406SDavid du Colombier gins(AEOR, &nod1, &nod);
7135efba406SDavid du Colombier if(tt == TFLOAT)
7145efba406SDavid du Colombier gins(AMOVWF, &nod, t);
7155efba406SDavid du Colombier else
7165efba406SDavid du Colombier gins(AMOVWD, &nod, t);
7175efba406SDavid du Colombier gins(ACMP, nodconst(0), Z);
7185efba406SDavid du Colombier raddr(&nod1, p);
7195efba406SDavid du Colombier gins(ABEQ, Z, Z);
7205efba406SDavid du Colombier regfree(&nod);
7215efba406SDavid du Colombier regfree(&nod1);
7225efba406SDavid du Colombier p1 = p;
7235efba406SDavid du Colombier regalloc(&nod, t, Z);
7249b7bf7dfSDavid du Colombier if(tt == TFLOAT) {
7255efba406SDavid du Colombier gins(AMOVF, nodfconst(2147483648.), &nod);
7265efba406SDavid du Colombier gins(AADDF, &nod, t);
7279b7bf7dfSDavid du Colombier } else {
7289b7bf7dfSDavid du Colombier gins(AMOVD, nodfconst(2147483648.), &nod);
7299b7bf7dfSDavid du Colombier gins(AADDD, &nod, t);
7309b7bf7dfSDavid du Colombier }
7315efba406SDavid du Colombier regfree(&nod);
7325efba406SDavid du Colombier patch(p1, pc);
7335efba406SDavid du Colombier return;
7345efba406SDavid du Colombier }
7355efba406SDavid du Colombier // fall through
7365efba406SDavid du Colombier
7375efba406SDavid du Colombier case TINT:
7387dd7cddfSDavid du Colombier case TLONG:
7397dd7cddfSDavid du Colombier case TIND:
7407dd7cddfSDavid du Colombier switch(tt) {
7417dd7cddfSDavid du Colombier case TDOUBLE:
7427dd7cddfSDavid du Colombier gins(AMOVWD, f, t);
7437dd7cddfSDavid du Colombier return;
7447dd7cddfSDavid du Colombier case TFLOAT:
7457dd7cddfSDavid du Colombier gins(AMOVWF, f, t);
7467dd7cddfSDavid du Colombier return;
7477dd7cddfSDavid du Colombier case TINT:
7487dd7cddfSDavid du Colombier case TUINT:
7497dd7cddfSDavid du Colombier case TLONG:
7507dd7cddfSDavid du Colombier case TULONG:
7517dd7cddfSDavid du Colombier case TIND:
7527dd7cddfSDavid du Colombier case TSHORT:
7537dd7cddfSDavid du Colombier case TUSHORT:
7547dd7cddfSDavid du Colombier case TCHAR:
7557dd7cddfSDavid du Colombier case TUCHAR:
7567dd7cddfSDavid du Colombier a = AMOVW;
7577dd7cddfSDavid du Colombier break;
7587dd7cddfSDavid du Colombier }
7597dd7cddfSDavid du Colombier break;
7607dd7cddfSDavid du Colombier case TSHORT:
7617dd7cddfSDavid du Colombier switch(tt) {
7627dd7cddfSDavid du Colombier case TDOUBLE:
7637dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
7647dd7cddfSDavid du Colombier gins(AMOVH, f, &nod);
7657dd7cddfSDavid du Colombier gins(AMOVWD, &nod, t);
7667dd7cddfSDavid du Colombier regfree(&nod);
7677dd7cddfSDavid du Colombier return;
7687dd7cddfSDavid du Colombier case TFLOAT:
7697dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
7707dd7cddfSDavid du Colombier gins(AMOVH, f, &nod);
7717dd7cddfSDavid du Colombier gins(AMOVWF, &nod, t);
7727dd7cddfSDavid du Colombier regfree(&nod);
7737dd7cddfSDavid du Colombier return;
7747dd7cddfSDavid du Colombier case TUINT:
7757dd7cddfSDavid du Colombier case TINT:
7767dd7cddfSDavid du Colombier case TULONG:
7777dd7cddfSDavid du Colombier case TLONG:
7787dd7cddfSDavid du Colombier case TIND:
7797dd7cddfSDavid du Colombier a = AMOVH;
7807dd7cddfSDavid du Colombier break;
7817dd7cddfSDavid du Colombier case TSHORT:
7827dd7cddfSDavid du Colombier case TUSHORT:
7837dd7cddfSDavid du Colombier case TCHAR:
7847dd7cddfSDavid du Colombier case TUCHAR:
7857dd7cddfSDavid du Colombier a = AMOVW;
7867dd7cddfSDavid du Colombier break;
7877dd7cddfSDavid du Colombier }
7887dd7cddfSDavid du Colombier break;
7897dd7cddfSDavid du Colombier case TUSHORT:
7907dd7cddfSDavid du Colombier switch(tt) {
7917dd7cddfSDavid du Colombier case TDOUBLE:
7927dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
7937dd7cddfSDavid du Colombier gins(AMOVHU, f, &nod);
7947dd7cddfSDavid du Colombier gins(AMOVWD, &nod, t);
7957dd7cddfSDavid du Colombier regfree(&nod);
7967dd7cddfSDavid du Colombier return;
7977dd7cddfSDavid du Colombier case TFLOAT:
7987dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
7997dd7cddfSDavid du Colombier gins(AMOVHU, f, &nod);
8007dd7cddfSDavid du Colombier gins(AMOVWF, &nod, t);
8017dd7cddfSDavid du Colombier regfree(&nod);
8027dd7cddfSDavid du Colombier return;
8037dd7cddfSDavid du Colombier case TINT:
8047dd7cddfSDavid du Colombier case TUINT:
8057dd7cddfSDavid du Colombier case TLONG:
8067dd7cddfSDavid du Colombier case TULONG:
8077dd7cddfSDavid du Colombier case TIND:
8087dd7cddfSDavid du Colombier a = AMOVHU;
8097dd7cddfSDavid du Colombier break;
8107dd7cddfSDavid du Colombier case TSHORT:
8117dd7cddfSDavid du Colombier case TUSHORT:
8127dd7cddfSDavid du Colombier case TCHAR:
8137dd7cddfSDavid du Colombier case TUCHAR:
8147dd7cddfSDavid du Colombier a = AMOVW;
8157dd7cddfSDavid du Colombier break;
8167dd7cddfSDavid du Colombier }
8177dd7cddfSDavid du Colombier break;
8187dd7cddfSDavid du Colombier case TCHAR:
8197dd7cddfSDavid du Colombier switch(tt) {
8207dd7cddfSDavid du Colombier case TDOUBLE:
8217dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
8227dd7cddfSDavid du Colombier gins(AMOVB, f, &nod);
8237dd7cddfSDavid du Colombier gins(AMOVWD, &nod, t);
8247dd7cddfSDavid du Colombier regfree(&nod);
8257dd7cddfSDavid du Colombier return;
8267dd7cddfSDavid du Colombier case TFLOAT:
8277dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
8287dd7cddfSDavid du Colombier gins(AMOVB, f, &nod);
8297dd7cddfSDavid du Colombier gins(AMOVWF, &nod, t);
8307dd7cddfSDavid du Colombier regfree(&nod);
8317dd7cddfSDavid du Colombier return;
8327dd7cddfSDavid du Colombier case TINT:
8337dd7cddfSDavid du Colombier case TUINT:
8347dd7cddfSDavid du Colombier case TLONG:
8357dd7cddfSDavid du Colombier case TULONG:
8367dd7cddfSDavid du Colombier case TIND:
8377dd7cddfSDavid du Colombier case TSHORT:
8387dd7cddfSDavid du Colombier case TUSHORT:
8397dd7cddfSDavid du Colombier a = AMOVB;
8407dd7cddfSDavid du Colombier break;
8417dd7cddfSDavid du Colombier case TCHAR:
8427dd7cddfSDavid du Colombier case TUCHAR:
8437dd7cddfSDavid du Colombier a = AMOVW;
8447dd7cddfSDavid du Colombier break;
8457dd7cddfSDavid du Colombier }
8467dd7cddfSDavid du Colombier break;
8477dd7cddfSDavid du Colombier case TUCHAR:
8487dd7cddfSDavid du Colombier switch(tt) {
8497dd7cddfSDavid du Colombier case TDOUBLE:
8507dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
8517dd7cddfSDavid du Colombier gins(AMOVBU, f, &nod);
8527dd7cddfSDavid du Colombier gins(AMOVWD, &nod, t);
8537dd7cddfSDavid du Colombier regfree(&nod);
8547dd7cddfSDavid du Colombier return;
8557dd7cddfSDavid du Colombier case TFLOAT:
8567dd7cddfSDavid du Colombier regalloc(&nod, f, Z);
8577dd7cddfSDavid du Colombier gins(AMOVBU, f, &nod);
8587dd7cddfSDavid du Colombier gins(AMOVWF, &nod, t);
8597dd7cddfSDavid du Colombier regfree(&nod);
8607dd7cddfSDavid du Colombier return;
8617dd7cddfSDavid du Colombier case TINT:
8627dd7cddfSDavid du Colombier case TUINT:
8637dd7cddfSDavid du Colombier case TLONG:
8647dd7cddfSDavid du Colombier case TULONG:
8657dd7cddfSDavid du Colombier case TIND:
8667dd7cddfSDavid du Colombier case TSHORT:
8677dd7cddfSDavid du Colombier case TUSHORT:
8687dd7cddfSDavid du Colombier a = AMOVBU;
8697dd7cddfSDavid du Colombier break;
8707dd7cddfSDavid du Colombier case TCHAR:
8717dd7cddfSDavid du Colombier case TUCHAR:
8727dd7cddfSDavid du Colombier a = AMOVW;
8737dd7cddfSDavid du Colombier break;
8747dd7cddfSDavid du Colombier }
8757dd7cddfSDavid du Colombier break;
8767dd7cddfSDavid du Colombier }
8777dd7cddfSDavid du Colombier if(a == AGOK)
8787dd7cddfSDavid du Colombier diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
8797dd7cddfSDavid du Colombier if(a == AMOVW || a == AMOVF || a == AMOVD)
8807dd7cddfSDavid du Colombier if(samaddr(f, t))
8817dd7cddfSDavid du Colombier return;
8827dd7cddfSDavid du Colombier gins(a, f, t);
8837dd7cddfSDavid du Colombier }
8847dd7cddfSDavid du Colombier
8857dd7cddfSDavid du Colombier void
gmover(Node * f,Node * t)886375daca8SDavid du Colombier gmover(Node *f, Node *t)
887375daca8SDavid du Colombier {
888375daca8SDavid du Colombier int ft, tt, a;
889375daca8SDavid du Colombier
890375daca8SDavid du Colombier ft = f->type->etype;
891375daca8SDavid du Colombier tt = t->type->etype;
892375daca8SDavid du Colombier a = AGOK;
893375daca8SDavid du Colombier if(typechlp[ft] && typechlp[tt] && ewidth[ft] >= ewidth[tt]){
894375daca8SDavid du Colombier switch(tt){
895375daca8SDavid du Colombier case TSHORT:
896375daca8SDavid du Colombier a = AMOVH;
897375daca8SDavid du Colombier break;
898375daca8SDavid du Colombier case TUSHORT:
899375daca8SDavid du Colombier a = AMOVHU;
900375daca8SDavid du Colombier break;
901375daca8SDavid du Colombier case TCHAR:
902375daca8SDavid du Colombier a = AMOVB;
903375daca8SDavid du Colombier break;
904375daca8SDavid du Colombier case TUCHAR:
905375daca8SDavid du Colombier a = AMOVBU;
906375daca8SDavid du Colombier break;
907375daca8SDavid du Colombier }
908375daca8SDavid du Colombier }
909375daca8SDavid du Colombier if(a == AGOK)
910375daca8SDavid du Colombier gmove(f, t);
911375daca8SDavid du Colombier else
912375daca8SDavid du Colombier gins(a, f, t);
913375daca8SDavid du Colombier }
914375daca8SDavid du Colombier
915375daca8SDavid du Colombier void
gins(int a,Node * f,Node * t)9167dd7cddfSDavid du Colombier gins(int a, Node *f, Node *t)
9177dd7cddfSDavid du Colombier {
9187dd7cddfSDavid du Colombier
9197dd7cddfSDavid du Colombier nextpc();
9207dd7cddfSDavid du Colombier p->as = a;
9217dd7cddfSDavid du Colombier if(f != Z)
9227dd7cddfSDavid du Colombier naddr(f, &p->from);
9237dd7cddfSDavid du Colombier if(t != Z)
9247dd7cddfSDavid du Colombier naddr(t, &p->to);
9257dd7cddfSDavid du Colombier if(debug['g'])
9267dd7cddfSDavid du Colombier print("%P\n", p);
9277dd7cddfSDavid du Colombier }
9287dd7cddfSDavid du Colombier
9297dd7cddfSDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)9307dd7cddfSDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
9317dd7cddfSDavid du Colombier {
932*3ec63e64SDavid du Colombier int a, et, true;
9337dd7cddfSDavid du Colombier Adr ta;
9347dd7cddfSDavid du Colombier
9357dd7cddfSDavid du Colombier et = TLONG;
9367dd7cddfSDavid du Colombier if(f1 != Z && f1->type != T)
9377dd7cddfSDavid du Colombier et = f1->type->etype;
938*3ec63e64SDavid du Colombier true = o & BTRUE;
939*3ec63e64SDavid du Colombier o &= ~BTRUE;
9407dd7cddfSDavid du Colombier a = AGOK;
9417dd7cddfSDavid du Colombier switch(o) {
9427dd7cddfSDavid du Colombier case OAS:
9437dd7cddfSDavid du Colombier gmove(f1, t);
9447dd7cddfSDavid du Colombier return;
9457dd7cddfSDavid du Colombier
9467dd7cddfSDavid du Colombier case OASADD:
9477dd7cddfSDavid du Colombier case OADD:
9487dd7cddfSDavid du Colombier a = AADD;
9497dd7cddfSDavid du Colombier if(et == TFLOAT)
9507dd7cddfSDavid du Colombier a = AADDF;
9517dd7cddfSDavid du Colombier else
9527dd7cddfSDavid du Colombier if(et == TDOUBLE || et == TVLONG)
9537dd7cddfSDavid du Colombier a = AADDD;
9547dd7cddfSDavid du Colombier break;
9557dd7cddfSDavid du Colombier
9567dd7cddfSDavid du Colombier case OASSUB:
9577dd7cddfSDavid du Colombier case OSUB:
9587dd7cddfSDavid du Colombier if(f2 && f2->op == OCONST) {
9597dd7cddfSDavid du Colombier Node *t = f1;
9607dd7cddfSDavid du Colombier f1 = f2;
9617dd7cddfSDavid du Colombier f2 = t;
9627dd7cddfSDavid du Colombier a = ARSB;
9637dd7cddfSDavid du Colombier } else
9647dd7cddfSDavid du Colombier a = ASUB;
9657dd7cddfSDavid du Colombier if(et == TFLOAT)
9667dd7cddfSDavid du Colombier a = ASUBF;
9677dd7cddfSDavid du Colombier else
9687dd7cddfSDavid du Colombier if(et == TDOUBLE || et == TVLONG)
9697dd7cddfSDavid du Colombier a = ASUBD;
9707dd7cddfSDavid du Colombier break;
9717dd7cddfSDavid du Colombier
9727dd7cddfSDavid du Colombier case OASOR:
9737dd7cddfSDavid du Colombier case OOR:
9747dd7cddfSDavid du Colombier a = AORR;
9757dd7cddfSDavid du Colombier break;
9767dd7cddfSDavid du Colombier
9777dd7cddfSDavid du Colombier case OASAND:
9787dd7cddfSDavid du Colombier case OAND:
9797dd7cddfSDavid du Colombier a = AAND;
9807dd7cddfSDavid du Colombier break;
9817dd7cddfSDavid du Colombier
9827dd7cddfSDavid du Colombier case OASXOR:
9837dd7cddfSDavid du Colombier case OXOR:
9847dd7cddfSDavid du Colombier a = AEOR;
9857dd7cddfSDavid du Colombier break;
9867dd7cddfSDavid du Colombier
9877dd7cddfSDavid du Colombier case OASLSHR:
9887dd7cddfSDavid du Colombier case OLSHR:
9897dd7cddfSDavid du Colombier a = ASRL;
9907dd7cddfSDavid du Colombier break;
9917dd7cddfSDavid du Colombier
9927dd7cddfSDavid du Colombier case OASASHR:
9937dd7cddfSDavid du Colombier case OASHR:
9947dd7cddfSDavid du Colombier a = ASRA;
9957dd7cddfSDavid du Colombier break;
9967dd7cddfSDavid du Colombier
9977dd7cddfSDavid du Colombier case OASASHL:
9987dd7cddfSDavid du Colombier case OASHL:
9997dd7cddfSDavid du Colombier a = ASLL;
10007dd7cddfSDavid du Colombier break;
10017dd7cddfSDavid du Colombier
10027dd7cddfSDavid du Colombier case OFUNC:
10037dd7cddfSDavid du Colombier a = ABL;
10047dd7cddfSDavid du Colombier break;
10057dd7cddfSDavid du Colombier
10067dd7cddfSDavid du Colombier case OASMUL:
10077dd7cddfSDavid du Colombier case OMUL:
10087dd7cddfSDavid du Colombier a = AMUL;
10097dd7cddfSDavid du Colombier if(et == TFLOAT)
10107dd7cddfSDavid du Colombier a = AMULF;
10117dd7cddfSDavid du Colombier else
10127dd7cddfSDavid du Colombier if(et == TDOUBLE || et == TVLONG)
10137dd7cddfSDavid du Colombier a = AMULD;
10147dd7cddfSDavid du Colombier break;
10157dd7cddfSDavid du Colombier
10167dd7cddfSDavid du Colombier case OASDIV:
10177dd7cddfSDavid du Colombier case ODIV:
10187dd7cddfSDavid du Colombier a = ADIV;
10197dd7cddfSDavid du Colombier if(et == TFLOAT)
10207dd7cddfSDavid du Colombier a = ADIVF;
10217dd7cddfSDavid du Colombier else
10227dd7cddfSDavid du Colombier if(et == TDOUBLE || et == TVLONG)
10237dd7cddfSDavid du Colombier a = ADIVD;
10247dd7cddfSDavid du Colombier break;
10257dd7cddfSDavid du Colombier
10267dd7cddfSDavid du Colombier case OASMOD:
10277dd7cddfSDavid du Colombier case OMOD:
10287dd7cddfSDavid du Colombier a = AMOD;
10297dd7cddfSDavid du Colombier break;
10307dd7cddfSDavid du Colombier
10317dd7cddfSDavid du Colombier case OASLMUL:
10327dd7cddfSDavid du Colombier case OLMUL:
10337dd7cddfSDavid du Colombier a = AMULU;
10347dd7cddfSDavid du Colombier break;
10357dd7cddfSDavid du Colombier
10367dd7cddfSDavid du Colombier case OASLMOD:
10377dd7cddfSDavid du Colombier case OLMOD:
10387dd7cddfSDavid du Colombier a = AMODU;
10397dd7cddfSDavid du Colombier break;
10407dd7cddfSDavid du Colombier
10417dd7cddfSDavid du Colombier case OASLDIV:
10427dd7cddfSDavid du Colombier case OLDIV:
10437dd7cddfSDavid du Colombier a = ADIVU;
10447dd7cddfSDavid du Colombier break;
10457dd7cddfSDavid du Colombier
104659cc4ca5SDavid du Colombier case OCASE:
10477dd7cddfSDavid du Colombier case OEQ:
10487dd7cddfSDavid du Colombier case ONE:
10497dd7cddfSDavid du Colombier case OLT:
10507dd7cddfSDavid du Colombier case OLE:
10517dd7cddfSDavid du Colombier case OGE:
10527dd7cddfSDavid du Colombier case OGT:
10537dd7cddfSDavid du Colombier case OLO:
10547dd7cddfSDavid du Colombier case OLS:
10557dd7cddfSDavid du Colombier case OHS:
10567dd7cddfSDavid du Colombier case OHI:
10577dd7cddfSDavid du Colombier a = ACMP;
10587dd7cddfSDavid du Colombier if(et == TFLOAT)
10597dd7cddfSDavid du Colombier a = ACMPF;
10607dd7cddfSDavid du Colombier else
10617dd7cddfSDavid du Colombier if(et == TDOUBLE || et == TVLONG)
10627dd7cddfSDavid du Colombier a = ACMPD;
10637dd7cddfSDavid du Colombier nextpc();
10647dd7cddfSDavid du Colombier p->as = a;
10657dd7cddfSDavid du Colombier naddr(f1, &p->from);
10669b7bf7dfSDavid du Colombier if(a == ACMP && f1->op == OCONST && p->from.offset < 0 &&
10679b7bf7dfSDavid du Colombier p->from.offset != 0x80000000) {
106859cc4ca5SDavid du Colombier p->as = ACMN;
106959cc4ca5SDavid du Colombier p->from.offset = -p->from.offset;
107059cc4ca5SDavid du Colombier }
10717dd7cddfSDavid du Colombier raddr(f2, p);
10727dd7cddfSDavid du Colombier switch(o) {
10737dd7cddfSDavid du Colombier case OEQ:
10747dd7cddfSDavid du Colombier a = ABEQ;
10757dd7cddfSDavid du Colombier break;
10767dd7cddfSDavid du Colombier case ONE:
10777dd7cddfSDavid du Colombier a = ABNE;
10787dd7cddfSDavid du Colombier break;
10797dd7cddfSDavid du Colombier case OLT:
10807dd7cddfSDavid du Colombier a = ABLT;
1081*3ec63e64SDavid du Colombier /* ensure NaN comparison is always false */
1082*3ec63e64SDavid du Colombier if(typefd[et] && !true)
1083*3ec63e64SDavid du Colombier a = ABMI;
10847dd7cddfSDavid du Colombier break;
10857dd7cddfSDavid du Colombier case OLE:
10867dd7cddfSDavid du Colombier a = ABLE;
1087*3ec63e64SDavid du Colombier if(typefd[et] && !true)
1088*3ec63e64SDavid du Colombier a = ABLS;
10897dd7cddfSDavid du Colombier break;
10907dd7cddfSDavid du Colombier case OGE:
10917dd7cddfSDavid du Colombier a = ABGE;
1092*3ec63e64SDavid du Colombier if(typefd[et] && true)
1093*3ec63e64SDavid du Colombier a = ABPL;
10947dd7cddfSDavid du Colombier break;
10957dd7cddfSDavid du Colombier case OGT:
10967dd7cddfSDavid du Colombier a = ABGT;
1097*3ec63e64SDavid du Colombier if(typefd[et] && true)
1098*3ec63e64SDavid du Colombier a = ABHI;
10997dd7cddfSDavid du Colombier break;
11007dd7cddfSDavid du Colombier case OLO:
11017dd7cddfSDavid du Colombier a = ABLO;
11027dd7cddfSDavid du Colombier break;
11037dd7cddfSDavid du Colombier case OLS:
11047dd7cddfSDavid du Colombier a = ABLS;
11057dd7cddfSDavid du Colombier break;
11067dd7cddfSDavid du Colombier case OHS:
11077dd7cddfSDavid du Colombier a = ABHS;
11087dd7cddfSDavid du Colombier break;
11097dd7cddfSDavid du Colombier case OHI:
11107dd7cddfSDavid du Colombier a = ABHI;
11117dd7cddfSDavid du Colombier break;
111259cc4ca5SDavid du Colombier case OCASE:
111359cc4ca5SDavid du Colombier nextpc();
111459cc4ca5SDavid du Colombier p->as = ACASE;
111559cc4ca5SDavid du Colombier p->scond = 0x9;
111659cc4ca5SDavid du Colombier naddr(f2, &p->from);
111759cc4ca5SDavid du Colombier a = ABHI;
111859cc4ca5SDavid du Colombier break;
11197dd7cddfSDavid du Colombier }
11207dd7cddfSDavid du Colombier f1 = Z;
11217dd7cddfSDavid du Colombier f2 = Z;
11227dd7cddfSDavid du Colombier break;
11237dd7cddfSDavid du Colombier }
11247dd7cddfSDavid du Colombier if(a == AGOK)
11257dd7cddfSDavid du Colombier diag(Z, "bad in gopcode %O", o);
11267dd7cddfSDavid du Colombier nextpc();
11277dd7cddfSDavid du Colombier p->as = a;
11287dd7cddfSDavid du Colombier if(f1 != Z)
11297dd7cddfSDavid du Colombier naddr(f1, &p->from);
11307dd7cddfSDavid du Colombier if(f2 != Z) {
11317dd7cddfSDavid du Colombier naddr(f2, &ta);
11327dd7cddfSDavid du Colombier p->reg = ta.reg;
11337dd7cddfSDavid du Colombier }
11347dd7cddfSDavid du Colombier if(t != Z)
11357dd7cddfSDavid du Colombier naddr(t, &p->to);
11367dd7cddfSDavid du Colombier if(debug['g'])
11377dd7cddfSDavid du Colombier print("%P\n", p);
11387dd7cddfSDavid du Colombier }
11397dd7cddfSDavid du Colombier
samaddr(Node * f,Node * t)11407dd7cddfSDavid du Colombier samaddr(Node *f, Node *t)
11417dd7cddfSDavid du Colombier {
11427dd7cddfSDavid du Colombier
11437dd7cddfSDavid du Colombier if(f->op != t->op)
11447dd7cddfSDavid du Colombier return 0;
11457dd7cddfSDavid du Colombier switch(f->op) {
11467dd7cddfSDavid du Colombier
11477dd7cddfSDavid du Colombier case OREGISTER:
11487dd7cddfSDavid du Colombier if(f->reg != t->reg)
11497dd7cddfSDavid du Colombier break;
11507dd7cddfSDavid du Colombier return 1;
11517dd7cddfSDavid du Colombier }
11527dd7cddfSDavid du Colombier return 0;
11537dd7cddfSDavid du Colombier }
11547dd7cddfSDavid du Colombier
11557dd7cddfSDavid du Colombier void
gbranch(int o)11567dd7cddfSDavid du Colombier gbranch(int o)
11577dd7cddfSDavid du Colombier {
11587dd7cddfSDavid du Colombier int a;
11597dd7cddfSDavid du Colombier
11607dd7cddfSDavid du Colombier a = AGOK;
11617dd7cddfSDavid du Colombier switch(o) {
11627dd7cddfSDavid du Colombier case ORETURN:
11637dd7cddfSDavid du Colombier a = ARET;
11647dd7cddfSDavid du Colombier break;
11657dd7cddfSDavid du Colombier case OGOTO:
11667dd7cddfSDavid du Colombier a = AB;
11677dd7cddfSDavid du Colombier break;
11687dd7cddfSDavid du Colombier }
11697dd7cddfSDavid du Colombier nextpc();
11707dd7cddfSDavid du Colombier if(a == AGOK) {
11717dd7cddfSDavid du Colombier diag(Z, "bad in gbranch %O", o);
11727dd7cddfSDavid du Colombier nextpc();
11737dd7cddfSDavid du Colombier }
11747dd7cddfSDavid du Colombier p->as = a;
11757dd7cddfSDavid du Colombier }
11767dd7cddfSDavid du Colombier
11777dd7cddfSDavid du Colombier void
patch(Prog * op,long pc)11787dd7cddfSDavid du Colombier patch(Prog *op, long pc)
11797dd7cddfSDavid du Colombier {
11807dd7cddfSDavid du Colombier
11817dd7cddfSDavid du Colombier op->to.offset = pc;
11827dd7cddfSDavid du Colombier op->to.type = D_BRANCH;
11837dd7cddfSDavid du Colombier }
11847dd7cddfSDavid du Colombier
11857dd7cddfSDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)11867dd7cddfSDavid du Colombier gpseudo(int a, Sym *s, Node *n)
11877dd7cddfSDavid du Colombier {
11887dd7cddfSDavid du Colombier
11897dd7cddfSDavid du Colombier nextpc();
11907dd7cddfSDavid du Colombier p->as = a;
11917dd7cddfSDavid du Colombier p->from.type = D_OREG;
11927dd7cddfSDavid du Colombier p->from.sym = s;
11937dd7cddfSDavid du Colombier p->from.name = D_EXTERN;
11945ede6b93SDavid du Colombier if(a == ATEXT)
1195e288d156SDavid du Colombier p->reg = (profileflg ? 0 : NOPROF);
11967dd7cddfSDavid du Colombier if(s->class == CSTATIC)
11977dd7cddfSDavid du Colombier p->from.name = D_STATIC;
11987dd7cddfSDavid du Colombier naddr(n, &p->to);
11997dd7cddfSDavid du Colombier if(a == ADATA || a == AGLOBL)
12007dd7cddfSDavid du Colombier pc--;
12017dd7cddfSDavid du Colombier }
12027dd7cddfSDavid du Colombier
12037dd7cddfSDavid du Colombier int
sconst(Node * n)12047dd7cddfSDavid du Colombier sconst(Node *n)
12057dd7cddfSDavid du Colombier {
12067dd7cddfSDavid du Colombier vlong vv;
12077dd7cddfSDavid du Colombier
12087dd7cddfSDavid du Colombier if(n->op == OCONST) {
12097dd7cddfSDavid du Colombier if(!typefd[n->type->etype]) {
12107dd7cddfSDavid du Colombier vv = n->vconst;
121159cc4ca5SDavid du Colombier if(vv >= (vlong)(-32766) && vv < (vlong)32766)
121259cc4ca5SDavid du Colombier return 1;
121359cc4ca5SDavid du Colombier /*
121459cc4ca5SDavid du Colombier * should be specialised for constant values which will
121559cc4ca5SDavid du Colombier * fit in different instructionsl; for now, let 5l
121659cc4ca5SDavid du Colombier * sort it out
121759cc4ca5SDavid du Colombier */
12187dd7cddfSDavid du Colombier return 1;
12197dd7cddfSDavid du Colombier }
12207dd7cddfSDavid du Colombier }
12217dd7cddfSDavid du Colombier return 0;
12227dd7cddfSDavid du Colombier }
12237dd7cddfSDavid du Colombier
12247dd7cddfSDavid du Colombier int
sval(long v)12257dd7cddfSDavid du Colombier sval(long v)
12267dd7cddfSDavid du Colombier {
122759cc4ca5SDavid du Colombier int i;
122859cc4ca5SDavid du Colombier
122959cc4ca5SDavid du Colombier for(i=0; i<16; i++) {
123059cc4ca5SDavid du Colombier if((v & ~0xff) == 0)
12317dd7cddfSDavid du Colombier return 1;
123259cc4ca5SDavid du Colombier if((~v & ~0xff) == 0)
123359cc4ca5SDavid du Colombier return 1;
123459cc4ca5SDavid du Colombier v = (v<<2) | ((ulong)v>>30);
123559cc4ca5SDavid du Colombier }
12367dd7cddfSDavid du Colombier return 0;
12377dd7cddfSDavid du Colombier }
12387dd7cddfSDavid du Colombier
12397dd7cddfSDavid du Colombier long
exreg(Type * t)12407dd7cddfSDavid du Colombier exreg(Type *t)
12417dd7cddfSDavid du Colombier {
12427dd7cddfSDavid du Colombier long o;
12437dd7cddfSDavid du Colombier
12447dd7cddfSDavid du Colombier if(typechlp[t->etype]) {
124551480713SDavid du Colombier if(exregoffset <= REGEXT-2)
12467dd7cddfSDavid du Colombier return 0;
12477dd7cddfSDavid du Colombier o = exregoffset;
124851480713SDavid du Colombier if(reg[o] && !resvreg[o])
124951480713SDavid du Colombier return 0;
125051480713SDavid du Colombier resvreg[o] = reg[o] = 1;
12517dd7cddfSDavid du Colombier exregoffset--;
12527dd7cddfSDavid du Colombier return o;
12537dd7cddfSDavid du Colombier }
12547dd7cddfSDavid du Colombier if(typefd[t->etype]) {
12557dd7cddfSDavid du Colombier if(exfregoffset <= NFREG-1)
12567dd7cddfSDavid du Colombier return 0;
12577dd7cddfSDavid du Colombier o = exfregoffset + NREG;
125851480713SDavid du Colombier if(reg[o] && !resvreg[o])
125951480713SDavid du Colombier return 0;
126051480713SDavid du Colombier resvreg[o] = reg[o] = 1;
12617dd7cddfSDavid du Colombier exfregoffset--;
12627dd7cddfSDavid du Colombier return o;
12637dd7cddfSDavid du Colombier }
12647dd7cddfSDavid du Colombier return 0;
12657dd7cddfSDavid du Colombier }
12667dd7cddfSDavid du Colombier
12677dd7cddfSDavid du Colombier schar ewidth[NTYPE] =
12687dd7cddfSDavid du Colombier {
12697dd7cddfSDavid du Colombier -1, /* [TXXX] */
12707dd7cddfSDavid du Colombier SZ_CHAR, /* [TCHAR] */
12717dd7cddfSDavid du Colombier SZ_CHAR, /* [TUCHAR] */
12727dd7cddfSDavid du Colombier SZ_SHORT, /* [TSHORT] */
12737dd7cddfSDavid du Colombier SZ_SHORT, /* [TUSHORT] */
12747dd7cddfSDavid du Colombier SZ_INT, /* [TINT] */
12757dd7cddfSDavid du Colombier SZ_INT, /* [TUINT] */
12767dd7cddfSDavid du Colombier SZ_LONG, /* [TLONG] */
12777dd7cddfSDavid du Colombier SZ_LONG, /* [TULONG] */
12787dd7cddfSDavid du Colombier SZ_VLONG, /* [TVLONG] */
12797dd7cddfSDavid du Colombier SZ_VLONG, /* [TUVLONG] */
12807dd7cddfSDavid du Colombier SZ_FLOAT, /* [TFLOAT] */
12817dd7cddfSDavid du Colombier SZ_DOUBLE, /* [TDOUBLE] */
12827dd7cddfSDavid du Colombier SZ_IND, /* [TIND] */
12837dd7cddfSDavid du Colombier 0, /* [TFUNC] */
12847dd7cddfSDavid du Colombier -1, /* [TARRAY] */
12857dd7cddfSDavid du Colombier 0, /* [TVOID] */
12867dd7cddfSDavid du Colombier -1, /* [TSTRUCT] */
12877dd7cddfSDavid du Colombier -1, /* [TUNION] */
12887dd7cddfSDavid du Colombier SZ_INT, /* [TENUM] */
12897dd7cddfSDavid du Colombier };
12907dd7cddfSDavid du Colombier
12917dd7cddfSDavid du Colombier long ncast[NTYPE] =
12927dd7cddfSDavid du Colombier {
12937dd7cddfSDavid du Colombier 0, /* [TXXX] */
12947dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TCHAR] */
12957dd7cddfSDavid du Colombier BCHAR|BUCHAR, /* [TUCHAR] */
12967dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TSHORT] */
12977dd7cddfSDavid du Colombier BSHORT|BUSHORT, /* [TUSHORT] */
12987dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
12997dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
13007dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
13017dd7cddfSDavid du Colombier BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
13027dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TVLONG] */
13037dd7cddfSDavid du Colombier BVLONG|BUVLONG, /* [TUVLONG] */
13047dd7cddfSDavid du Colombier BFLOAT, /* [TFLOAT] */
13057dd7cddfSDavid du Colombier BDOUBLE, /* [TDOUBLE] */
13067dd7cddfSDavid du Colombier BLONG|BULONG|BIND, /* [TIND] */
13077dd7cddfSDavid du Colombier 0, /* [TFUNC] */
13087dd7cddfSDavid du Colombier 0, /* [TARRAY] */
13097dd7cddfSDavid du Colombier 0, /* [TVOID] */
13107dd7cddfSDavid du Colombier BSTRUCT, /* [TSTRUCT] */
13117dd7cddfSDavid du Colombier BUNION, /* [TUNION] */
13127dd7cddfSDavid du Colombier 0, /* [TENUM] */
13137dd7cddfSDavid du Colombier };
1314