3 static char resvreg[nelem(reg)];
5 #define isv(et) ((et) == TVLONG || (et) == TUVLONG || (et) == TIND)
15 exfregoffset = FREGEXT;
27 tfield = types[TLONG];
29 typeswitch = typechlv;
33 memmove(typechlpv, typechlp, sizeof(typechlpv));
34 typechlpv[TVLONG] = 1;
35 typechlpv[TUVLONG] = 1;
40 zprog.from.type = D_NONE;
41 zprog.from.name = D_NONE;
42 zprog.from.reg = NREG;
43 zprog.to = zprog.from;
45 regnode.op = OREGISTER;
46 regnode.class = CEXREG;
50 regnode.type = types[TLONG];
53 qregnode.type = types[TVLONG];
55 constnode.op = OCONST;
56 constnode.class = CXXX;
57 constnode.complex = 0;
58 constnode.addable = 20;
59 constnode.type = types[TLONG];
61 vconstnode = constnode;
62 vconstnode.type = types[TVLONG];
64 fconstnode.op = OCONST;
65 fconstnode.class = CXXX;
66 fconstnode.complex = 0;
67 fconstnode.addable = 20;
68 fconstnode.type = types[TDOUBLE];
70 nodsafe = new(ONAME, Z, Z);
71 nodsafe->sym = slookup(".safe");
72 nodsafe->type = types[TINT];
73 nodsafe->etype = types[TINT]->etype;
74 nodsafe->class = CAUTO;
77 t = typ(TARRAY, types[TCHAR]);
78 symrathole = slookup(".rathole");
79 symrathole->class = CGLOBL;
82 nodrat = new(ONAME, Z, Z);
83 nodrat->sym = symrathole;
84 nodrat->type = types[TIND];
85 nodrat->etype = TVOID;
86 nodrat->class = CGLOBL;
90 nodret = new(ONAME, Z, Z);
91 nodret->sym = slookup(".ret");
92 nodret->type = types[TIND];
94 nodret->class = CPARAM;
95 nodret = new(OIND, nodret, Z);
100 memset(reg, 0, sizeof(reg));
106 /* keep two external registers */
109 memmove(resvreg, reg, sizeof(reg));
118 for(i=0; i<NREG; i++)
119 if(reg[i] && !resvreg[i])
120 diag(Z, "reg %d left allocated", i);
121 for(i=NREG; i<NREG+NFREG; i++)
122 if(reg[i] && !resvreg[i])
123 diag(Z, "freg %d left allocated", i-NREG);
126 symstring->type->width = nstring;
127 symrathole->type->width = nrathole;
128 for(i=0; i<NHASH; i++)
129 for(s = hash[i]; s != S; s = s->link) {
132 if(s->type->width == 0)
134 if(s->class != CGLOBL && s->class != CSTATIC)
136 if(s->type == types[TENUM])
138 gpseudo(AGLOBL, s, nodconst(s->type->width));
149 p = alloc(sizeof(*p));
163 gargs(Node *n, Node *tn1, Node *tn2)
166 Node fnxargs[20], *fnxp;
171 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
175 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
181 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
188 garg1(n->left, tn1, tn2, f, fnxp);
189 garg1(n->right, tn1, tn2, f, fnxp);
193 if(n->complex >= FNX) {
205 if(typesu[n->type->etype]) {
207 if(n->complex >= FNX) {
208 sugen(*fnxp, tn2, n->type->width);
211 sugen(n, tn2, n->type->width);
214 if(REGARG >= 0 && curarg == 0 && typechlpv[n->type->etype]) {
216 if(n->complex >= FNX) {
225 gopcode(OAS, n, Z, tn2);
229 if(n->complex >= FNX) {
235 gopcode(OAS, tn1, Z, tn2);
240 nodgconst(vlong v, Type *t)
243 return nodconst((long)v);
244 vconstnode.vconst = v;
251 constnode.vconst = v;
258 constnode.vconst = v & MASK(32);
265 fconstnode.fconst = d;
270 nodreg(Node *n, Node *nn, int reg)
275 n->lineno = nn->lineno;
279 regret(Node *n, Node *nn)
284 if(typefd[nn->type->etype])
291 regalloc(Node *n, Node *tn, Node *o)
296 switch(tn->type->etype) {
308 if(o != Z && o->op == OREGISTER) {
310 if(i >= 0 && i < NREG)
313 j = lasti + REGRET+1;
314 for(i=REGRET+1; i<NREG; i++) {
317 if(reg[j] == 0 && resvreg[j] == 0) {
323 diag(tn, "out of fixed registers");
328 if(o != Z && o->op == OREGISTER) {
330 if(i >= NREG && i < NREG+NFREG)
334 for(i=NREG; i<NREG+NFREG; i++) {
343 diag(tn, "out of float registers");
346 diag(tn, "unknown type in regalloc: %T", tn->type);
359 regialloc(Node *n, Node *tn, Node *o)
364 nod.type = types[TIND];
365 regalloc(n, &nod, o);
374 if(n->op != OREGISTER && n->op != OINDREG)
377 if(i < 0 || i >= sizeof(reg))
384 diag(n, "error in regfree: %d", i);
388 regsalloc(Node *n, Node *nn)
390 cursafe = align(cursafe, nn->type, Aaut3);
391 maxargsafe = maxround(maxargsafe, cursafe+curarg);
393 n->xoffset = -(stkoff + cursafe);
395 n->etype = nn->type->etype;
396 n->lineno = nn->lineno;
400 regaalloc1(Node *n, Node *nn)
402 nodreg(n, nn, REGARG);
404 curarg = align(curarg, nn->type, Aarg1);
405 curarg = align(curarg, nn->type, Aarg2);
406 maxargsafe = maxround(maxargsafe, cursafe+curarg);
410 regaalloc(Node *n, Node *nn)
412 curarg = align(curarg, nn->type, Aarg1);
416 n->xoffset = curarg + SZ_VLONG;
419 curarg = align(curarg, nn->type, Aarg2);
420 maxargsafe = maxround(maxargsafe, cursafe+curarg);
424 regind(Node *n, Node *nn)
427 if(n->op != OREGISTER) {
428 diag(n, "regind not OREGISTER");
436 raddr(Node *n, Prog *p)
441 if(a.type == D_CONST && a.offset == 0) {
445 if(a.type != D_REG && a.type != D_FREG) {
447 diag(n, "bad in raddr: %O", n->op);
449 diag(n, "bad in raddr: <null>");
456 naddr(Node *n, Adr *a)
466 diag(n, "bad in naddr: %O", n->op);
481 if(a->type == D_REG) {
485 if(a->type == D_CONST) {
494 a->offset = n->xoffset;
503 a->offset = n->xoffset;
504 if(n->class == CSTATIC)
506 if(n->class == CEXTERN || n->class == CGLOBL) {
510 if(n->class == CAUTO) {
514 if(n->class == CPARAM) {
523 if(typefd[n->type->etype]) {
528 a->offset = n->vconst;
534 if(a->type == D_OREG) {
538 print("bad addr %D\n", a);
542 if(n->left->op == OCONST) {
558 fop(int as, int f1, int f2, Node *t)
560 Node nod1, nod2, nod3;
562 nodreg(&nod1, t, NREG+f1);
563 nodreg(&nod2, t, NREG+f2);
564 regalloc(&nod3, t, t);
565 gopcode(as, &nod1, &nod2, &nod3);
571 gmove(Node *f, Node *t)
579 if(ft == TDOUBLE && f->op == OCONST) {
581 if(ft == TFLOAT && f->op == OCONST) {
586 * put it into a register then
587 * worry what to do with it.
589 if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
625 regalloc(&nod, f, t);
634 * put it into a register then
637 if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
670 if(!typefd[ft] && vconst(f) == 0) {
675 regalloc(&nod, t, f);
677 regalloc(&nod, t, Z);
685 * type x type cross table
737 if(ft == TUINT || ft == TULONG)
738 gins(AUCVTFWD, f, t);
740 gins(ASCVTFWD, f, t);
743 if(ft == TUINT || ft == TULONG)
744 gins(AUCVTFWS, f, t);
746 gins(ASCVTFWS, f, t);
767 a = (f->op == OREGISTER) ? ASXTW : AMOVW;
807 regalloc(&nod, f, Z);
808 gins(AMOVH, f, &nod);
809 gins(ASCVTFWD, &nod, t);
813 regalloc(&nod, f, Z);
814 gins(AMOVH, f, &nod);
815 gins(ASCVTFWS, &nod, t);
838 regalloc(&nod, f, Z);
839 gins(AMOVHU, f, &nod);
840 gins(AUCVTFWD, &nod, t);
844 regalloc(&nod, f, Z);
845 gins(AMOVHU, f, &nod);
846 gins(AUCVTFWS, &nod, t);
869 regalloc(&nod, f, Z);
870 gins(AMOVB, f, &nod);
871 gins(ASCVTFWD, &nod, t);
875 regalloc(&nod, f, Z);
876 gins(AMOVB, f, &nod);
877 gins(ASCVTFWS, &nod, t);
900 regalloc(&nod, f, Z);
901 gins(AMOVBU, f, &nod);
902 gins(AUCVTFWD, &nod, t);
906 regalloc(&nod, f, Z);
907 gins(AMOVBU, f, &nod);
908 gins(AUCVTFWS, &nod, t);
930 diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
931 if(a == AMOV || (a == AMOVW || a == AMOVWU) && ewidth[ft] == ewidth[tt] || a == AFMOVS || a == AFMOVD)
938 gmover(Node *f, Node *t)
945 if(typechlp[ft] && typechlp[tt] && ewidth[ft] >= ewidth[tt]){
974 gins(int a, Node *f, Node *t)
988 gopcode(int o, Node *f1, Node *f2, Node *t)
994 if(f1 != Z && f1->type != T) {
995 et = f1->type->etype;
996 if(f1->op == OCONST){
997 if(t != Z && t->type != T)
999 else if(f2 != Z && f2->type != T && ewidth[f2->type->etype] > ewidth[et])
1000 et = f2->type->etype;
1016 else if(et == TFLOAT)
1018 else if(et == TDOUBLE)
1027 else if(et == TFLOAT)
1029 else if(et == TDOUBLE)
1084 else if(et == TFLOAT)
1086 else if(et == TDOUBLE)
1095 else if(et == TFLOAT)
1097 else if(et == TDOUBLE)
1142 a = ACASE; /* ACASEW? */
1160 else if(et == TDOUBLE)
1164 naddr(f1, &p->from);
1165 if(f1->op == OCONST && p->from.offset < 0){
1166 if(a == ACMPW && (ulong)p->from.offset != 0x80000000UL) {
1168 p->from.offset = -p->from.offset;
1169 }else if(a == ACMP && p->from.offset != 0x8000000000000000LL){
1171 p->from.offset = -p->from.offset;
1184 /* ensure NaN comparison is always false */
1185 if(typefd[et] && !true)
1190 if(typefd[et] && !true)
1195 if(typefd[et] && true)
1200 if(typefd[et] && true)
1221 diag(Z, "bad in gopcode %O", o);
1225 naddr(f1, &p->from);
1237 samaddr(Node *f, Node *t)
1239 return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
1258 diag(Z, "bad in gbranch %O", o);
1265 patch(Prog *op, long pc)
1269 op->to.type = D_BRANCH;
1273 gpseudo(int a, Sym *s, Node *n)
1278 p->from.type = D_OREG;
1280 p->from.name = D_EXTERN;
1282 p->reg = (profileflg ? 0 : NOPROF);
1283 if(s->class == CSTATIC)
1284 p->from.name = D_STATIC;
1286 if(a == ADATA || a == AGLOBL)
1295 if(n->op == OCONST) {
1296 if(!typefd[n->type->etype]) {
1298 if(vv >= (vlong)(-32766) && vv < (vlong)32766)
1301 * should be specialised for constant values which will
1302 * fit in different instructionsl; for now, let 5l
1314 /* uimm12 or uimm24? */
1317 if((v & 0xFFF) == 0)
1325 return isaddcon(v) || isaddcon(-v);
1329 usableoffset(Node *n, vlong o, Node *v)
1334 if(v->op != OCONST || typefd[v->type->etype])
1343 return o >= -256 && o < 4096*s;
1351 if(typechlpv[t->etype]) {
1352 if(exregoffset <= REGEXT-2)
1355 if(reg[o] && !resvreg[o])
1357 resvreg[o] = reg[o] = 1;
1361 if(typefd[t->etype]) {
1362 if(exfregoffset <= NFREG-1)
1364 o = exfregoffset + NREG;
1365 if(reg[o] && !resvreg[o])
1367 resvreg[o] = reg[o] = 1;
1374 schar ewidth[NTYPE] =
1377 SZ_CHAR, /* [TCHAR] */
1378 SZ_CHAR, /* [TUCHAR] */
1379 SZ_SHORT, /* [TSHORT] */
1380 SZ_SHORT, /* [TUSHORT] */
1381 SZ_INT, /* [TINT] */
1382 SZ_INT, /* [TUINT] */
1383 SZ_LONG, /* [TLONG] */
1384 SZ_LONG, /* [TULONG] */
1385 SZ_VLONG, /* [TVLONG] */
1386 SZ_VLONG, /* [TUVLONG] */
1387 SZ_FLOAT, /* [TFLOAT] */
1388 SZ_DOUBLE, /* [TDOUBLE] */
1389 SZ_IND, /* [TIND] */
1395 SZ_INT, /* [TENUM] */
1401 BCHAR|BUCHAR, /* [TCHAR] */
1402 BCHAR|BUCHAR, /* [TUCHAR] */
1403 BSHORT|BUSHORT, /* [TSHORT] */
1404 BSHORT|BUSHORT, /* [TUSHORT] */
1405 BINT|BUINT|BLONG|BULONG, /* [TINT] */
1406 BINT|BUINT|BLONG|BULONG, /* [TUINT] */
1407 BINT|BUINT|BLONG|BULONG, /* [TLONG] */
1408 BINT|BUINT|BLONG|BULONG, /* [TULONG] */
1409 BVLONG|BUVLONG|BIND, /* [TVLONG] */
1410 BVLONG|BUVLONG|BIND, /* [TUVLONG] */
1411 BFLOAT, /* [TFLOAT] */
1412 BDOUBLE, /* [TDOUBLE] */
1413 BVLONG|BUVLONG|BIND, /* [TIND] */
1417 BSTRUCT, /* [TSTRUCT] */
1418 BUNION, /* [TUNION] */