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 memset(reg, 0, sizeof(reg));
86 for(i=NREG; i<NREG+NREG; i+=2)
97 if(i != REGZERO && i != REGTMP && i != REGLINK)
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 & MASK(32);
228 constnode.vconst = v;
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])
261 regalloc(Node *n, Node *tn, Node *o)
266 switch(tn->type->etype) {
276 if(o != Z && o->op == OREGISTER) {
278 if(i > 0 && i < NREG)
281 j = lasti + REGRET+1;
282 for(i=REGRET+1; i<NREG; i++) {
291 diag(tn, "out of fixed registers");
297 if(o != Z && o->op == OREGISTER) {
299 if(i >= NREG && i < NREG+NREG)
303 for(i=NREG; i<NREG+NREG; i+=2) {
312 diag(tn, "out of float registers");
315 diag(tn, "unknown type in regalloc: %T", tn->type);
328 regialloc(Node *n, Node *tn, Node *o)
333 nod.type = types[TIND];
334 regalloc(n, &nod, o);
343 if(n->op != OREGISTER && n->op != OINDREG)
346 if(i < 0 || i >= sizeof(reg))
353 diag(n, "error in regfree: %d", i);
357 regsalloc(Node *n, Node *nn)
359 cursafe = align(cursafe, nn->type, Aaut3);
360 maxargsafe = maxround(maxargsafe, cursafe+curarg);
362 n->xoffset = -(stkoff + cursafe);
364 n->etype = nn->type->etype;
365 n->lineno = nn->lineno;
369 regaalloc1(Node *n, Node *nn)
371 nodreg(n, nn, REGARG);
373 curarg = align(curarg, nn->type, Aarg1);
374 curarg = align(curarg, nn->type, Aarg2);
375 maxargsafe = maxround(maxargsafe, cursafe+curarg);
379 regaalloc(Node *n, Node *nn)
381 curarg = align(curarg, nn->type, Aarg1);
385 n->xoffset = curarg + SZ_LONG;
388 curarg = align(curarg, nn->type, Aarg2);
389 maxargsafe = maxround(maxargsafe, cursafe+curarg);
393 regind(Node *n, Node *nn)
396 if(n->op != OREGISTER) {
397 diag(n, "regind not OREGISTER");
405 raddr(Node *n, Prog *p)
410 if(a.type == D_CONST && a.offset == 0) {
414 if(a.type != D_REG && a.type != D_FREG) {
416 diag(n, "bad in raddr: %O", n->op);
418 diag(n, "bad in raddr: <null>");
425 naddr(Node *n, Adr *a)
435 diag(n, "bad in naddr: %O", n->op);
450 if(a->type == D_REG) {
454 if(a->type == D_CONST) {
463 a->offset = n->xoffset;
472 a->offset = n->xoffset;
473 if(n->class == CSTATIC)
475 if(n->class == CEXTERN || n->class == CGLOBL) {
479 if(n->class == CAUTO) {
483 if(n->class == CPARAM) {
492 if(typefd[n->type->etype]) {
497 a->offset = n->vconst;
503 if(a->type == D_OREG) {
510 if(n->left->op == OCONST) {
526 fop(int as, int f1, int f2, Node *t)
528 Node nod1, nod2, nod3;
530 nodreg(&nod1, t, NREG+f1);
531 nodreg(&nod2, t, NREG+f2);
532 regalloc(&nod3, t, t);
533 gopcode(as, &nod1, &nod2, &nod3);
539 gmove(Node *f, Node *t)
549 if(ft == TDOUBLE && f->op == OCONST) {
568 fop(OSUB, FREGHALF, FREGZERO, t);
572 fop(OSUB, FREGONE, FREGZERO, t);
576 fop(OSUB, FREGTWO, FREGZERO, t);
580 fop(OADD, FREGONE, FREGHALF, t);
584 fop(OADD, FREGTWO, FREGHALF, t);
588 fop(OADD, FREGTWO, FREGONE, t);
592 if(ft == TFLOAT && f->op == OCONST) {
597 nodreg(&nod, f, NREG+a);
604 * put it into a register then
605 * worry what to do with it.
607 if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
611 /* special case can load mem to Freg */
612 regalloc(&nod, t, t);
613 gins(AMOVW, f, &nod);
643 regalloc(&nod, f, t);
652 * put it into a register then
655 if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
659 /* special case can store mem from Freg */
660 regalloc(&nod, f, Z);
665 gins(AMOVW, &nod, t);
691 if(!typefd[ft] && vconst(f) == 0) {
696 regalloc(&nod, t, f);
698 regalloc(&nod, t, Z);
706 * type x type cross table
734 regalloc(&nod, f, Z); /* should be type float */
739 gins(AFMOVF, &nod, nodrat);
741 gins(AMOVW, nodrat, t);
743 if(nrathole < SZ_LONG)
840 regalloc(&nod, t, t); /* should be type float */
841 gins(AMOVW, f, nodrat);
842 gins(AFMOVF, nodrat, &nod);
848 if(nrathole < SZ_LONG)
851 regalloc(&nod, t, Z);
855 p->to.reg = FREGZERO;
858 gins(AFMOVF, nodfconst(4294967296.), &nod);
859 gins(AFADDF, &nod, t);
863 p->to.reg = FREGZERO;
866 gins(AFMOVD, nodfconst(4294967296.), &nod);
867 gins(AFADDD, &nod, t);
890 diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
891 if(a == AMOVW || a == AFMOVF || a == AFMOVD)
898 gins(int a, Node *f, Node *t)
912 gopcode(int o, Node *f1, Node *f2, Node *t)
918 if(f1 != Z && f1->type != T)
919 et = f1->type->etype;
932 if(et == TDOUBLE || et == TVLONG)
942 if(et == TDOUBLE || et == TVLONG)
988 if(et == TDOUBLE || et == TVLONG) {
1001 if(et == TDOUBLE || et == TVLONG) {
1081 if(et == TDOUBLE || et == TVLONG)
1084 naddr(f1, &p->from);
1087 if(f1 == Z || t == Z || f2 != Z)
1088 diag(Z, "bad cmp in gopcode %O", o);
1097 diag(Z, "bad in gopcode %O", o);
1101 naddr(f1, &p->from);
1105 if(ta.type == D_CONST && ta.offset == 0)
1114 samaddr(Node *f, Node *t)
1122 if(f->reg != t->reg)
1145 diag(Z, "bad in gbranch %O", o);
1152 patch(Prog *op, long pc)
1156 op->to.type = D_BRANCH;
1160 gpseudo(int a, Sym *s, Node *n)
1165 p->from.type = D_OREG;
1168 p->reg = (profileflg ? 0 : NOPROF);
1169 p->from.name = D_EXTERN;
1170 if(s->class == CSTATIC)
1171 p->from.name = D_STATIC;
1173 if(a == ADATA || a == AGLOBL)
1181 if(v >= -(1<<12) && v < (1<<12))
1191 if(n->op == OCONST) {
1192 if(!typefd[n->type->etype]) {
1194 if(vv >= -(vlong)(1<<12) && vv < (vlong)(1<<12))
1206 if(typechlp[t->etype]) {
1207 if(exregoffset <= 3)
1213 if(typefd[t->etype]) {
1214 if(exfregoffset <= 16)
1216 o = exfregoffset + NREG;
1223 schar ewidth[NTYPE] =
1226 SZ_CHAR, /* [TCHAR] */
1227 SZ_CHAR, /* [TUCHAR] */
1228 SZ_SHORT, /* [TSHORT] */
1229 SZ_SHORT, /* [TUSHORT] */
1230 SZ_INT, /* [TINT] */
1231 SZ_INT, /* [TUINT] */
1232 SZ_LONG, /* [TLONG] */
1233 SZ_LONG, /* [TULONG] */
1234 SZ_VLONG, /* [TVLONG] */
1235 SZ_VLONG, /* [TUVLONG] */
1236 SZ_FLOAT, /* [TFLOAT] */
1237 SZ_DOUBLE, /* [TDOUBLE] */
1238 SZ_IND, /* [TIND] */
1244 SZ_INT, /* [TENUM] */
1250 BCHAR|BUCHAR, /* [TCHAR] */
1251 BCHAR|BUCHAR, /* [TUCHAR] */
1252 BSHORT|BUSHORT, /* [TSHORT] */
1253 BSHORT|BUSHORT, /* [TUSHORT] */
1254 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
1255 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
1256 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
1257 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
1258 BVLONG|BUVLONG, /* [TVLONG] */
1259 BVLONG|BUVLONG, /* [TUVLONG] */
1260 BFLOAT, /* [TFLOAT] */
1261 BDOUBLE, /* [TDOUBLE] */
1262 BLONG|BULONG|BIND, /* [TIND] */
1266 BSTRUCT, /* [TSTRUCT] */
1267 BUNION, /* [TUNION] */