12 exfregoffset = FREGEXT;
23 tfield = types[TLONG];
28 zprog.from.type = D_NONE;
29 zprog.from.name = D_NONE;
30 zprog.from.reg = NREG;
31 zprog.to = zprog.from;
33 regnode.op = OREGISTER;
34 regnode.class = CEXREG;
38 regnode.type = types[TLONG];
40 constnode.op = OCONST;
41 constnode.class = CXXX;
42 constnode.complex = 0;
43 constnode.addable = 20;
44 constnode.type = types[TLONG];
46 fconstnode.op = OCONST;
47 fconstnode.class = CXXX;
48 fconstnode.complex = 0;
49 fconstnode.addable = 20;
50 fconstnode.type = types[TDOUBLE];
52 nodsafe = new(ONAME, Z, Z);
53 nodsafe->sym = slookup(".safe");
54 nodsafe->type = types[TINT];
55 nodsafe->etype = types[TINT]->etype;
56 nodsafe->class = CAUTO;
59 t = typ(TARRAY, types[TCHAR]);
60 symrathole = slookup(".rathole");
61 symrathole->class = CGLOBL;
64 nodrat = new(ONAME, Z, Z);
65 nodrat->sym = symrathole;
66 nodrat->type = types[TIND];
67 nodrat->etype = TVOID;
68 nodrat->class = CGLOBL;
72 nodret = new(ONAME, Z, Z);
73 nodret->sym = slookup(".ret");
74 nodret->type = types[TIND];
76 nodret->class = CPARAM;
77 nodret = new(OIND, nodret, Z);
82 for(i=0; i<nelem(reg); i++) {
85 (i >= NREG && ((i-NREG)&1)))
99 diag(Z, "reg %d left allocated", i);
100 for(i=NREG; i<NREG+NREG; i+=2)
102 diag(Z, "freg %d left allocated", i-NREG);
105 symstring->type->width = nstring;
106 symrathole->type->width = nrathole;
107 for(i=0; i<NHASH; i++)
108 for(s = hash[i]; s != S; s = s->link) {
111 if(s->type->width == 0)
113 if(s->class != CGLOBL && s->class != CSTATIC)
115 if(s->type == types[TENUM])
117 gpseudo(AGLOBL, s, nodconst(s->type->width));
128 p = alloc(sizeof(*p));
142 gargs(Node *n, Node *tn1, Node *tn2)
145 Node fnxargs[20], *fnxp;
150 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
154 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
160 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
167 garg1(n->left, tn1, tn2, f, fnxp);
168 garg1(n->right, tn1, tn2, f, fnxp);
172 if(n->complex >= FNX) {
184 if(typesuv[n->type->etype]) {
186 if(n->complex >= FNX) {
187 sugen(*fnxp, tn2, n->type->width);
190 sugen(n, tn2, n->type->width);
193 if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
195 if(n->complex >= FNX) {
204 gopcode(OAS, n, Z, tn2);
208 if(n->complex >= FNX) {
214 gopcode(OAS, tn1, Z, tn2);
221 constnode.vconst = v;
228 constnode.vconst = v & MASK(32);
235 fconstnode.fconst = d;
240 nodreg(Node *n, Node *nn, int reg)
245 n->lineno = nn->lineno;
249 regret(Node *n, Node *nn)
254 if(typefd[nn->type->etype])
265 for(i=REGRET+1; i<NREG; i++)
268 diag(Z, "out of fixed registers");
273 regalloc(Node *n, Node *tn, Node *o)
278 switch(tn->type->etype) {
288 if(o != Z && o->op == OREGISTER) {
290 if(i > 0 && i < NREG)
293 j = lasti + REGRET+1;
294 for(i=REGRET+1; i<NREG; i++) {
303 diag(tn, "out of fixed registers");
309 if(o != Z && o->op == OREGISTER) {
311 if(i >= NREG && i < NREG+NREG)
315 for(i=NREG; i<NREG+NREG; i+=2) {
324 diag(tn, "out of float registers");
327 diag(tn, "unknown type in regalloc: %T", tn->type);
340 regialloc(Node *n, Node *tn, Node *o)
345 nod.type = types[TIND];
346 regalloc(n, &nod, o);
355 if(n->op != OREGISTER && n->op != OINDREG)
358 if(i < 0 || i >= sizeof(reg))
365 diag(n, "error in regfree: %d", i);
369 regsalloc(Node *n, Node *nn)
371 cursafe = align(cursafe, nn->type, Aaut3);
372 maxargsafe = maxround(maxargsafe, cursafe+curarg);
374 n->xoffset = -(stkoff + cursafe);
376 n->etype = nn->type->etype;
377 n->lineno = nn->lineno;
381 regaalloc1(Node *n, Node *nn)
383 nodreg(n, nn, REGARG);
385 curarg = align(curarg, nn->type, Aarg1);
386 curarg = align(curarg, nn->type, Aarg2);
387 maxargsafe = maxround(maxargsafe, cursafe+curarg);
391 regaalloc(Node *n, Node *nn)
393 curarg = align(curarg, nn->type, Aarg1);
397 n->xoffset = curarg + SZ_LONG;
400 curarg = align(curarg, nn->type, Aarg2);
401 maxargsafe = maxround(maxargsafe, cursafe+curarg);
405 regind(Node *n, Node *nn)
408 if(n->op != OREGISTER) {
409 diag(n, "regind not OREGISTER");
417 raddr(Node *n, Prog *p)
422 if(a.type == D_CONST && a.offset == 0) {
426 if(a.type != D_REG && a.type != D_FREG) {
428 diag(n, "bad in raddr: %O", n->op);
430 diag(n, "bad in raddr: <null>");
437 naddr(Node *n, Adr *a)
447 diag(n, "bad in naddr: %O", n->op);
462 if(a->type == D_REG) {
466 if(a->type == D_CONST) {
475 a->offset = n->xoffset;
484 a->offset = n->xoffset;
485 if(n->class == CSTATIC)
487 if(n->class == CEXTERN || n->class == CGLOBL) {
491 if(n->class == CAUTO) {
495 if(n->class == CPARAM) {
504 if(typefd[n->type->etype]) {
509 a->offset = n->vconst;
515 if(a->type == D_OREG) {
522 if(n->left->op == OCONST) {
538 fop(int as, int f1, int f2, Node *t)
540 Node nod1, nod2, nod3;
542 nodreg(&nod1, t, NREG+f1);
543 nodreg(&nod2, t, NREG+f2);
544 regalloc(&nod3, t, t);
545 gopcode(as, &nod1, &nod2, &nod3);
551 gmove(Node *f, Node *t)
554 Node nod, nod1, nod2;
561 print("gop: %O %O[%s],%O[%s]\n", OAS,
562 f->op, tnames[ft], t->op, tnames[tt]);
564 if(ft == TDOUBLE && f->op == OCONST) {
583 fop(OSUB, FREGHALF, FREGZERO, t);
587 fop(OSUB, FREGONE, FREGZERO, t);
591 fop(OSUB, FREGTWO, FREGZERO, t);
595 fop(OADD, FREGONE, FREGHALF, t);
599 fop(OADD, FREGTWO, FREGHALF, t);
603 fop(OADD, FREGTWO, FREGONE, t);
607 if(ft == TFLOAT && f->op == OCONST) {
612 nodreg(&nod, f, NREG+a);
619 * put it into a register then
620 * worry what to do with it.
622 if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
626 /* special case can load mem to Freg */
627 regalloc(&nod, t, t);
628 gins(AMOVW, f, &nod);
658 if(typechlp[ft] && typeilp[tt])
659 regalloc(&nod, t, t);
661 regalloc(&nod, f, t);
670 * put it into a register then
673 if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
697 if(!typefd[ft] && vconst(f) == 0) {
702 regalloc(&nod, t, f);
704 regalloc(&nod, t, Z);
712 * type x type cross table
742 regalloc(&nod, f, Z);
743 gins(AMOVDW, f, &nod);
746 gins(AMOVW, &nod, t);
751 regalloc(&nod1, ®node, Z);
752 regalloc(&nod2, ®node, Z);
755 gins(AMOVW, Z, &nod1);
756 p->from.type = D_FCREG;
760 gins(ANOR, nodconst(0), nodconst(0));
765 gins(ANOR, nodconst(0), nodconst(0));
770 gins(AOR, nodconst(3), &nod2);
774 gins(AXOR, nodconst(2), &nod2);
777 gins(AMOVW, &nod2, Z);
778 p->to.type = D_FCREG;
782 gins(ANOR, nodconst(0), nodconst(0));
787 gins(ANOR, nodconst(0), nodconst(0));
792 regalloc(&nod, f, Z);
793 gins(AMOVDW, f, &nod);
796 gins(AMOVW, &nod, t);
801 gins(AMOVW, &nod1, Z);
802 p->to.type = D_FCREG;
806 gins(ANOR, nodconst(0), nodconst(0));
811 gins(ANOR, nodconst(0), nodconst(0));
830 if(ft == TULONG || ft == TUINT) {
831 regalloc(&nod, t, Z);
836 gins(AMOVD, nodfconst(4294967296.), &nod);
837 gins(AADDD, &nod, t);
845 if(ft == TULONG || ft == TUINT) {
846 regalloc(&nod, t, Z);
851 gins(AMOVF, nodfconst(4294967296.), &nod);
852 gins(AADDF, &nod, t);
874 regalloc(&nod, f, Z);
875 gins(AMOVH, f, &nod);
876 gins(AMOVW, &nod, t);
881 regalloc(&nod, f, Z);
882 gins(AMOVH, f, &nod);
883 gins(AMOVW, &nod, t);
906 regalloc(&nod, f, Z);
907 gins(AMOVHU, f, &nod);
908 gins(AMOVW, &nod, t);
913 regalloc(&nod, f, Z);
914 gins(AMOVHU, f, &nod);
915 gins(AMOVW, &nod, t);
938 regalloc(&nod, f, Z);
939 gins(AMOVB, f, &nod);
940 gins(AMOVW, &nod, t);
945 regalloc(&nod, f, Z);
946 gins(AMOVB, f, &nod);
947 gins(AMOVW, &nod, t);
970 regalloc(&nod, f, Z);
971 gins(AMOVBU, f, &nod);
972 gins(AMOVW, &nod, t);
977 regalloc(&nod, f, Z);
978 gins(AMOVBU, f, &nod);
979 gins(AMOVW, &nod, t);
1000 diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
1001 if(a == AMOVW || a == AMOVF || a == AMOVD)
1008 gins(int a, Node *f, Node *t)
1022 gopcode(int o, Node *f1, Node *f2, Node *t)
1028 if(f1 != Z && f1->type != T)
1029 et = f1->type->etype;
1042 if(et == TDOUBLE || et == TVLONG)
1052 if(et == TDOUBLE || et == TVLONG)
1104 if(et == TDOUBLE || et == TVLONG) {
1117 if(et == TDOUBLE || et == TVLONG) {
1148 naddr(f1, &p->from);
1188 if(o == OEQ || o == ONE)
1191 if(o == OLT || o == OGE)
1195 if(o == OEQ || o == ONE)
1198 if(o == OLT || o == OGE)
1202 naddr(f1, &p->from);
1208 if(o == OEQ || o == OGE || o == OGT)
1215 if(vconst(f1) == 0 || vconst(f2) == 0) {
1216 if(vconst(f1) == 0) {
1217 o = invrel[relindex(o)];
1243 if(o == OLE || o == OGT || o == OLS || o == OHI) {
1244 naddr(f1, &p->from);
1247 naddr(f2, &p->from);
1250 naddr(®node, &p->to);
1251 p->to.reg = tmpreg();
1253 if(o == OLO || o == OLS || o == OHS || o == OHI)
1260 naddr(®node, &p->from);
1261 p->from.reg = tmpreg();
1263 if(o == OLT || o == OGT || o == OLO || o == OHI)
1271 diag(Z, "bad in gopcode %O", o);
1275 naddr(f1, &p->from);
1279 if(ta.type == D_CONST && ta.offset == 0)
1289 samaddr(Node *f, Node *t)
1297 if(f->reg != t->reg)
1320 diag(Z, "bad in gbranch %O", o);
1327 patch(Prog *op, long pc)
1331 op->to.type = D_BRANCH;
1335 gpseudo(int a, Sym *s, Node *n)
1340 p->from.type = D_OREG;
1343 p->reg = (profileflg ? 0 : NOPROF);
1344 p->from.name = D_EXTERN;
1345 if(s->class == CSTATIC)
1346 p->from.name = D_STATIC;
1348 if(a == ADATA || a == AGLOBL)
1357 if(n->op == OCONST) {
1358 if(!typefd[n->type->etype]) {
1360 if(vv >= (vlong)(-32766) && vv < (vlong)32766)
1370 if(v >= -32766L && v < 32766L)
1380 if(typechlp[t->etype]) {
1381 if(exregoffset <= 16)
1387 if(typefd[t->etype]) {
1388 if(exfregoffset <= 16)
1390 o = exfregoffset + NREG;
1397 schar ewidth[NTYPE] =
1400 SZ_CHAR, /* [TCHAR] */
1401 SZ_CHAR, /* [TUCHAR] */
1402 SZ_SHORT, /* [TSHORT] */
1403 SZ_SHORT, /* [TUSHORT] */
1404 SZ_INT, /* [TINT] */
1405 SZ_INT, /* [TUINT] */
1406 SZ_LONG, /* [TLONG] */
1407 SZ_LONG, /* [TULONG] */
1408 SZ_VLONG, /* [TVLONG] */
1409 SZ_VLONG, /* [TUVLONG] */
1410 SZ_FLOAT, /* [TFLOAT] */
1411 SZ_DOUBLE, /* [TDOUBLE] */
1412 SZ_IND, /* [TIND] */
1418 SZ_INT, /* [TENUM] */
1424 BCHAR|BUCHAR, /* [TCHAR] */
1425 BCHAR|BUCHAR, /* [TUCHAR] */
1426 BSHORT|BUSHORT, /* [TSHORT] */
1427 BSHORT|BUSHORT, /* [TUSHORT] */
1428 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
1429 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
1430 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
1431 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
1432 BVLONG|BUVLONG, /* [TVLONG] */
1433 BVLONG|BUVLONG, /* [TUVLONG] */
1434 BFLOAT, /* [TFLOAT] */
1435 BDOUBLE, /* [TDOUBLE] */
1436 BLONG|BULONG|BIND, /* [TIND] */
1440 BSTRUCT, /* [TSTRUCT] */
1441 BUNION, /* [TUNION] */