13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier void 43e12c5d1SDavid du Colombier ginit(void) 53e12c5d1SDavid du Colombier { 63e12c5d1SDavid du Colombier int i; 73e12c5d1SDavid du Colombier Type *t; 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier thechar = 'v'; 103e12c5d1SDavid du Colombier thestring = "mips"; 113e12c5d1SDavid du Colombier exregoffset = REGEXT; 123e12c5d1SDavid du Colombier exfregoffset = FREGEXT; 133e12c5d1SDavid du Colombier listinit(); 143e12c5d1SDavid du Colombier nstring = 0; 153e12c5d1SDavid du Colombier mnstring = 0; 163e12c5d1SDavid du Colombier nrathole = 0; 173e12c5d1SDavid du Colombier pc = 0; 183e12c5d1SDavid du Colombier breakpc = -1; 193e12c5d1SDavid du Colombier continpc = -1; 203e12c5d1SDavid du Colombier cases = C; 213e12c5d1SDavid du Colombier firstp = P; 223e12c5d1SDavid du Colombier lastp = P; 233e12c5d1SDavid du Colombier tfield = types[TFIELD]; 243e12c5d1SDavid du Colombier if(TINT == TSHORT) { 253e12c5d1SDavid du Colombier tint = types[TSHORT]; 263e12c5d1SDavid du Colombier tuint = types[TUSHORT]; 273e12c5d1SDavid du Colombier types[TFUNC]->link = tint; 283e12c5d1SDavid du Colombier } 293e12c5d1SDavid du Colombier ewidth[TENUM] = ewidth[TINT]; 303e12c5d1SDavid du Colombier types[TENUM]->width = ewidth[TENUM]; 313e12c5d1SDavid du Colombier suround = SU_ALLIGN; 323e12c5d1SDavid du Colombier supad = SU_PAD; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier zprog.link = P; 353e12c5d1SDavid du Colombier zprog.as = AGOK; 363e12c5d1SDavid du Colombier zprog.reg = NREG; 373e12c5d1SDavid du Colombier zprog.from.type = D_NONE; 383e12c5d1SDavid du Colombier zprog.from.name = D_NONE; 393e12c5d1SDavid du Colombier zprog.from.reg = NREG; 403e12c5d1SDavid du Colombier zprog.to = zprog.from; 413e12c5d1SDavid du Colombier 423e12c5d1SDavid du Colombier regnode.op = OREGISTER; 433e12c5d1SDavid du Colombier regnode.class = CEXREG; 443e12c5d1SDavid du Colombier regnode.reg = REGTMP; 453e12c5d1SDavid du Colombier regnode.complex = 0; 463e12c5d1SDavid du Colombier regnode.addable = 11; 473e12c5d1SDavid du Colombier regnode.type = types[TLONG]; 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier constnode.op = OCONST; 503e12c5d1SDavid du Colombier constnode.class = CXXX; 513e12c5d1SDavid du Colombier constnode.complex = 0; 523e12c5d1SDavid du Colombier constnode.addable = 20; 533e12c5d1SDavid du Colombier constnode.type = types[TLONG]; 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier fconstnode.op = OCONST; 563e12c5d1SDavid du Colombier fconstnode.class = CXXX; 573e12c5d1SDavid du Colombier fconstnode.complex = 0; 583e12c5d1SDavid du Colombier fconstnode.addable = 20; 593e12c5d1SDavid du Colombier fconstnode.type = types[TDOUBLE]; 603e12c5d1SDavid du Colombier 613e12c5d1SDavid du Colombier nodsafe = new(ONAME, Z, Z); 623e12c5d1SDavid du Colombier nodsafe->sym = slookup(".safe"); 633e12c5d1SDavid du Colombier nodsafe->type = tint; 643e12c5d1SDavid du Colombier nodsafe->etype = tint->etype; 653e12c5d1SDavid du Colombier nodsafe->class = CAUTO; 663e12c5d1SDavid du Colombier complex(nodsafe); 673e12c5d1SDavid du Colombier 683e12c5d1SDavid du Colombier t = typ(TARRAY, types[TCHAR]); 693e12c5d1SDavid du Colombier symrathole = slookup(".rathole"); 703e12c5d1SDavid du Colombier symrathole->class = CGLOBL; 713e12c5d1SDavid du Colombier symrathole->type = t; 723e12c5d1SDavid du Colombier 733e12c5d1SDavid du Colombier nodrat = new(ONAME, Z, Z); 743e12c5d1SDavid du Colombier nodrat->sym = symrathole; 753e12c5d1SDavid du Colombier nodrat->type = types[TIND]; 763e12c5d1SDavid du Colombier nodrat->etype = TVOID; 773e12c5d1SDavid du Colombier nodrat->class = CGLOBL; 783e12c5d1SDavid du Colombier complex(nodrat); 793e12c5d1SDavid du Colombier nodrat->type = t; 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier nodret = new(ONAME, Z, Z); 823e12c5d1SDavid du Colombier nodret->sym = slookup(".ret"); 833e12c5d1SDavid du Colombier nodret->type = types[TIND]; 843e12c5d1SDavid du Colombier nodret->etype = TIND; 853e12c5d1SDavid du Colombier nodret->class = CPARAM; 863e12c5d1SDavid du Colombier nodret = new(OIND, nodret, Z); 873e12c5d1SDavid du Colombier complex(nodret); 883e12c5d1SDavid du Colombier 89*219b2ee8SDavid du Colombier com64init(); 90*219b2ee8SDavid du Colombier 913e12c5d1SDavid du Colombier memset(reg, 0, sizeof(reg)); 923e12c5d1SDavid du Colombier for(i=NREG; i<NREG+NREG; i+=2) 933e12c5d1SDavid du Colombier reg[i+1] = 1; 943e12c5d1SDavid du Colombier reg[REGZERO] = 1; 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier void 983e12c5d1SDavid du Colombier gclean(void) 993e12c5d1SDavid du Colombier { 1003e12c5d1SDavid du Colombier int i; 1013e12c5d1SDavid du Colombier Sym *s; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier for(i=0; i<NREG; i++) 1043e12c5d1SDavid du Colombier if(i != REGZERO) 1053e12c5d1SDavid du Colombier if(reg[i]) 1063e12c5d1SDavid du Colombier diag(Z, "reg %d left allocated", i); 1073e12c5d1SDavid du Colombier for(i=NREG; i<NREG+NREG; i+=2) 1083e12c5d1SDavid du Colombier if(reg[i]) 1093e12c5d1SDavid du Colombier diag(Z, "freg %d left allocated", i-NREG); 1103e12c5d1SDavid du Colombier while(mnstring) 1113e12c5d1SDavid du Colombier outstring("", 1L); 1123e12c5d1SDavid du Colombier symstring->type->width = nstring; 1133e12c5d1SDavid du Colombier symrathole->type->width = nrathole; 1143e12c5d1SDavid du Colombier for(i=0; i<NHASH; i++) 1153e12c5d1SDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 1163e12c5d1SDavid du Colombier if(s->type == T) 1173e12c5d1SDavid du Colombier continue; 1183e12c5d1SDavid du Colombier if(s->type->width == 0) 1193e12c5d1SDavid du Colombier continue; 1203e12c5d1SDavid du Colombier if(s->class != CGLOBL && s->class != CSTATIC) 1213e12c5d1SDavid du Colombier continue; 1223e12c5d1SDavid du Colombier if(s->type == types[TENUM]) 1233e12c5d1SDavid du Colombier continue; 1243e12c5d1SDavid du Colombier gpseudo(AGLOBL, s, nodconst(s->type->width)); 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier nextpc(); 1273e12c5d1SDavid du Colombier p->as = AEND; 1283e12c5d1SDavid du Colombier outcode(); 1293e12c5d1SDavid du Colombier } 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier void 1323e12c5d1SDavid du Colombier nextpc(void) 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier 1353e12c5d1SDavid du Colombier ALLOC(p, Prog); 1363e12c5d1SDavid du Colombier *p = zprog; 1373e12c5d1SDavid du Colombier p->lineno = nearln; 1383e12c5d1SDavid du Colombier pc++; 1393e12c5d1SDavid du Colombier if(firstp == P) { 1403e12c5d1SDavid du Colombier firstp = p; 1413e12c5d1SDavid du Colombier lastp = p; 1423e12c5d1SDavid du Colombier return; 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier lastp->link = p; 1453e12c5d1SDavid du Colombier lastp = p; 1463e12c5d1SDavid du Colombier } 1473e12c5d1SDavid du Colombier 1483e12c5d1SDavid du Colombier void 1493e12c5d1SDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2) 1503e12c5d1SDavid du Colombier { 1513e12c5d1SDavid du Colombier long regs; 1523e12c5d1SDavid du Colombier Node fnxargs[20], *fnxp; 1533e12c5d1SDavid du Colombier 1543e12c5d1SDavid du Colombier regs = cursafe; 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier fnxp = fnxargs; 1573e12c5d1SDavid du Colombier garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */ 1583e12c5d1SDavid du Colombier 1593e12c5d1SDavid du Colombier curarg = 0; 1603e12c5d1SDavid du Colombier fnxp = fnxargs; 1613e12c5d1SDavid du Colombier garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */ 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier cursafe = regs; 1643e12c5d1SDavid du Colombier } 1653e12c5d1SDavid du Colombier 1663e12c5d1SDavid du Colombier void 1673e12c5d1SDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) 1683e12c5d1SDavid du Colombier { 1693e12c5d1SDavid du Colombier Node nod; 1703e12c5d1SDavid du Colombier 1713e12c5d1SDavid du Colombier if(n == Z) 1723e12c5d1SDavid du Colombier return; 1733e12c5d1SDavid du Colombier if(n->op == OLIST) { 1743e12c5d1SDavid du Colombier garg1(n->left, tn1, tn2, f, fnxp); 1753e12c5d1SDavid du Colombier garg1(n->right, tn1, tn2, f, fnxp); 1763e12c5d1SDavid du Colombier return; 1773e12c5d1SDavid du Colombier } 1783e12c5d1SDavid du Colombier if(f == 0) { 1793e12c5d1SDavid du Colombier if(n->complex >= FNX) { 1803e12c5d1SDavid du Colombier regsalloc(*fnxp, n); 1813e12c5d1SDavid du Colombier nod = znode; 1823e12c5d1SDavid du Colombier nod.op = OAS; 1833e12c5d1SDavid du Colombier nod.left = *fnxp; 1843e12c5d1SDavid du Colombier nod.right = n; 1853e12c5d1SDavid du Colombier nod.type = n->type; 1863e12c5d1SDavid du Colombier cgen(&nod, Z); 1873e12c5d1SDavid du Colombier (*fnxp)++; 1883e12c5d1SDavid du Colombier } 1893e12c5d1SDavid du Colombier return; 1903e12c5d1SDavid du Colombier } 191*219b2ee8SDavid du Colombier if(typesuv[n->type->etype]) { 1923e12c5d1SDavid du Colombier regaalloc(tn2, n); 1933e12c5d1SDavid du Colombier if(n->complex >= FNX) { 1943e12c5d1SDavid du Colombier sugen(*fnxp, tn2, n->type->width); 1953e12c5d1SDavid du Colombier (*fnxp)++; 1963e12c5d1SDavid du Colombier } else 1973e12c5d1SDavid du Colombier sugen(n, tn2, n->type->width); 1983e12c5d1SDavid du Colombier return; 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier if(REGARG && curarg == 0 && typechlp[n->type->etype]) { 2013e12c5d1SDavid du Colombier regaalloc1(tn1, n); 2023e12c5d1SDavid du Colombier if(n->complex >= FNX) { 2033e12c5d1SDavid du Colombier cgen(*fnxp, tn1); 2043e12c5d1SDavid du Colombier (*fnxp)++; 2053e12c5d1SDavid du Colombier } else 2063e12c5d1SDavid du Colombier cgen(n, tn1); 2073e12c5d1SDavid du Colombier return; 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier if(vconst(n) == 0) { 2103e12c5d1SDavid du Colombier regaalloc(tn2, n); 2113e12c5d1SDavid du Colombier gopcode(OAS, n, Z, tn2); 2123e12c5d1SDavid du Colombier return; 2133e12c5d1SDavid du Colombier } 2143e12c5d1SDavid du Colombier regalloc(tn1, n, Z); 2153e12c5d1SDavid du Colombier if(n->complex >= FNX) { 2163e12c5d1SDavid du Colombier cgen(*fnxp, tn1); 2173e12c5d1SDavid du Colombier (*fnxp)++; 2183e12c5d1SDavid du Colombier } else 2193e12c5d1SDavid du Colombier cgen(n, tn1); 2203e12c5d1SDavid du Colombier regaalloc(tn2, n); 2213e12c5d1SDavid du Colombier gopcode(OAS, tn1, Z, tn2); 2223e12c5d1SDavid du Colombier regfree(tn1); 2233e12c5d1SDavid du Colombier } 2243e12c5d1SDavid du Colombier 2253e12c5d1SDavid du Colombier Node* 2263e12c5d1SDavid du Colombier nodconst(long v) 2273e12c5d1SDavid du Colombier { 228*219b2ee8SDavid du Colombier constnode.vconst = v; 229*219b2ee8SDavid du Colombier return &constnode; 230*219b2ee8SDavid du Colombier } 231*219b2ee8SDavid du Colombier 232*219b2ee8SDavid du Colombier Node* 233*219b2ee8SDavid du Colombier nod32const(vlong v) 234*219b2ee8SDavid du Colombier { 235*219b2ee8SDavid du Colombier constnode.vconst = v & MASK(32); 2363e12c5d1SDavid du Colombier return &constnode; 2373e12c5d1SDavid du Colombier } 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier Node* 240bd389b36SDavid du Colombier nodfconst(double d) 2413e12c5d1SDavid du Colombier { 242*219b2ee8SDavid du Colombier fconstnode.fconst = d; 2433e12c5d1SDavid du Colombier return &fconstnode; 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier void 2473e12c5d1SDavid du Colombier nodreg(Node *n, Node *nn, int reg) 2483e12c5d1SDavid du Colombier { 2493e12c5d1SDavid du Colombier *n = regnode; 2503e12c5d1SDavid du Colombier n->reg = reg; 2513e12c5d1SDavid du Colombier n->type = nn->type; 2523e12c5d1SDavid du Colombier n->lineno = nn->lineno; 2533e12c5d1SDavid du Colombier } 2543e12c5d1SDavid du Colombier 2553e12c5d1SDavid du Colombier void 2563e12c5d1SDavid du Colombier regret(Node *n, Node *nn) 2573e12c5d1SDavid du Colombier { 2583e12c5d1SDavid du Colombier int r; 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier r = REGRET; 261*219b2ee8SDavid du Colombier if(typefd[nn->type->etype]) 2623e12c5d1SDavid du Colombier r = FREGRET+NREG; 2633e12c5d1SDavid du Colombier nodreg(n, nn, r); 2643e12c5d1SDavid du Colombier reg[r]++; 2653e12c5d1SDavid du Colombier } 2663e12c5d1SDavid du Colombier 2673e12c5d1SDavid du Colombier tmpreg(void) 2683e12c5d1SDavid du Colombier { 2693e12c5d1SDavid du Colombier int i; 2703e12c5d1SDavid du Colombier 2713e12c5d1SDavid du Colombier for(i=REGRET+1; i<NREG; i++) 2723e12c5d1SDavid du Colombier if(reg[i] == 0) 2733e12c5d1SDavid du Colombier return i; 2743e12c5d1SDavid du Colombier diag(Z, "out of fixed registers"); 2753e12c5d1SDavid du Colombier return 0; 2763e12c5d1SDavid du Colombier } 2773e12c5d1SDavid du Colombier 2783e12c5d1SDavid du Colombier void 2793e12c5d1SDavid du Colombier regalloc(Node *n, Node *tn, Node *o) 2803e12c5d1SDavid du Colombier { 2813e12c5d1SDavid du Colombier int i, j; 2823e12c5d1SDavid du Colombier static lasti; 2833e12c5d1SDavid du Colombier 2843e12c5d1SDavid du Colombier switch(tn->type->etype) { 2853e12c5d1SDavid du Colombier case TCHAR: 2863e12c5d1SDavid du Colombier case TUCHAR: 2873e12c5d1SDavid du Colombier case TSHORT: 2883e12c5d1SDavid du Colombier case TUSHORT: 2893e12c5d1SDavid du Colombier case TLONG: 2903e12c5d1SDavid du Colombier case TULONG: 2913e12c5d1SDavid du Colombier case TIND: 2923e12c5d1SDavid du Colombier if(o != Z && o->op == OREGISTER) { 2933e12c5d1SDavid du Colombier i = o->reg; 2943e12c5d1SDavid du Colombier if(i > 0 && i < NREG) 2953e12c5d1SDavid du Colombier goto out; 2963e12c5d1SDavid du Colombier } 2973e12c5d1SDavid du Colombier j = lasti + REGRET+1; 2983e12c5d1SDavid du Colombier for(i=REGRET+1; i<NREG; i++) { 2993e12c5d1SDavid du Colombier if(j >= NREG) 3003e12c5d1SDavid du Colombier j = REGRET+1; 3013e12c5d1SDavid du Colombier if(reg[j] == 0) { 3023e12c5d1SDavid du Colombier i = j; 3033e12c5d1SDavid du Colombier goto out; 3043e12c5d1SDavid du Colombier } 3053e12c5d1SDavid du Colombier j++; 3063e12c5d1SDavid du Colombier } 3073e12c5d1SDavid du Colombier diag(tn, "out of fixed registers"); 3083e12c5d1SDavid du Colombier goto err; 3093e12c5d1SDavid du Colombier 3103e12c5d1SDavid du Colombier case TFLOAT: 3113e12c5d1SDavid du Colombier case TDOUBLE: 3123e12c5d1SDavid du Colombier case TVLONG: 3133e12c5d1SDavid du Colombier if(o != Z && o->op == OREGISTER) { 3143e12c5d1SDavid du Colombier i = o->reg; 3153e12c5d1SDavid du Colombier if(i >= NREG && i < NREG+NREG) 3163e12c5d1SDavid du Colombier goto out; 3173e12c5d1SDavid du Colombier } 318*219b2ee8SDavid du Colombier j = 0*2 + NREG; 3193e12c5d1SDavid du Colombier for(i=NREG; i<NREG+NREG; i+=2) { 3203e12c5d1SDavid du Colombier if(j >= NREG+NREG) 3213e12c5d1SDavid du Colombier j = NREG; 3223e12c5d1SDavid du Colombier if(reg[j] == 0) { 3233e12c5d1SDavid du Colombier i = j; 3243e12c5d1SDavid du Colombier goto out; 3253e12c5d1SDavid du Colombier } 3263e12c5d1SDavid du Colombier j += 2; 3273e12c5d1SDavid du Colombier } 3283e12c5d1SDavid du Colombier diag(tn, "out of float registers"); 3293e12c5d1SDavid du Colombier goto err; 3303e12c5d1SDavid du Colombier } 3313e12c5d1SDavid du Colombier diag(tn, "unknown type in regalloc: %T", tn->type); 3323e12c5d1SDavid du Colombier err: 3333e12c5d1SDavid du Colombier i = 0; 3343e12c5d1SDavid du Colombier out: 3353e12c5d1SDavid du Colombier if(i) 3363e12c5d1SDavid du Colombier reg[i]++; 3373e12c5d1SDavid du Colombier lasti++; 3383e12c5d1SDavid du Colombier if(lasti >= 5) 3393e12c5d1SDavid du Colombier lasti = 0; 3403e12c5d1SDavid du Colombier nodreg(n, tn, i); 3413e12c5d1SDavid du Colombier } 3423e12c5d1SDavid du Colombier 3433e12c5d1SDavid du Colombier void 3443e12c5d1SDavid du Colombier regialloc(Node *n, Node *tn, Node *o) 3453e12c5d1SDavid du Colombier { 3463e12c5d1SDavid du Colombier Node nod; 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier nod = *tn; 3493e12c5d1SDavid du Colombier nod.type = types[TIND]; 3503e12c5d1SDavid du Colombier regalloc(n, &nod, o); 3513e12c5d1SDavid du Colombier } 3523e12c5d1SDavid du Colombier 3533e12c5d1SDavid du Colombier void 3543e12c5d1SDavid du Colombier regfree(Node *n) 3553e12c5d1SDavid du Colombier { 3563e12c5d1SDavid du Colombier int i; 3573e12c5d1SDavid du Colombier 3583e12c5d1SDavid du Colombier i = 0; 3593e12c5d1SDavid du Colombier if(n->op != OREGISTER && n->op != OINDREG) 3603e12c5d1SDavid du Colombier goto err; 3613e12c5d1SDavid du Colombier i = n->reg; 3623e12c5d1SDavid du Colombier if(i < 0 || i >= sizeof(reg)) 3633e12c5d1SDavid du Colombier goto err; 3643e12c5d1SDavid du Colombier if(reg[i] <= 0) 3653e12c5d1SDavid du Colombier goto err; 3663e12c5d1SDavid du Colombier reg[i]--; 3673e12c5d1SDavid du Colombier return; 3683e12c5d1SDavid du Colombier err: 3693e12c5d1SDavid du Colombier diag(n, "error in regfree: %d", i); 3703e12c5d1SDavid du Colombier } 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier void 3733e12c5d1SDavid du Colombier regsalloc(Node *n, Node *nn) 3743e12c5d1SDavid du Colombier { 3753e12c5d1SDavid du Colombier long o; 3763e12c5d1SDavid du Colombier 3773e12c5d1SDavid du Colombier o = nn->type->width; 3783e12c5d1SDavid du Colombier o += round(o, tint->width); 3793e12c5d1SDavid du Colombier cursafe += o; 3803e12c5d1SDavid du Colombier if(cursafe+curarg > maxargsafe) 3813e12c5d1SDavid du Colombier maxargsafe = cursafe+curarg; 3823e12c5d1SDavid du Colombier *n = *nodsafe; 383*219b2ee8SDavid du Colombier n->xoffset = -(stkoff + cursafe); 3843e12c5d1SDavid du Colombier n->type = nn->type; 3853e12c5d1SDavid du Colombier n->etype = nn->type->etype; 3863e12c5d1SDavid du Colombier n->lineno = nn->lineno; 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier 3893e12c5d1SDavid du Colombier void 3903e12c5d1SDavid du Colombier regaalloc1(Node *n, Node *nn) 3913e12c5d1SDavid du Colombier { 3923e12c5d1SDavid du Colombier int r; 3933e12c5d1SDavid du Colombier 3943e12c5d1SDavid du Colombier r = REGARG; 3953e12c5d1SDavid du Colombier nodreg(n, nn, r); 3963e12c5d1SDavid du Colombier reg[r]++; 3973e12c5d1SDavid du Colombier curarg += 4; 3983e12c5d1SDavid du Colombier if(cursafe+curarg > maxargsafe) 3993e12c5d1SDavid du Colombier maxargsafe = cursafe+curarg; 4003e12c5d1SDavid du Colombier } 4013e12c5d1SDavid du Colombier 4023e12c5d1SDavid du Colombier void 4033e12c5d1SDavid du Colombier regaalloc(Node *n, Node *nn) 4043e12c5d1SDavid du Colombier { 4053e12c5d1SDavid du Colombier long o; 4063e12c5d1SDavid du Colombier 4073e12c5d1SDavid du Colombier *n = *nn; 4083e12c5d1SDavid du Colombier n->op = OINDREG; 4093e12c5d1SDavid du Colombier n->reg = REGSP; 410*219b2ee8SDavid du Colombier n->xoffset = curarg + 4; 4113e12c5d1SDavid du Colombier n->complex = 0; 4123e12c5d1SDavid du Colombier n->addable = 20; 4133e12c5d1SDavid du Colombier o = nn->type->width; 4143e12c5d1SDavid du Colombier o += round(o, tint->width); 4153e12c5d1SDavid du Colombier curarg += o; 4163e12c5d1SDavid du Colombier if(cursafe+curarg > maxargsafe) 4173e12c5d1SDavid du Colombier maxargsafe = cursafe+curarg; 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier 4203e12c5d1SDavid du Colombier void 4213e12c5d1SDavid du Colombier regind(Node *n, Node *nn) 4223e12c5d1SDavid du Colombier { 4233e12c5d1SDavid du Colombier 4243e12c5d1SDavid du Colombier if(n->op != OREGISTER) { 4253e12c5d1SDavid du Colombier diag(n, "regind not OREGISTER"); 4263e12c5d1SDavid du Colombier return; 4273e12c5d1SDavid du Colombier } 4283e12c5d1SDavid du Colombier n->op = OINDREG; 4293e12c5d1SDavid du Colombier n->type = nn->type; 4303e12c5d1SDavid du Colombier } 4313e12c5d1SDavid du Colombier 4323e12c5d1SDavid du Colombier void 4333e12c5d1SDavid du Colombier raddr(Node *n, Prog *p) 4343e12c5d1SDavid du Colombier { 4353e12c5d1SDavid du Colombier Adr a; 4363e12c5d1SDavid du Colombier 4373e12c5d1SDavid du Colombier naddr(n, &a); 4383e12c5d1SDavid du Colombier if(a.type == D_CONST && a.offset == 0) { 4393e12c5d1SDavid du Colombier a.type = D_REG; 4403e12c5d1SDavid du Colombier a.reg = 0; 4413e12c5d1SDavid du Colombier } 4423e12c5d1SDavid du Colombier if(a.type != D_REG && a.type != D_FREG) { 4433e12c5d1SDavid du Colombier if(n) 4443e12c5d1SDavid du Colombier diag(n, "bad in raddr: %O", n->op); 4453e12c5d1SDavid du Colombier else 4463e12c5d1SDavid du Colombier diag(n, "bad in raddr: <null>"); 4473e12c5d1SDavid du Colombier p->reg = NREG; 4483e12c5d1SDavid du Colombier } else 4493e12c5d1SDavid du Colombier p->reg = a.reg; 4503e12c5d1SDavid du Colombier } 4513e12c5d1SDavid du Colombier 4523e12c5d1SDavid du Colombier void 4533e12c5d1SDavid du Colombier naddr(Node *n, Adr *a) 4543e12c5d1SDavid du Colombier { 4553e12c5d1SDavid du Colombier long v; 4563e12c5d1SDavid du Colombier 4573e12c5d1SDavid du Colombier a->type = D_NONE; 4583e12c5d1SDavid du Colombier if(n == Z) 4593e12c5d1SDavid du Colombier return; 4603e12c5d1SDavid du Colombier switch(n->op) { 4613e12c5d1SDavid du Colombier default: 4623e12c5d1SDavid du Colombier bad: 4633e12c5d1SDavid du Colombier diag(n, "bad in naddr: %O", n->op); 4643e12c5d1SDavid du Colombier break; 4653e12c5d1SDavid du Colombier 4663e12c5d1SDavid du Colombier case OREGISTER: 4673e12c5d1SDavid du Colombier a->type = D_REG; 4683e12c5d1SDavid du Colombier a->sym = S; 4693e12c5d1SDavid du Colombier a->reg = n->reg; 4703e12c5d1SDavid du Colombier if(a->reg >= NREG) { 4713e12c5d1SDavid du Colombier a->type = D_FREG; 4723e12c5d1SDavid du Colombier a->reg -= NREG; 4733e12c5d1SDavid du Colombier } 4743e12c5d1SDavid du Colombier break; 4753e12c5d1SDavid du Colombier 4763e12c5d1SDavid du Colombier case OIND: 4773e12c5d1SDavid du Colombier naddr(n->left, a); 4783e12c5d1SDavid du Colombier if(a->type == D_REG) { 4793e12c5d1SDavid du Colombier a->type = D_OREG; 4803e12c5d1SDavid du Colombier break; 4813e12c5d1SDavid du Colombier } 4823e12c5d1SDavid du Colombier if(a->type == D_CONST) { 4833e12c5d1SDavid du Colombier a->type = D_OREG; 4843e12c5d1SDavid du Colombier break; 4853e12c5d1SDavid du Colombier } 4863e12c5d1SDavid du Colombier goto bad; 4873e12c5d1SDavid du Colombier 4883e12c5d1SDavid du Colombier case OINDREG: 4893e12c5d1SDavid du Colombier a->type = D_OREG; 4903e12c5d1SDavid du Colombier a->sym = S; 491*219b2ee8SDavid du Colombier a->offset = n->xoffset; 4923e12c5d1SDavid du Colombier a->reg = n->reg; 4933e12c5d1SDavid du Colombier break; 4943e12c5d1SDavid du Colombier 4953e12c5d1SDavid du Colombier case ONAME: 4963e12c5d1SDavid du Colombier a->etype = n->etype; 4973e12c5d1SDavid du Colombier a->type = D_OREG; 4983e12c5d1SDavid du Colombier a->name = D_STATIC; 4993e12c5d1SDavid du Colombier a->sym = n->sym; 500*219b2ee8SDavid du Colombier a->offset = n->xoffset; 5013e12c5d1SDavid du Colombier if(n->class == CSTATIC) 5023e12c5d1SDavid du Colombier break; 5033e12c5d1SDavid du Colombier if(n->class == CEXTERN || n->class == CGLOBL) { 5043e12c5d1SDavid du Colombier a->name = D_EXTERN; 5053e12c5d1SDavid du Colombier break; 5063e12c5d1SDavid du Colombier } 5073e12c5d1SDavid du Colombier if(n->class == CAUTO) { 5083e12c5d1SDavid du Colombier a->name = D_AUTO; 5093e12c5d1SDavid du Colombier break; 5103e12c5d1SDavid du Colombier } 5113e12c5d1SDavid du Colombier if(n->class == CPARAM) { 5123e12c5d1SDavid du Colombier a->name = D_PARAM; 5133e12c5d1SDavid du Colombier break; 5143e12c5d1SDavid du Colombier } 5153e12c5d1SDavid du Colombier goto bad; 5163e12c5d1SDavid du Colombier 5173e12c5d1SDavid du Colombier case OCONST: 5183e12c5d1SDavid du Colombier a->sym = S; 5193e12c5d1SDavid du Colombier a->reg = NREG; 520*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) { 5213e12c5d1SDavid du Colombier a->type = D_FCONST; 522*219b2ee8SDavid du Colombier a->dval = n->fconst; 5233e12c5d1SDavid du Colombier } else { 5243e12c5d1SDavid du Colombier a->type = D_CONST; 525*219b2ee8SDavid du Colombier a->offset = n->vconst; 5263e12c5d1SDavid du Colombier } 5273e12c5d1SDavid du Colombier break; 5283e12c5d1SDavid du Colombier 5293e12c5d1SDavid du Colombier case OADDR: 5303e12c5d1SDavid du Colombier naddr(n->left, a); 5313e12c5d1SDavid du Colombier if(a->type == D_OREG) { 5323e12c5d1SDavid du Colombier a->type = D_CONST; 5333e12c5d1SDavid du Colombier break; 5343e12c5d1SDavid du Colombier } 5353e12c5d1SDavid du Colombier goto bad; 5363e12c5d1SDavid du Colombier 5373e12c5d1SDavid du Colombier case OADD: 5383e12c5d1SDavid du Colombier if(n->left->op == OCONST) { 5393e12c5d1SDavid du Colombier naddr(n->left, a); 5403e12c5d1SDavid du Colombier v = a->offset; 5413e12c5d1SDavid du Colombier naddr(n->right, a); 5423e12c5d1SDavid du Colombier } else { 5433e12c5d1SDavid du Colombier naddr(n->right, a); 5443e12c5d1SDavid du Colombier v = a->offset; 5453e12c5d1SDavid du Colombier naddr(n->left, a); 5463e12c5d1SDavid du Colombier } 5473e12c5d1SDavid du Colombier a->offset += v; 5483e12c5d1SDavid du Colombier break; 5493e12c5d1SDavid du Colombier 5503e12c5d1SDavid du Colombier } 5513e12c5d1SDavid du Colombier } 5523e12c5d1SDavid du Colombier 5533e12c5d1SDavid du Colombier void 5543e12c5d1SDavid du Colombier fop(int as, int f1, int f2, Node *t) 5553e12c5d1SDavid du Colombier { 5563e12c5d1SDavid du Colombier Node nod1, nod2, nod3; 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier nodreg(&nod1, t, NREG+f1); 5593e12c5d1SDavid du Colombier nodreg(&nod2, t, NREG+f2); 5603e12c5d1SDavid du Colombier regalloc(&nod3, t, t); 5613e12c5d1SDavid du Colombier gopcode(as, &nod1, &nod2, &nod3); 5623e12c5d1SDavid du Colombier gmove(&nod3, t); 5633e12c5d1SDavid du Colombier regfree(&nod3); 5643e12c5d1SDavid du Colombier } 5653e12c5d1SDavid du Colombier 5663e12c5d1SDavid du Colombier void 5673e12c5d1SDavid du Colombier gmove(Node *f, Node *t) 5683e12c5d1SDavid du Colombier { 5693e12c5d1SDavid du Colombier int ft, tt, a; 5703e12c5d1SDavid du Colombier Node nod, nod1, nod2; 571bd389b36SDavid du Colombier Prog *p1; 5723e12c5d1SDavid du Colombier double d; 5733e12c5d1SDavid du Colombier 5743e12c5d1SDavid du Colombier ft = f->type->etype; 5753e12c5d1SDavid du Colombier tt = t->type->etype; 5763e12c5d1SDavid du Colombier 5773e12c5d1SDavid du Colombier if(ft == TDOUBLE && f->op == OCONST) { 578*219b2ee8SDavid du Colombier d = f->fconst; 5793e12c5d1SDavid du Colombier if(d == 0.0) { 5803e12c5d1SDavid du Colombier a = FREGZERO; 5813e12c5d1SDavid du Colombier goto ffreg; 5823e12c5d1SDavid du Colombier } 5833e12c5d1SDavid du Colombier if(d == 0.5) { 5843e12c5d1SDavid du Colombier a = FREGHALF; 5853e12c5d1SDavid du Colombier goto ffreg; 5863e12c5d1SDavid du Colombier } 5873e12c5d1SDavid du Colombier if(d == 1.0) { 5883e12c5d1SDavid du Colombier a = FREGONE; 5893e12c5d1SDavid du Colombier goto ffreg; 5903e12c5d1SDavid du Colombier } 5913e12c5d1SDavid du Colombier if(d == 2.0) { 5923e12c5d1SDavid du Colombier a = FREGTWO; 5933e12c5d1SDavid du Colombier goto ffreg; 5943e12c5d1SDavid du Colombier } 5953e12c5d1SDavid du Colombier if(d == -.5) { 5963e12c5d1SDavid du Colombier fop(OSUB, FREGHALF, FREGZERO, t); 5973e12c5d1SDavid du Colombier return; 5983e12c5d1SDavid du Colombier } 5993e12c5d1SDavid du Colombier if(d == -1.0) { 6003e12c5d1SDavid du Colombier fop(OSUB, FREGONE, FREGZERO, t); 6013e12c5d1SDavid du Colombier return; 6023e12c5d1SDavid du Colombier } 6033e12c5d1SDavid du Colombier if(d == -2.0) { 6043e12c5d1SDavid du Colombier fop(OSUB, FREGTWO, FREGZERO, t); 6053e12c5d1SDavid du Colombier return; 6063e12c5d1SDavid du Colombier } 6073e12c5d1SDavid du Colombier if(d == 1.5) { 6083e12c5d1SDavid du Colombier fop(OADD, FREGONE, FREGHALF, t); 6093e12c5d1SDavid du Colombier return; 6103e12c5d1SDavid du Colombier } 6113e12c5d1SDavid du Colombier if(d == 2.5) { 6123e12c5d1SDavid du Colombier fop(OADD, FREGTWO, FREGHALF, t); 6133e12c5d1SDavid du Colombier return; 6143e12c5d1SDavid du Colombier } 6153e12c5d1SDavid du Colombier if(d == 3.0) { 6163e12c5d1SDavid du Colombier fop(OADD, FREGTWO, FREGONE, t); 6173e12c5d1SDavid du Colombier return; 6183e12c5d1SDavid du Colombier } 6193e12c5d1SDavid du Colombier } 6203e12c5d1SDavid du Colombier if(ft == TFLOAT && f->op == OCONST) { 621*219b2ee8SDavid du Colombier d = f->fconst; 6223e12c5d1SDavid du Colombier if(d == 0) { 6233e12c5d1SDavid du Colombier a = FREGZERO; 6243e12c5d1SDavid du Colombier ffreg: 6253e12c5d1SDavid du Colombier nodreg(&nod, f, NREG+a); 6263e12c5d1SDavid du Colombier gmove(&nod, t); 6273e12c5d1SDavid du Colombier return; 6283e12c5d1SDavid du Colombier } 6293e12c5d1SDavid du Colombier } 6303e12c5d1SDavid du Colombier /* 6313e12c5d1SDavid du Colombier * a load -- 6323e12c5d1SDavid du Colombier * put it into a register then 6333e12c5d1SDavid du Colombier * worry what to do with it. 6343e12c5d1SDavid du Colombier */ 6353e12c5d1SDavid du Colombier if(f->op == ONAME || f->op == OINDREG || f->op == OIND) { 6363e12c5d1SDavid du Colombier switch(ft) { 6373e12c5d1SDavid du Colombier default: 638*219b2ee8SDavid du Colombier if(typefd[tt]) { 6393e12c5d1SDavid du Colombier /* special case can load mem to Freg */ 6403e12c5d1SDavid du Colombier regalloc(&nod, t, t); 6413e12c5d1SDavid du Colombier gins(AMOVW, f, &nod); 6423e12c5d1SDavid du Colombier a = AMOVWD; 6433e12c5d1SDavid du Colombier if(tt == TFLOAT) 6443e12c5d1SDavid du Colombier a = AMOVWF; 6453e12c5d1SDavid du Colombier gins(a, &nod, &nod); 6463e12c5d1SDavid du Colombier gmove(&nod, t); 6473e12c5d1SDavid du Colombier regfree(&nod); 6483e12c5d1SDavid du Colombier return; 6493e12c5d1SDavid du Colombier } 6503e12c5d1SDavid du Colombier a = AMOVW; 6513e12c5d1SDavid du Colombier break; 6523e12c5d1SDavid du Colombier case TFLOAT: 6533e12c5d1SDavid du Colombier a = AMOVF; 6543e12c5d1SDavid du Colombier break; 6553e12c5d1SDavid du Colombier case TDOUBLE: 6563e12c5d1SDavid du Colombier a = AMOVD; 6573e12c5d1SDavid du Colombier break; 6583e12c5d1SDavid du Colombier case TCHAR: 6593e12c5d1SDavid du Colombier a = AMOVB; 6603e12c5d1SDavid du Colombier break; 6613e12c5d1SDavid du Colombier case TUCHAR: 6623e12c5d1SDavid du Colombier a = AMOVBU; 6633e12c5d1SDavid du Colombier break; 6643e12c5d1SDavid du Colombier case TSHORT: 6653e12c5d1SDavid du Colombier a = AMOVH; 6663e12c5d1SDavid du Colombier break; 6673e12c5d1SDavid du Colombier case TUSHORT: 6683e12c5d1SDavid du Colombier a = AMOVHU; 6693e12c5d1SDavid du Colombier break; 6703e12c5d1SDavid du Colombier } 6713e12c5d1SDavid du Colombier if(typechlp[ft] && typelp[tt]) 6723e12c5d1SDavid du Colombier regalloc(&nod, t, t); 6733e12c5d1SDavid du Colombier else 6743e12c5d1SDavid du Colombier regalloc(&nod, f, t); 6753e12c5d1SDavid du Colombier gins(a, f, &nod); 6763e12c5d1SDavid du Colombier gmove(&nod, t); 6773e12c5d1SDavid du Colombier regfree(&nod); 6783e12c5d1SDavid du Colombier return; 6793e12c5d1SDavid du Colombier } 6803e12c5d1SDavid du Colombier 6813e12c5d1SDavid du Colombier /* 6823e12c5d1SDavid du Colombier * a store -- 6833e12c5d1SDavid du Colombier * put it into a register then 6843e12c5d1SDavid du Colombier * store it. 6853e12c5d1SDavid du Colombier */ 6863e12c5d1SDavid du Colombier if(t->op == ONAME || t->op == OINDREG || t->op == OIND) { 6873e12c5d1SDavid du Colombier switch(tt) { 6883e12c5d1SDavid du Colombier default: 6893e12c5d1SDavid du Colombier a = AMOVW; 6903e12c5d1SDavid du Colombier break; 6913e12c5d1SDavid du Colombier case TUCHAR: 6923e12c5d1SDavid du Colombier case TCHAR: 6933e12c5d1SDavid du Colombier a = AMOVB; 6943e12c5d1SDavid du Colombier break; 6953e12c5d1SDavid du Colombier case TUSHORT: 6963e12c5d1SDavid du Colombier case TSHORT: 6973e12c5d1SDavid du Colombier a = AMOVH; 6983e12c5d1SDavid du Colombier break; 6993e12c5d1SDavid du Colombier case TFLOAT: 7003e12c5d1SDavid du Colombier a = AMOVF; 7013e12c5d1SDavid du Colombier break; 7023e12c5d1SDavid du Colombier case TVLONG: 7033e12c5d1SDavid du Colombier case TDOUBLE: 7043e12c5d1SDavid du Colombier a = AMOVD; 7053e12c5d1SDavid du Colombier break; 7063e12c5d1SDavid du Colombier } 707*219b2ee8SDavid du Colombier if(!typefd[ft] && vconst(f) == 0) { 7083e12c5d1SDavid du Colombier gins(a, f, t); 7093e12c5d1SDavid du Colombier return; 7103e12c5d1SDavid du Colombier } 7113e12c5d1SDavid du Colombier if(ft == tt) 7123e12c5d1SDavid du Colombier regalloc(&nod, t, f); 7133e12c5d1SDavid du Colombier else 7143e12c5d1SDavid du Colombier regalloc(&nod, t, Z); 7153e12c5d1SDavid du Colombier gmove(f, &nod); 7163e12c5d1SDavid du Colombier gins(a, &nod, t); 7173e12c5d1SDavid du Colombier regfree(&nod); 7183e12c5d1SDavid du Colombier return; 7193e12c5d1SDavid du Colombier } 7203e12c5d1SDavid du Colombier 7213e12c5d1SDavid du Colombier /* 7223e12c5d1SDavid du Colombier * type x type cross table 7233e12c5d1SDavid du Colombier */ 7243e12c5d1SDavid du Colombier a = AGOK; 7253e12c5d1SDavid du Colombier switch(ft) { 7263e12c5d1SDavid du Colombier case TDOUBLE: 7273e12c5d1SDavid du Colombier case TVLONG: 7283e12c5d1SDavid du Colombier case TFLOAT: 7293e12c5d1SDavid du Colombier switch(tt) { 7303e12c5d1SDavid du Colombier case TDOUBLE: 7313e12c5d1SDavid du Colombier case TVLONG: 7323e12c5d1SDavid du Colombier a = AMOVD; 7333e12c5d1SDavid du Colombier if(ft == TFLOAT) 7343e12c5d1SDavid du Colombier a = AMOVFD; 7353e12c5d1SDavid du Colombier break; 7363e12c5d1SDavid du Colombier case TFLOAT: 7373e12c5d1SDavid du Colombier a = AMOVDF; 7383e12c5d1SDavid du Colombier if(ft == TFLOAT) 7393e12c5d1SDavid du Colombier a = AMOVF; 7403e12c5d1SDavid du Colombier break; 7413e12c5d1SDavid du Colombier case TLONG: 7423e12c5d1SDavid du Colombier case TULONG: 7433e12c5d1SDavid du Colombier case TIND: 7443e12c5d1SDavid du Colombier case TSHORT: 7453e12c5d1SDavid du Colombier case TUSHORT: 7463e12c5d1SDavid du Colombier case TCHAR: 7473e12c5d1SDavid du Colombier case TUCHAR: 7483e12c5d1SDavid du Colombier regalloc(&nod1, ®node, Z); 7493e12c5d1SDavid du Colombier regalloc(&nod2, ®node, Z); 750*219b2ee8SDavid du Colombier 751*219b2ee8SDavid du Colombier /* movw fcr, rx */ 7523e12c5d1SDavid du Colombier gins(AMOVW, Z, &nod1); 7533e12c5d1SDavid du Colombier p->from.type = D_FCREG; 7543e12c5d1SDavid du Colombier p->from.reg = 31; 7553e12c5d1SDavid du Colombier 756*219b2ee8SDavid du Colombier /* nop */ 7573e12c5d1SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 7583e12c5d1SDavid du Colombier p->to.type = D_REG; 7593e12c5d1SDavid du Colombier p->to.reg = 0; 7603e12c5d1SDavid du Colombier 761*219b2ee8SDavid du Colombier /* nop */ 762*219b2ee8SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 763*219b2ee8SDavid du Colombier p->to.type = D_REG; 764*219b2ee8SDavid du Colombier p->to.reg = 0; 765*219b2ee8SDavid du Colombier 766*219b2ee8SDavid du Colombier /* or $3, rx, ry */ 767*219b2ee8SDavid du Colombier gins(AOR, nodconst(3), &nod2); 768*219b2ee8SDavid du Colombier p->reg = nod1.reg; 769*219b2ee8SDavid du Colombier 770*219b2ee8SDavid du Colombier /* xor $2, ry */ 771*219b2ee8SDavid du Colombier gins(AXOR, nodconst(2), &nod2); 772*219b2ee8SDavid du Colombier 773*219b2ee8SDavid du Colombier /* movw ry, fcr */ 774*219b2ee8SDavid du Colombier gins(AMOVW, &nod2, Z); 775*219b2ee8SDavid du Colombier p->to.type = D_FCREG; 776*219b2ee8SDavid du Colombier p->to.reg = 31; 777*219b2ee8SDavid du Colombier 778*219b2ee8SDavid du Colombier /* nop */ 779*219b2ee8SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 780*219b2ee8SDavid du Colombier p->to.type = D_REG; 781*219b2ee8SDavid du Colombier p->to.reg = 0; 782*219b2ee8SDavid du Colombier 783*219b2ee8SDavid du Colombier /* nop */ 784*219b2ee8SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 785*219b2ee8SDavid du Colombier p->to.type = D_REG; 786*219b2ee8SDavid du Colombier p->to.reg = 0; 787*219b2ee8SDavid du Colombier 788*219b2ee8SDavid du Colombier /* convert f, t */ 7893e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 7903e12c5d1SDavid du Colombier gins(AMOVDW, f, &nod); 7913e12c5d1SDavid du Colombier if(ft == TFLOAT) 7923e12c5d1SDavid du Colombier p->as = AMOVFW; 7933e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 7943e12c5d1SDavid du Colombier regfree(&nod); 7953e12c5d1SDavid du Colombier gins(AMOVW, t, t); 7963e12c5d1SDavid du Colombier 797*219b2ee8SDavid du Colombier /* movw rx, fcr */ 7983e12c5d1SDavid du Colombier gins(AMOVW, &nod1, Z); 7993e12c5d1SDavid du Colombier p->to.type = D_FCREG; 8003e12c5d1SDavid du Colombier p->to.reg = 31; 801*219b2ee8SDavid du Colombier 802*219b2ee8SDavid du Colombier /* nop */ 8033e12c5d1SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 8043e12c5d1SDavid du Colombier p->to.type = D_REG; 8053e12c5d1SDavid du Colombier p->to.reg = 0; 806*219b2ee8SDavid du Colombier 807*219b2ee8SDavid du Colombier /* nop */ 808*219b2ee8SDavid du Colombier gins(ANOR, nodconst(0), nodconst(0)); 809*219b2ee8SDavid du Colombier p->to.type = D_REG; 810*219b2ee8SDavid du Colombier p->to.reg = 0; 811*219b2ee8SDavid du Colombier 8123e12c5d1SDavid du Colombier regfree(&nod1); 8133e12c5d1SDavid du Colombier regfree(&nod2); 8143e12c5d1SDavid du Colombier return; 8153e12c5d1SDavid du Colombier } 8163e12c5d1SDavid du Colombier break; 8173e12c5d1SDavid du Colombier case TULONG: 818bd389b36SDavid du Colombier case TLONG: 8193e12c5d1SDavid du Colombier case TIND: 8203e12c5d1SDavid du Colombier switch(tt) { 8213e12c5d1SDavid du Colombier case TDOUBLE: 8223e12c5d1SDavid du Colombier case TVLONG: 8233e12c5d1SDavid du Colombier gins(AMOVW, f, t); 8243e12c5d1SDavid du Colombier gins(AMOVWD, t, t); 825bd389b36SDavid du Colombier if(ft == TULONG) { 826bd389b36SDavid du Colombier regalloc(&nod, t, Z); 827bd389b36SDavid du Colombier gins(ACMPGED, t, Z); 828bd389b36SDavid du Colombier p->reg = FREGZERO; 829bd389b36SDavid du Colombier gins(ABFPT, Z, Z); 830bd389b36SDavid du Colombier p1 = p; 831bd389b36SDavid du Colombier gins(AMOVD, nodfconst(4294967296.), &nod); 832bd389b36SDavid du Colombier gins(AADDD, &nod, t); 833bd389b36SDavid du Colombier patch(p1, pc); 834bd389b36SDavid du Colombier regfree(&nod); 835bd389b36SDavid du Colombier } 8363e12c5d1SDavid du Colombier return; 8373e12c5d1SDavid du Colombier case TFLOAT: 8383e12c5d1SDavid du Colombier gins(AMOVW, f, t); 8393e12c5d1SDavid du Colombier gins(AMOVWF, t, t); 840bd389b36SDavid du Colombier if(ft == TULONG) { 841bd389b36SDavid du Colombier regalloc(&nod, t, Z); 842bd389b36SDavid du Colombier gins(ACMPGEF, t, Z); 843bd389b36SDavid du Colombier p->reg = FREGZERO; 844bd389b36SDavid du Colombier gins(ABFPT, Z, Z); 845bd389b36SDavid du Colombier p1 = p; 846bd389b36SDavid du Colombier gins(AMOVF, nodfconst(4294967296.), &nod); 847bd389b36SDavid du Colombier gins(AADDF, &nod, t); 848bd389b36SDavid du Colombier patch(p1, pc); 849bd389b36SDavid du Colombier regfree(&nod); 850bd389b36SDavid du Colombier } 8513e12c5d1SDavid du Colombier return; 8523e12c5d1SDavid du Colombier case TLONG: 8533e12c5d1SDavid du Colombier case TULONG: 8543e12c5d1SDavid du Colombier case TIND: 8553e12c5d1SDavid du Colombier case TSHORT: 8563e12c5d1SDavid du Colombier case TUSHORT: 8573e12c5d1SDavid du Colombier case TCHAR: 8583e12c5d1SDavid du Colombier case TUCHAR: 8593e12c5d1SDavid du Colombier a = AMOVW; 8603e12c5d1SDavid du Colombier break; 8613e12c5d1SDavid du Colombier } 8623e12c5d1SDavid du Colombier break; 8633e12c5d1SDavid du Colombier case TSHORT: 8643e12c5d1SDavid du Colombier switch(tt) { 8653e12c5d1SDavid du Colombier case TDOUBLE: 8663e12c5d1SDavid du Colombier case TVLONG: 8673e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 8683e12c5d1SDavid du Colombier gins(AMOVH, f, &nod); 8693e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 8703e12c5d1SDavid du Colombier gins(AMOVWD, t, t); 8713e12c5d1SDavid du Colombier regfree(&nod); 8723e12c5d1SDavid du Colombier return; 8733e12c5d1SDavid du Colombier case TFLOAT: 8743e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 8753e12c5d1SDavid du Colombier gins(AMOVH, f, &nod); 8763e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 8773e12c5d1SDavid du Colombier gins(AMOVWF, t, t); 8783e12c5d1SDavid du Colombier regfree(&nod); 8793e12c5d1SDavid du Colombier return; 8803e12c5d1SDavid du Colombier case TULONG: 8813e12c5d1SDavid du Colombier case TLONG: 8823e12c5d1SDavid du Colombier case TIND: 8833e12c5d1SDavid du Colombier a = AMOVH; 8843e12c5d1SDavid du Colombier break; 8853e12c5d1SDavid du Colombier case TSHORT: 8863e12c5d1SDavid du Colombier case TUSHORT: 8873e12c5d1SDavid du Colombier case TCHAR: 8883e12c5d1SDavid du Colombier case TUCHAR: 8893e12c5d1SDavid du Colombier a = AMOVW; 8903e12c5d1SDavid du Colombier break; 8913e12c5d1SDavid du Colombier } 8923e12c5d1SDavid du Colombier break; 8933e12c5d1SDavid du Colombier case TUSHORT: 8943e12c5d1SDavid du Colombier switch(tt) { 8953e12c5d1SDavid du Colombier case TDOUBLE: 8963e12c5d1SDavid du Colombier case TVLONG: 8973e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 8983e12c5d1SDavid du Colombier gins(AMOVHU, f, &nod); 8993e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9003e12c5d1SDavid du Colombier gins(AMOVWD, t, t); 9013e12c5d1SDavid du Colombier regfree(&nod); 9023e12c5d1SDavid du Colombier return; 9033e12c5d1SDavid du Colombier case TFLOAT: 9043e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 9053e12c5d1SDavid du Colombier gins(AMOVHU, f, &nod); 9063e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9073e12c5d1SDavid du Colombier gins(AMOVWF, t, t); 9083e12c5d1SDavid du Colombier regfree(&nod); 9093e12c5d1SDavid du Colombier return; 9103e12c5d1SDavid du Colombier case TLONG: 9113e12c5d1SDavid du Colombier case TULONG: 9123e12c5d1SDavid du Colombier case TIND: 9133e12c5d1SDavid du Colombier a = AMOVHU; 9143e12c5d1SDavid du Colombier break; 9153e12c5d1SDavid du Colombier case TSHORT: 9163e12c5d1SDavid du Colombier case TUSHORT: 9173e12c5d1SDavid du Colombier case TCHAR: 9183e12c5d1SDavid du Colombier case TUCHAR: 9193e12c5d1SDavid du Colombier a = AMOVW; 9203e12c5d1SDavid du Colombier break; 9213e12c5d1SDavid du Colombier } 9223e12c5d1SDavid du Colombier break; 9233e12c5d1SDavid du Colombier case TCHAR: 9243e12c5d1SDavid du Colombier switch(tt) { 9253e12c5d1SDavid du Colombier case TDOUBLE: 9263e12c5d1SDavid du Colombier case TVLONG: 9273e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 9283e12c5d1SDavid du Colombier gins(AMOVB, f, &nod); 9293e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9303e12c5d1SDavid du Colombier gins(AMOVWD, t, t); 9313e12c5d1SDavid du Colombier regfree(&nod); 9323e12c5d1SDavid du Colombier return; 9333e12c5d1SDavid du Colombier case TFLOAT: 9343e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 9353e12c5d1SDavid du Colombier gins(AMOVB, f, &nod); 9363e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9373e12c5d1SDavid du Colombier gins(AMOVWF, t, t); 9383e12c5d1SDavid du Colombier regfree(&nod); 9393e12c5d1SDavid du Colombier return; 9403e12c5d1SDavid du Colombier case TLONG: 9413e12c5d1SDavid du Colombier case TULONG: 9423e12c5d1SDavid du Colombier case TIND: 9433e12c5d1SDavid du Colombier case TSHORT: 9443e12c5d1SDavid du Colombier case TUSHORT: 9453e12c5d1SDavid du Colombier a = AMOVB; 9463e12c5d1SDavid du Colombier break; 9473e12c5d1SDavid du Colombier case TCHAR: 9483e12c5d1SDavid du Colombier case TUCHAR: 9493e12c5d1SDavid du Colombier a = AMOVW; 9503e12c5d1SDavid du Colombier break; 9513e12c5d1SDavid du Colombier } 9523e12c5d1SDavid du Colombier break; 9533e12c5d1SDavid du Colombier case TUCHAR: 9543e12c5d1SDavid du Colombier switch(tt) { 9553e12c5d1SDavid du Colombier case TDOUBLE: 9563e12c5d1SDavid du Colombier case TVLONG: 9573e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 9583e12c5d1SDavid du Colombier gins(AMOVBU, f, &nod); 9593e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9603e12c5d1SDavid du Colombier gins(AMOVWD, t, t); 9613e12c5d1SDavid du Colombier regfree(&nod); 9623e12c5d1SDavid du Colombier return; 9633e12c5d1SDavid du Colombier case TFLOAT: 9643e12c5d1SDavid du Colombier regalloc(&nod, f, Z); 9653e12c5d1SDavid du Colombier gins(AMOVBU, f, &nod); 9663e12c5d1SDavid du Colombier gins(AMOVW, &nod, t); 9673e12c5d1SDavid du Colombier gins(AMOVWF, t, t); 9683e12c5d1SDavid du Colombier regfree(&nod); 9693e12c5d1SDavid du Colombier return; 9703e12c5d1SDavid du Colombier case TLONG: 9713e12c5d1SDavid du Colombier case TULONG: 9723e12c5d1SDavid du Colombier case TIND: 9733e12c5d1SDavid du Colombier case TSHORT: 9743e12c5d1SDavid du Colombier case TUSHORT: 9753e12c5d1SDavid du Colombier a = AMOVBU; 9763e12c5d1SDavid du Colombier break; 9773e12c5d1SDavid du Colombier case TCHAR: 9783e12c5d1SDavid du Colombier case TUCHAR: 9793e12c5d1SDavid du Colombier a = AMOVW; 9803e12c5d1SDavid du Colombier break; 9813e12c5d1SDavid du Colombier } 9823e12c5d1SDavid du Colombier break; 9833e12c5d1SDavid du Colombier } 9843e12c5d1SDavid du Colombier if(a == AMOVW || a == AMOVF || a == AMOVD) 9853e12c5d1SDavid du Colombier if(samaddr(f, t)) 9863e12c5d1SDavid du Colombier return; 9873e12c5d1SDavid du Colombier gins(a, f, t); 9883e12c5d1SDavid du Colombier } 9893e12c5d1SDavid du Colombier 9903e12c5d1SDavid du Colombier void 9913e12c5d1SDavid du Colombier gins(int a, Node *f, Node *t) 9923e12c5d1SDavid du Colombier { 9933e12c5d1SDavid du Colombier 9943e12c5d1SDavid du Colombier nextpc(); 9953e12c5d1SDavid du Colombier p->as = a; 9963e12c5d1SDavid du Colombier if(f != Z) 9973e12c5d1SDavid du Colombier naddr(f, &p->from); 9983e12c5d1SDavid du Colombier if(t != Z) 9993e12c5d1SDavid du Colombier naddr(t, &p->to); 10003e12c5d1SDavid du Colombier if(debug['g']) 10013e12c5d1SDavid du Colombier print("%P\n", p); 10023e12c5d1SDavid du Colombier } 10033e12c5d1SDavid du Colombier 10043e12c5d1SDavid du Colombier void 10053e12c5d1SDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t) 10063e12c5d1SDavid du Colombier { 10073e12c5d1SDavid du Colombier int a, et; 10083e12c5d1SDavid du Colombier Adr ta; 10093e12c5d1SDavid du Colombier 10103e12c5d1SDavid du Colombier et = TLONG; 10113e12c5d1SDavid du Colombier if(f1 != Z && f1->type != T) 10123e12c5d1SDavid du Colombier et = f1->type->etype; 10133e12c5d1SDavid du Colombier a = AGOK; 10143e12c5d1SDavid du Colombier switch(o) { 10153e12c5d1SDavid du Colombier case OAS: 10163e12c5d1SDavid du Colombier gmove(f1, t); 10173e12c5d1SDavid du Colombier return; 10183e12c5d1SDavid du Colombier 10193e12c5d1SDavid du Colombier case OASADD: 10203e12c5d1SDavid du Colombier case OADD: 10213e12c5d1SDavid du Colombier a = AADDU; 10223e12c5d1SDavid du Colombier if(et == TFLOAT) 10233e12c5d1SDavid du Colombier a = AADDF; 10243e12c5d1SDavid du Colombier else 10253e12c5d1SDavid du Colombier if(et == TDOUBLE || et == TVLONG) 10263e12c5d1SDavid du Colombier a = AADDD; 10273e12c5d1SDavid du Colombier break; 10283e12c5d1SDavid du Colombier 10293e12c5d1SDavid du Colombier case OASSUB: 10303e12c5d1SDavid du Colombier case OSUB: 10313e12c5d1SDavid du Colombier a = ASUBU; 10323e12c5d1SDavid du Colombier if(et == TFLOAT) 10333e12c5d1SDavid du Colombier a = ASUBF; 10343e12c5d1SDavid du Colombier else 10353e12c5d1SDavid du Colombier if(et == TDOUBLE || et == TVLONG) 10363e12c5d1SDavid du Colombier a = ASUBD; 10373e12c5d1SDavid du Colombier break; 10383e12c5d1SDavid du Colombier 10393e12c5d1SDavid du Colombier case OASOR: 10403e12c5d1SDavid du Colombier case OOR: 10413e12c5d1SDavid du Colombier a = AOR; 10423e12c5d1SDavid du Colombier break; 10433e12c5d1SDavid du Colombier 10443e12c5d1SDavid du Colombier case OASAND: 10453e12c5d1SDavid du Colombier case OAND: 10463e12c5d1SDavid du Colombier a = AAND; 10473e12c5d1SDavid du Colombier break; 10483e12c5d1SDavid du Colombier 10493e12c5d1SDavid du Colombier case OASXOR: 10503e12c5d1SDavid du Colombier case OXOR: 10513e12c5d1SDavid du Colombier a = AXOR; 10523e12c5d1SDavid du Colombier break; 10533e12c5d1SDavid du Colombier 10543e12c5d1SDavid du Colombier case OASLSHR: 10553e12c5d1SDavid du Colombier case OLSHR: 10563e12c5d1SDavid du Colombier a = ASRL; 10573e12c5d1SDavid du Colombier break; 10583e12c5d1SDavid du Colombier 10593e12c5d1SDavid du Colombier case OASASHR: 10603e12c5d1SDavid du Colombier case OASHR: 10613e12c5d1SDavid du Colombier a = ASRA; 10623e12c5d1SDavid du Colombier break; 10633e12c5d1SDavid du Colombier 10643e12c5d1SDavid du Colombier case OASASHL: 10653e12c5d1SDavid du Colombier case OASHL: 10663e12c5d1SDavid du Colombier a = ASLL; 10673e12c5d1SDavid du Colombier break; 10683e12c5d1SDavid du Colombier 10693e12c5d1SDavid du Colombier case OFUNC: 10703e12c5d1SDavid du Colombier a = AJAL; 10713e12c5d1SDavid du Colombier break; 10723e12c5d1SDavid du Colombier 10733e12c5d1SDavid du Colombier case OASMUL: 10743e12c5d1SDavid du Colombier case OMUL: 10753e12c5d1SDavid du Colombier if(et == TFLOAT) { 10763e12c5d1SDavid du Colombier a = AMULF; 10773e12c5d1SDavid du Colombier break; 10783e12c5d1SDavid du Colombier } else 10793e12c5d1SDavid du Colombier if(et == TDOUBLE || et == TVLONG) { 10803e12c5d1SDavid du Colombier a = AMULD; 10813e12c5d1SDavid du Colombier break; 10823e12c5d1SDavid du Colombier } 10833e12c5d1SDavid du Colombier a = AMUL; 10843e12c5d1SDavid du Colombier goto muldiv; 10853e12c5d1SDavid du Colombier 10863e12c5d1SDavid du Colombier case OASDIV: 10873e12c5d1SDavid du Colombier case ODIV: 10883e12c5d1SDavid du Colombier if(et == TFLOAT) { 10893e12c5d1SDavid du Colombier a = ADIVF; 10903e12c5d1SDavid du Colombier break; 10913e12c5d1SDavid du Colombier } else 10923e12c5d1SDavid du Colombier if(et == TDOUBLE || et == TVLONG) { 10933e12c5d1SDavid du Colombier a = ADIVD; 10943e12c5d1SDavid du Colombier break; 10953e12c5d1SDavid du Colombier } 10963e12c5d1SDavid du Colombier a = ADIV; 10973e12c5d1SDavid du Colombier goto muldiv; 10983e12c5d1SDavid du Colombier 10993e12c5d1SDavid du Colombier case OASMOD: 11003e12c5d1SDavid du Colombier case OMOD: 11013e12c5d1SDavid du Colombier a = ADIV; 11023e12c5d1SDavid du Colombier o = OMOD; 11033e12c5d1SDavid du Colombier goto muldiv; 11043e12c5d1SDavid du Colombier 11053e12c5d1SDavid du Colombier case OASLMUL: 11063e12c5d1SDavid du Colombier case OLMUL: 11073e12c5d1SDavid du Colombier a = AMULU; 11083e12c5d1SDavid du Colombier goto muldiv; 11093e12c5d1SDavid du Colombier 11103e12c5d1SDavid du Colombier case OASLMOD: 11113e12c5d1SDavid du Colombier case OLMOD: 11123e12c5d1SDavid du Colombier a = ADIVU; 11133e12c5d1SDavid du Colombier o = OMOD; 11143e12c5d1SDavid du Colombier goto muldiv; 11153e12c5d1SDavid du Colombier 11163e12c5d1SDavid du Colombier case OASLDIV: 11173e12c5d1SDavid du Colombier case OLDIV: 11183e12c5d1SDavid du Colombier a = ADIVU; 11193e12c5d1SDavid du Colombier goto muldiv; 11203e12c5d1SDavid du Colombier 11213e12c5d1SDavid du Colombier muldiv: 11223e12c5d1SDavid du Colombier nextpc(); 11233e12c5d1SDavid du Colombier naddr(f1, &p->from); 11243e12c5d1SDavid du Colombier if(f2 == Z) 11253e12c5d1SDavid du Colombier raddr(t, p); 11263e12c5d1SDavid du Colombier else 11273e12c5d1SDavid du Colombier raddr(f2, p); 11283e12c5d1SDavid du Colombier p->as = a; 11293e12c5d1SDavid du Colombier if(debug['g']) 11303e12c5d1SDavid du Colombier print("%P\n", p); 11313e12c5d1SDavid du Colombier 11323e12c5d1SDavid du Colombier nextpc(); 11333e12c5d1SDavid du Colombier p->as = AMOVW; 11343e12c5d1SDavid du Colombier a = D_LO; 11353e12c5d1SDavid du Colombier if(o == OMOD) 11363e12c5d1SDavid du Colombier a = D_HI; 11373e12c5d1SDavid du Colombier p->from.type = a; 11383e12c5d1SDavid du Colombier naddr(t, &p->to); 11393e12c5d1SDavid du Colombier if(debug['g']) 11403e12c5d1SDavid du Colombier print("%P\n", p); 11413e12c5d1SDavid du Colombier return; 11423e12c5d1SDavid du Colombier 11433e12c5d1SDavid du Colombier case OEQ: 1144*219b2ee8SDavid du Colombier if(!typefd[et]) { 11453e12c5d1SDavid du Colombier a = ABEQ; 11463e12c5d1SDavid du Colombier break; 11473e12c5d1SDavid du Colombier } 11483e12c5d1SDavid du Colombier 11493e12c5d1SDavid du Colombier case ONE: 1150*219b2ee8SDavid du Colombier if(!typefd[et]) { 11513e12c5d1SDavid du Colombier a = ABNE; 11523e12c5d1SDavid du Colombier break; 11533e12c5d1SDavid du Colombier } 11543e12c5d1SDavid du Colombier 11553e12c5d1SDavid du Colombier case OLT: 11563e12c5d1SDavid du Colombier case OLE: 11573e12c5d1SDavid du Colombier case OGE: 11583e12c5d1SDavid du Colombier case OGT: 1159*219b2ee8SDavid du Colombier if(typefd[et]) { 11603e12c5d1SDavid du Colombier nextpc(); 11613e12c5d1SDavid du Colombier if(et == TFLOAT) { 11623e12c5d1SDavid du Colombier a = ACMPGTF; 11633e12c5d1SDavid du Colombier if(o == OEQ || o == ONE) 11643e12c5d1SDavid du Colombier a = ACMPEQF; 11653e12c5d1SDavid du Colombier else 11663e12c5d1SDavid du Colombier if(o == OLT || o == OGE) 11673e12c5d1SDavid du Colombier a = ACMPGEF; 11683e12c5d1SDavid du Colombier } else { 11693e12c5d1SDavid du Colombier a = ACMPGTD; 11703e12c5d1SDavid du Colombier if(o == OEQ || o == ONE) 11713e12c5d1SDavid du Colombier a = ACMPEQD; 11723e12c5d1SDavid du Colombier else 11733e12c5d1SDavid du Colombier if(o == OLT || o == OGE) 11743e12c5d1SDavid du Colombier a = ACMPGED; 11753e12c5d1SDavid du Colombier } 11763e12c5d1SDavid du Colombier p->as = a; 11773e12c5d1SDavid du Colombier naddr(f1, &p->from); 11783e12c5d1SDavid du Colombier raddr(f2, p); 11793e12c5d1SDavid du Colombier if(debug['g']) 11803e12c5d1SDavid du Colombier print("%P\n", p); 11813e12c5d1SDavid du Colombier nextpc(); 11823e12c5d1SDavid du Colombier a = ABFPF; 11833e12c5d1SDavid du Colombier if(o == OEQ || o == OGE || o == OGT) 11843e12c5d1SDavid du Colombier a = ABFPT; 11853e12c5d1SDavid du Colombier p->as = a; 11863e12c5d1SDavid du Colombier if(debug['g']) 11873e12c5d1SDavid du Colombier print("%P\n", p); 11883e12c5d1SDavid du Colombier return; 11893e12c5d1SDavid du Colombier } 11903e12c5d1SDavid du Colombier if(vconst(f1) == 0 || vconst(f2) == 0) { 11913e12c5d1SDavid du Colombier if(vconst(f1) == 0) { 11923e12c5d1SDavid du Colombier o = invrel[relindex(o)]; 11933e12c5d1SDavid du Colombier f1 = f2; 11943e12c5d1SDavid du Colombier } 11953e12c5d1SDavid du Colombier switch(o) { 11963e12c5d1SDavid du Colombier case OLT: 11973e12c5d1SDavid du Colombier a = ABLTZ; 11983e12c5d1SDavid du Colombier break; 11993e12c5d1SDavid du Colombier case OLE: 12003e12c5d1SDavid du Colombier a = ABLEZ; 12013e12c5d1SDavid du Colombier break; 12023e12c5d1SDavid du Colombier case OGE: 12033e12c5d1SDavid du Colombier a = ABGEZ; 12043e12c5d1SDavid du Colombier break; 12053e12c5d1SDavid du Colombier case OGT: 12063e12c5d1SDavid du Colombier a = ABGTZ; 12073e12c5d1SDavid du Colombier break; 12083e12c5d1SDavid du Colombier } 12093e12c5d1SDavid du Colombier f2 = Z; 12103e12c5d1SDavid du Colombier break; 12113e12c5d1SDavid du Colombier } 12123e12c5d1SDavid du Colombier 12133e12c5d1SDavid du Colombier case OLO: 12143e12c5d1SDavid du Colombier case OLS: 12153e12c5d1SDavid du Colombier case OHS: 12163e12c5d1SDavid du Colombier case OHI: 12173e12c5d1SDavid du Colombier nextpc(); 12183e12c5d1SDavid du Colombier if(o == OLE || o == OGT || o == OLS || o == OHI) { 12193e12c5d1SDavid du Colombier naddr(f1, &p->from); 12203e12c5d1SDavid du Colombier raddr(f2, p); 12213e12c5d1SDavid du Colombier } else { 12223e12c5d1SDavid du Colombier naddr(f2, &p->from); 12233e12c5d1SDavid du Colombier raddr(f1, p); 12243e12c5d1SDavid du Colombier } 12253e12c5d1SDavid du Colombier naddr(®node, &p->to); 12263e12c5d1SDavid du Colombier p->to.reg = tmpreg(); 12273e12c5d1SDavid du Colombier a = ASGT; 12283e12c5d1SDavid du Colombier if(o == OLO || o == OLS || o == OHS || o == OHI) 12293e12c5d1SDavid du Colombier a = ASGTU; 12303e12c5d1SDavid du Colombier p->as = a; 12313e12c5d1SDavid du Colombier if(debug['g']) 12323e12c5d1SDavid du Colombier print("%P\n", p); 12333e12c5d1SDavid du Colombier 12343e12c5d1SDavid du Colombier nextpc(); 12353e12c5d1SDavid du Colombier naddr(®node, &p->from); 12363e12c5d1SDavid du Colombier p->from.reg = tmpreg(); 12373e12c5d1SDavid du Colombier a = ABEQ; 12383e12c5d1SDavid du Colombier if(o == OLT || o == OGT || o == OLO || o == OHI) 12393e12c5d1SDavid du Colombier a = ABNE; 12403e12c5d1SDavid du Colombier p->as = a; 12413e12c5d1SDavid du Colombier if(debug['g']) 12423e12c5d1SDavid du Colombier print("%P\n", p); 12433e12c5d1SDavid du Colombier return; 12443e12c5d1SDavid du Colombier } 12453e12c5d1SDavid du Colombier if(a == AGOK) 12463e12c5d1SDavid du Colombier diag(Z, "bad in gopcode %O", o); 12473e12c5d1SDavid du Colombier nextpc(); 12483e12c5d1SDavid du Colombier p->as = a; 12493e12c5d1SDavid du Colombier if(f1 != Z) 12503e12c5d1SDavid du Colombier naddr(f1, &p->from); 12513e12c5d1SDavid du Colombier if(f2 != Z) { 12523e12c5d1SDavid du Colombier naddr(f2, &ta); 12533e12c5d1SDavid du Colombier p->reg = ta.reg; 1254*219b2ee8SDavid du Colombier if(ta.type == D_CONST && ta.offset == 0) 1255*219b2ee8SDavid du Colombier p->reg = REGZERO; 12563e12c5d1SDavid du Colombier } 12573e12c5d1SDavid du Colombier if(t != Z) 12583e12c5d1SDavid du Colombier naddr(t, &p->to); 12593e12c5d1SDavid du Colombier if(debug['g']) 12603e12c5d1SDavid du Colombier print("%P\n", p); 12613e12c5d1SDavid du Colombier } 12623e12c5d1SDavid du Colombier 12633e12c5d1SDavid du Colombier samaddr(Node *f, Node *t) 12643e12c5d1SDavid du Colombier { 12653e12c5d1SDavid du Colombier 12663e12c5d1SDavid du Colombier if(f->op != t->op) 12673e12c5d1SDavid du Colombier return 0; 12683e12c5d1SDavid du Colombier switch(f->op) { 12693e12c5d1SDavid du Colombier 12703e12c5d1SDavid du Colombier case OREGISTER: 12713e12c5d1SDavid du Colombier if(f->reg != t->reg) 12723e12c5d1SDavid du Colombier break; 12733e12c5d1SDavid du Colombier return 1; 12743e12c5d1SDavid du Colombier } 12753e12c5d1SDavid du Colombier return 0; 12763e12c5d1SDavid du Colombier } 12773e12c5d1SDavid du Colombier 12783e12c5d1SDavid du Colombier void 12793e12c5d1SDavid du Colombier gbranch(int o) 12803e12c5d1SDavid du Colombier { 12813e12c5d1SDavid du Colombier int a; 12823e12c5d1SDavid du Colombier 12833e12c5d1SDavid du Colombier a = AGOK; 12843e12c5d1SDavid du Colombier switch(o) { 12853e12c5d1SDavid du Colombier case ORETURN: 12863e12c5d1SDavid du Colombier a = ARET; 12873e12c5d1SDavid du Colombier break; 12883e12c5d1SDavid du Colombier case OGOTO: 12893e12c5d1SDavid du Colombier a = AJMP; 12903e12c5d1SDavid du Colombier break; 12913e12c5d1SDavid du Colombier } 12923e12c5d1SDavid du Colombier nextpc(); 12933e12c5d1SDavid du Colombier if(a == AGOK) { 12943e12c5d1SDavid du Colombier diag(Z, "bad in gbranch %O", o); 12953e12c5d1SDavid du Colombier nextpc(); 12963e12c5d1SDavid du Colombier } 12973e12c5d1SDavid du Colombier p->as = a; 12983e12c5d1SDavid du Colombier } 12993e12c5d1SDavid du Colombier 13003e12c5d1SDavid du Colombier void 13013e12c5d1SDavid du Colombier patch(Prog *op, long pc) 13023e12c5d1SDavid du Colombier { 13033e12c5d1SDavid du Colombier 13043e12c5d1SDavid du Colombier op->to.offset = pc; 13053e12c5d1SDavid du Colombier op->to.type = D_BRANCH; 13063e12c5d1SDavid du Colombier } 13073e12c5d1SDavid du Colombier 13083e12c5d1SDavid du Colombier void 13093e12c5d1SDavid du Colombier gpseudo(int a, Sym *s, Node *n) 13103e12c5d1SDavid du Colombier { 13113e12c5d1SDavid du Colombier 13123e12c5d1SDavid du Colombier nextpc(); 13133e12c5d1SDavid du Colombier p->as = a; 13143e12c5d1SDavid du Colombier p->from.type = D_OREG; 13153e12c5d1SDavid du Colombier p->from.sym = s; 13163e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 13173e12c5d1SDavid du Colombier if(s->class == CSTATIC) 13183e12c5d1SDavid du Colombier p->from.name = D_STATIC; 13193e12c5d1SDavid du Colombier naddr(n, &p->to); 13203e12c5d1SDavid du Colombier if(a == ADATA || a == AGLOBL) 13213e12c5d1SDavid du Colombier pc--; 13223e12c5d1SDavid du Colombier } 13233e12c5d1SDavid du Colombier 13243e12c5d1SDavid du Colombier int 13253e12c5d1SDavid du Colombier sconst(Node *n) 13263e12c5d1SDavid du Colombier { 1327*219b2ee8SDavid du Colombier vlong vv; 13283e12c5d1SDavid du Colombier 1329*219b2ee8SDavid du Colombier if(n->op == OCONST) { 1330*219b2ee8SDavid du Colombier if(!typefd[n->type->etype]) { 1331*219b2ee8SDavid du Colombier vv = n->vconst; 1332*219b2ee8SDavid du Colombier if(vv >= -32766LL && vv < 32766LL) 13333e12c5d1SDavid du Colombier return 1; 13343e12c5d1SDavid du Colombier } 1335*219b2ee8SDavid du Colombier } 13363e12c5d1SDavid du Colombier return 0; 13373e12c5d1SDavid du Colombier } 13383e12c5d1SDavid du Colombier 13393e12c5d1SDavid du Colombier int 13403e12c5d1SDavid du Colombier sval(long v) 13413e12c5d1SDavid du Colombier { 13423e12c5d1SDavid du Colombier if(v >= -32766L && v < 32766L) 13433e12c5d1SDavid du Colombier return 1; 13443e12c5d1SDavid du Colombier return 0; 13453e12c5d1SDavid du Colombier } 13463e12c5d1SDavid du Colombier 13473e12c5d1SDavid du Colombier long 13483e12c5d1SDavid du Colombier exreg(Type *t) 13493e12c5d1SDavid du Colombier { 13503e12c5d1SDavid du Colombier long o; 13513e12c5d1SDavid du Colombier 13523e12c5d1SDavid du Colombier if(typechlp[t->etype]) { 13533e12c5d1SDavid du Colombier if(exregoffset <= 16) 13543e12c5d1SDavid du Colombier return 0; 13553e12c5d1SDavid du Colombier o = exregoffset; 13563e12c5d1SDavid du Colombier exregoffset--; 13573e12c5d1SDavid du Colombier return o; 13583e12c5d1SDavid du Colombier } 1359*219b2ee8SDavid du Colombier if(typefd[t->etype]) { 13603e12c5d1SDavid du Colombier if(exfregoffset <= 16) 13613e12c5d1SDavid du Colombier return 0; 13623e12c5d1SDavid du Colombier o = exfregoffset + NREG; 13633e12c5d1SDavid du Colombier exfregoffset--; 13643e12c5d1SDavid du Colombier return o; 13653e12c5d1SDavid du Colombier } 13663e12c5d1SDavid du Colombier return 0; 13673e12c5d1SDavid du Colombier } 13683e12c5d1SDavid du Colombier 13693e12c5d1SDavid du Colombier schar ewidth[XTYPE] = 13703e12c5d1SDavid du Colombier { 13713e12c5d1SDavid du Colombier -1, /* TXXX */ 13723e12c5d1SDavid du Colombier SZ_CHAR, SZ_CHAR, /* TCHAR TUCHAR */ 13733e12c5d1SDavid du Colombier SZ_SHORT, SZ_SHORT, /* TSHORT TUSHORT */ 13743e12c5d1SDavid du Colombier SZ_LONG, SZ_LONG, /* TLONG TULONG */ 1375*219b2ee8SDavid du Colombier SZ_VLONG, SZ_VLONG, /* TVLONG TUVLONG */ 13763e12c5d1SDavid du Colombier SZ_FLOAT, SZ_DOUBLE, /* TFLOAT TDOUBLE */ 13773e12c5d1SDavid du Colombier SZ_IND, 0, /* TIND TFUNC */ 13783e12c5d1SDavid du Colombier -1, 0, /* TARRAY TVOID */ 13793e12c5d1SDavid du Colombier -1, -1, /* TSTRUCT TUNION */ 13803e12c5d1SDavid du Colombier -1 /* TENUM */ 13813e12c5d1SDavid du Colombier }; 13823e12c5d1SDavid du Colombier long ncast[XTYPE] = 13833e12c5d1SDavid du Colombier { 13843e12c5d1SDavid du Colombier /* TXXX */ 0, 13853e12c5d1SDavid du Colombier /* TCHAR */ BCHAR|BUCHAR, 13863e12c5d1SDavid du Colombier /* TUCHAR */ BCHAR|BUCHAR, 13873e12c5d1SDavid du Colombier /* TSHORT */ BSHORT|BUSHORT, 13883e12c5d1SDavid du Colombier /* TUSHORT */ BSHORT|BUSHORT, 13893e12c5d1SDavid du Colombier /* TLONG */ BLONG|BULONG|BIND, 13903e12c5d1SDavid du Colombier /* TULONG */ BLONG|BULONG|BIND, 1391*219b2ee8SDavid du Colombier /* TVLONG */ BVLONG|BUVLONG, 1392*219b2ee8SDavid du Colombier /* TUVLONG */ BVLONG|BUVLONG, 13933e12c5d1SDavid du Colombier /* TFLOAT */ BFLOAT, 13943e12c5d1SDavid du Colombier /* TDOUBLE */ BDOUBLE, 13953e12c5d1SDavid du Colombier /* TIND */ BLONG|BULONG|BIND, 13963e12c5d1SDavid du Colombier /* TFUNC */ 0, 13973e12c5d1SDavid du Colombier /* TARRAY */ 0, 13983e12c5d1SDavid du Colombier /* TVOID */ 0, 13993e12c5d1SDavid du Colombier /* TSTRUCT */ BSTRUCT, 14003e12c5d1SDavid du Colombier /* TUNION */ BUNION, 14013e12c5d1SDavid du Colombier /* TENUM */ 0, 14023e12c5d1SDavid du Colombier }; 1403