3 static char resvreg[nelem(reg)];
13 exfregoffset = FREGEXT;
24 tfield = types[TLONG];
29 zprog.from.type = D_NONE;
30 zprog.from.name = D_NONE;
31 zprog.from.reg = NREG;
32 zprog.to = zprog.from;
35 regnode.op = OREGISTER;
36 regnode.class = CEXREG;
40 regnode.type = types[TLONG];
42 constnode.op = OCONST;
43 constnode.class = CXXX;
44 constnode.complex = 0;
45 constnode.addable = 20;
46 constnode.type = types[TLONG];
48 fconstnode.op = OCONST;
49 fconstnode.class = CXXX;
50 fconstnode.complex = 0;
51 fconstnode.addable = 20;
52 fconstnode.type = types[TDOUBLE];
54 nodsafe = new(ONAME, Z, Z);
55 nodsafe->sym = slookup(".safe");
56 nodsafe->type = types[TINT];
57 nodsafe->etype = types[TINT]->etype;
58 nodsafe->class = CAUTO;
61 t = typ(TARRAY, types[TCHAR]);
62 symrathole = slookup(".rathole");
63 symrathole->class = CGLOBL;
66 nodrat = new(ONAME, Z, Z);
67 nodrat->sym = symrathole;
68 nodrat->type = types[TIND];
69 nodrat->etype = TVOID;
70 nodrat->class = CGLOBL;
74 nodret = new(ONAME, Z, Z);
75 nodret->sym = slookup(".ret");
76 nodret->type = types[TIND];
78 nodret->class = CPARAM;
79 nodret = new(OIND, nodret, Z);
84 memset(reg, 0, sizeof(reg));
91 /* keep two external registers */
94 memmove(resvreg, reg, sizeof(reg));
103 for(i=0; i<NREG; i++)
104 if(reg[i] && !resvreg[i])
105 diag(Z, "reg %d left allocated", i);
106 for(i=NREG; i<NREG+NFREG; i++)
107 if(reg[i] && !resvreg[i])
108 diag(Z, "freg %d left allocated", i-NREG);
111 symstring->type->width = nstring;
112 symrathole->type->width = nrathole;
113 for(i=0; i<NHASH; i++)
114 for(s = hash[i]; s != S; s = s->link) {
117 if(s->type->width == 0)
119 if(s->class != CGLOBL && s->class != CSTATIC)
121 if(s->type == types[TENUM])
123 gpseudo(AGLOBL, s, nodconst(s->type->width));
134 p = alloc(sizeof(*p));
148 gargs(Node *n, Node *tn1, Node *tn2)
151 Node fnxargs[20], *fnxp;
156 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
160 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
166 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
173 garg1(n->left, tn1, tn2, f, fnxp);
174 garg1(n->right, tn1, tn2, f, fnxp);
178 if(n->complex >= FNX) {
190 if(typesuv[n->type->etype]) {
192 if(n->complex >= FNX) {
193 sugen(*fnxp, tn2, n->type->width);
196 sugen(n, tn2, n->type->width);
199 if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
201 if(n->complex >= FNX) {
209 if(n->complex >= FNX) {
215 gopcode(OAS, tn1, Z, tn2);
222 constnode.vconst = v;
229 constnode.vconst = v & MASK(32);
236 fconstnode.fconst = d;
241 nodreg(Node *n, Node *nn, int reg)
246 n->lineno = nn->lineno;
250 regret(Node *n, Node *nn)
255 if(typefd[nn->type->etype])
266 for(i=REGRET+1; i<NREG; i++)
269 diag(Z, "out of fixed registers");
274 regalloc(Node *n, Node *tn, Node *o)
279 switch(tn->type->etype) {
289 if(o != Z && o->op == OREGISTER) {
291 if(i >= 0 && i < NREG)
294 j = lasti + REGRET+1;
295 for(i=REGRET+1; i<NREG; i++) {
298 if(reg[j] == 0 && resvreg[j] == 0) {
304 diag(tn, "out of fixed registers");
310 if(o != Z && o->op == OREGISTER) {
312 if(i >= NREG && i < NREG+NFREG)
316 for(i=NREG; i<NREG+NFREG; i++) {
325 diag(tn, "out of float registers");
328 diag(tn, "unknown type in regalloc: %T", tn->type);
341 regialloc(Node *n, Node *tn, Node *o)
346 nod.type = types[TIND];
347 regalloc(n, &nod, o);
356 if(n->op != OREGISTER && n->op != OINDREG)
359 if(i < 0 || i >= sizeof(reg))
366 diag(n, "error in regfree: %d", i);
370 regsalloc(Node *n, Node *nn)
372 cursafe = align(cursafe, nn->type, Aaut3);
373 maxargsafe = maxround(maxargsafe, cursafe+curarg);
375 n->xoffset = -(stkoff + cursafe);
377 n->etype = nn->type->etype;
378 n->lineno = nn->lineno;
382 regaalloc1(Node *n, Node *nn)
384 nodreg(n, nn, REGARG);
386 curarg = align(curarg, nn->type, Aarg1);
387 curarg = align(curarg, nn->type, Aarg2);
388 maxargsafe = maxround(maxargsafe, cursafe+curarg);
392 regaalloc(Node *n, Node *nn)
394 curarg = align(curarg, nn->type, Aarg1);
398 n->xoffset = curarg + SZ_LONG;
401 curarg = align(curarg, nn->type, Aarg2);
402 maxargsafe = maxround(maxargsafe, cursafe+curarg);
406 regind(Node *n, Node *nn)
409 if(n->op != OREGISTER) {
410 diag(n, "regind not OREGISTER");
418 raddr(Node *n, Prog *p)
423 if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
427 if(a.type != D_REG && a.type != D_FREG) {
429 diag(n, "bad in raddr: %O", n->op);
431 diag(n, "bad in raddr: <null>");
438 naddr(Node *n, Adr *a)
448 diag(n, "bad in naddr: %O", n->op);
463 if(a->type == D_REG) {
467 if(a->type == D_CONST) {
476 a->offset = n->xoffset;
485 a->offset = n->xoffset;
486 if(n->class == CSTATIC)
488 if(n->class == CEXTERN || n->class == CGLOBL) {
492 if(n->class == CAUTO) {
496 if(n->class == CPARAM) {
505 if(typefd[n->type->etype]) {
510 a->offset = n->vconst;
516 if(a->type == D_OREG) {
523 if(n->left->op == OCONST) {
539 fop(int as, int f1, int f2, Node *t)
541 Node nod1, nod2, nod3;
543 nodreg(&nod1, t, NREG+f1);
544 nodreg(&nod2, t, NREG+f2);
545 regalloc(&nod3, t, t);
546 gopcode(as, &nod1, &nod2, &nod3);
552 gmovm(Node *f, Node *t, int w)
561 gmove(Node *f, Node *t)
570 if(ft == TDOUBLE && f->op == OCONST) {
572 if(ft == TFLOAT && f->op == OCONST) {
577 * put it into a register then
578 * worry what to do with it.
580 if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
604 if(typechlp[ft] && typeilp[tt])
605 regalloc(&nod, t, t);
607 regalloc(&nod, f, t);
616 * put it into a register then
619 if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
645 regalloc(&nod, t, f);
647 regalloc(&nod, t, Z);
655 * type x type cross table
695 if(tt == TFLOAT || tt == TDOUBLE) {
696 // ugly and probably longer than necessary,
697 // but vfp has a single instruction for this,
698 // so hopefully it won't last long.
701 // tmp1 = tmp & 0x80000000
703 // t = float(int32(tmp))
707 regalloc(&nod, f, Z);
708 regalloc(&nod1, f, Z);
709 gins(AMOVW, f, &nod);
710 gins(AMOVW, &nod, &nod1);
711 gins(AAND, nodconst(0x80000000), &nod1);
712 gins(AEOR, &nod1, &nod);
714 gins(AMOVWF, &nod, t);
716 gins(AMOVWD, &nod, t);
717 gins(ACMP, nodconst(0), Z);
723 regalloc(&nod, t, Z);
724 gins(AMOVF, nodfconst(2147483648.), &nod);
725 gins(AADDF, &nod, t);
758 regalloc(&nod, f, Z);
759 gins(AMOVH, f, &nod);
760 gins(AMOVWD, &nod, t);
764 regalloc(&nod, f, Z);
765 gins(AMOVH, f, &nod);
766 gins(AMOVWF, &nod, t);
787 regalloc(&nod, f, Z);
788 gins(AMOVHU, f, &nod);
789 gins(AMOVWD, &nod, t);
793 regalloc(&nod, f, Z);
794 gins(AMOVHU, f, &nod);
795 gins(AMOVWF, &nod, t);
816 regalloc(&nod, f, Z);
817 gins(AMOVB, f, &nod);
818 gins(AMOVWD, &nod, t);
822 regalloc(&nod, f, Z);
823 gins(AMOVB, f, &nod);
824 gins(AMOVWF, &nod, t);
845 regalloc(&nod, f, Z);
846 gins(AMOVBU, f, &nod);
847 gins(AMOVWD, &nod, t);
851 regalloc(&nod, f, Z);
852 gins(AMOVBU, f, &nod);
853 gins(AMOVWF, &nod, t);
873 diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
874 if(a == AMOVW || a == AMOVF || a == AMOVD)
881 gmover(Node *f, Node *t)
888 if(typechlp[ft] && typechlp[tt] && ewidth[ft] >= ewidth[tt]){
911 gins(int a, Node *f, Node *t)
925 gopcode(int o, Node *f1, Node *f2, Node *t)
931 if(f1 != Z && f1->type != T)
932 et = f1->type->etype;
945 if(et == TDOUBLE || et == TVLONG)
951 if(f2 && f2->op == OCONST) {
961 if(et == TDOUBLE || et == TVLONG)
1005 if(et == TDOUBLE || et == TVLONG)
1015 if(et == TDOUBLE || et == TVLONG)
1054 if(et == TDOUBLE || et == TVLONG)
1058 naddr(f1, &p->from);
1059 if(a == ACMP && f1->op == OCONST && p->from.offset < 0) {
1061 p->from.offset = -p->from.offset;
1099 naddr(f2, &p->from);
1108 diag(Z, "bad in gopcode %O", o);
1112 naddr(f1, &p->from);
1123 samaddr(Node *f, Node *t)
1131 if(f->reg != t->reg)
1154 diag(Z, "bad in gbranch %O", o);
1161 patch(Prog *op, long pc)
1165 op->to.type = D_BRANCH;
1169 gpseudo(int a, Sym *s, Node *n)
1174 p->from.type = D_OREG;
1176 p->from.name = D_EXTERN;
1178 p->reg = (profileflg ? 0 : NOPROF);
1179 if(s->class == CSTATIC)
1180 p->from.name = D_STATIC;
1182 if(a == ADATA || a == AGLOBL)
1191 if(n->op == OCONST) {
1192 if(!typefd[n->type->etype]) {
1194 if(vv >= (vlong)(-32766) && vv < (vlong)32766)
1197 * should be specialised for constant values which will
1198 * fit in different instructionsl; for now, let 5l
1212 for(i=0; i<16; i++) {
1213 if((v & ~0xff) == 0)
1215 if((~v & ~0xff) == 0)
1217 v = (v<<2) | ((ulong)v>>30);
1227 if(typechlp[t->etype]) {
1228 if(exregoffset <= REGEXT-2)
1231 if(reg[o] && !resvreg[o])
1233 resvreg[o] = reg[o] = 1;
1237 if(typefd[t->etype]) {
1238 if(exfregoffset <= NFREG-1)
1240 o = exfregoffset + NREG;
1241 if(reg[o] && !resvreg[o])
1243 resvreg[o] = reg[o] = 1;
1250 schar ewidth[NTYPE] =
1253 SZ_CHAR, /* [TCHAR] */
1254 SZ_CHAR, /* [TUCHAR] */
1255 SZ_SHORT, /* [TSHORT] */
1256 SZ_SHORT, /* [TUSHORT] */
1257 SZ_INT, /* [TINT] */
1258 SZ_INT, /* [TUINT] */
1259 SZ_LONG, /* [TLONG] */
1260 SZ_LONG, /* [TULONG] */
1261 SZ_VLONG, /* [TVLONG] */
1262 SZ_VLONG, /* [TUVLONG] */
1263 SZ_FLOAT, /* [TFLOAT] */
1264 SZ_DOUBLE, /* [TDOUBLE] */
1265 SZ_IND, /* [TIND] */
1271 SZ_INT, /* [TENUM] */
1277 BCHAR|BUCHAR, /* [TCHAR] */
1278 BCHAR|BUCHAR, /* [TUCHAR] */
1279 BSHORT|BUSHORT, /* [TSHORT] */
1280 BSHORT|BUSHORT, /* [TUSHORT] */
1281 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
1282 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
1283 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
1284 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
1285 BVLONG|BUVLONG, /* [TVLONG] */
1286 BVLONG|BUVLONG, /* [TUVLONG] */
1287 BFLOAT, /* [TFLOAT] */
1288 BDOUBLE, /* [TDOUBLE] */
1289 BLONG|BULONG|BIND, /* [TIND] */
1293 BSTRUCT, /* [TSTRUCT] */
1294 BUNION, /* [TUNION] */