11 exfregoffset = FREGEXT;
22 tfield = types[TLONG];
30 zprog.from.type = D_NONE;
31 zprog.from.name = D_NONE;
32 zprog.from.reg = NREG;
33 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);
82 memset(reg, 0, sizeof(reg));
95 diag(Z, "reg %d left allocated", i);
96 for(i=NREG; i<NREG+NREG; i+=2)
98 diag(Z, "freg %d left allocated", i-NREG);
101 symstring->type->width = nstring;
102 symrathole->type->width = nrathole;
103 for(i=0; i<NHASH; i++)
104 for(s = hash[i]; s != S; s = s->link) {
107 if(s->type->width == 0)
109 if(s->class != CGLOBL && s->class != CSTATIC)
111 if(s->type == types[TENUM])
113 gpseudo(AGLOBL, s, nodconst(s->type->width));
124 p = alloc(sizeof(*p));
138 gargs(Node *n, Node *tn1, Node *tn2)
141 Node fnxargs[20], *fnxp;
146 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
150 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
156 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
163 garg1(n->left, tn1, tn2, f, fnxp);
164 garg1(n->right, tn1, tn2, f, fnxp);
168 if(n->complex >= FNX) {
180 if(typesu[n->type->etype]) {
182 if(n->complex >= FNX) {
183 sugen(*fnxp, tn2, n->type->width);
186 sugen(n, tn2, n->type->width);
189 if(REGARG != NREG && curarg == 0 &&
190 (typechlp[n->type->etype] || typev[n->type->etype])) {
192 if(n->complex >= FNX) {
201 gopcode(OAS, n, Z, tn2);
205 if(n->complex >= FNX) {
211 gopcode(OAS, tn1, Z, tn2);
218 constnode.vconst = v;
225 fconstnode.fconst = d;
230 nodreg(Node *n, Node *nn, int reg)
235 n->lineno = nn->lineno;
239 regret(Node *n, Node *nn)
244 if(typefd[nn->type->etype])
251 regalloc(Node *n, Node *tn, Node *o)
256 switch(tn->type->etype) {
268 if(o != Z && o->op == OREGISTER) {
270 if(i >= 0 && i < NREG - 1)
273 j = lasti + REGRET+1;
274 for(i=REGRET+1; i<NREG; i++) {
283 diag(tn, "out of fixed registers");
288 if(o != Z && o->op == OREGISTER) {
290 if(i >= NREG && i < NREG+NREG)
293 j = NREG + 12 + lasti;
294 for(i=NREG; i<NREG+NREG; i++) {
303 diag(tn, "out of float registers");
306 diag(tn, "unknown type in regalloc: %T", tn->type);
319 regialloc(Node *n, Node *tn, Node *o)
324 nod.type = types[TIND];
325 regalloc(n, &nod, o);
334 if(n->op != OREGISTER && n->op != OINDREG)
337 if(i < 0 || i >= sizeof(reg))
344 diag(n, "error in regfree: %d op %O", i, n->op);
348 regsalloc(Node *n, Node *nn)
350 cursafe = align(cursafe, nn->type, Aaut3);
351 maxargsafe = maxround(maxargsafe, cursafe+curarg);
353 n->xoffset = -(stkoff + cursafe);
355 n->etype = nn->type->etype;
356 n->lineno = nn->lineno;
360 regaalloc1(Node *n, Node *nn)
362 nodreg(n, nn, REGARG);
364 curarg = align(curarg, nn->type, Aarg1);
365 curarg = align(curarg, nn->type, Aarg2);
366 maxargsafe = maxround(maxargsafe, cursafe+curarg);
370 regaalloc(Node *n, Node *nn)
372 curarg = align(curarg, nn->type, Aarg1);
376 n->xoffset = curarg + SZ_VLONG;
379 curarg = align(curarg, nn->type, Aarg2);
380 maxargsafe = maxround(maxargsafe, cursafe+curarg);
384 regind(Node *n, Node *nn)
387 if(n->op != OREGISTER) {
388 diag(n, "regind not OREGISTER");
396 raddr(Node *n, Prog *p)
401 if(a.type == D_CONST && a.offset == 0) {
405 if(a.type != D_REG && a.type != D_FREG) {
407 diag(n, "bad in raddr: %O", n->op);
409 diag(n, "bad in raddr: <null>");
416 naddr(Node *n, Adr *a)
426 diag(n, "bad in naddr: %O", n->op);
441 if(a->type == D_REG) {
445 if(a->type == D_CONST) {
454 a->offset = n->xoffset;
463 a->offset = n->xoffset;
464 if(n->class == CSTATIC)
466 if(n->class == CEXTERN || n->class == CGLOBL) {
470 if(n->class == CAUTO) {
474 if(n->class == CPARAM) {
483 if(typefd[n->type->etype]) {
486 } else if(typev[n->type->etype]) {
488 a->offset = n->vconst;
491 a->offset = convvtox(n->vconst, TLONG); /* alpha arithmetic */
497 if(a->type == D_OREG) {
504 if(n->left->op == OCONST) {
520 fop(int as, int f1, int f2, Node *t)
522 Node nod1, nod2, nod3;
524 nodreg(&nod1, t, NREG+f1);
525 nodreg(&nod2, t, NREG+f2);
526 regalloc(&nod3, t, t);
527 gopcode(as, &nod1, &nod2, &nod3);
533 gmove(Node *f, Node *t)
542 if(ft == TDOUBLE && f->op == OCONST) {
561 fop(OSUB, FREGHALF, FREGZERO, t);
565 fop(OSUB, FREGONE, FREGZERO, t);
569 fop(OSUB, FREGTWO, FREGZERO, t);
573 fop(OADD, FREGONE, FREGHALF, t);
577 fop(OADD, FREGTWO, FREGHALF, t);
581 fop(OADD, FREGTWO, FREGONE, t);
585 if(ft == TFLOAT && f->op == OCONST) {
590 nodreg(&nod, f, NREG+a);
597 * put it into a register then
598 * worry what to do with it.
600 if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
607 /* todo: optimise freg case? */
611 /* special case can load mem to Freg */
612 regalloc(&nod, t, t);
613 gins(AMOVL, f, &nod);
643 if(typechlp[ft] && typeilp[tt])
644 regalloc(&nod, t, t);
646 regalloc(&nod, f, t);
655 * put it into a register then
658 if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
682 if(!typefd[ft] && vconst(f) == 0) {
687 regalloc(&nod, t, f);
689 regalloc(&nod, t, Z);
697 * type x type cross table
723 /*warn(Z, "float to fix"); /**/
724 regalloc(&nod, f, Z); /* should be type float */
725 gins(ACVTTQ, f, &nod);
726 gins(AMOVT, &nod, nodrat);
728 gins(AMOVQ, nodrat, t);
730 if(nrathole < SZ_VLONG)
769 if (ft == TULONG || ft == TUINT) {
857 /*warn(Z, "fix to float"); /**/
858 regalloc(&nod, t, Z); /* should be type float */
859 gins(AMOVQ, f, nodrat);
860 gins(AMOVT, nodrat, &nod);
866 if(nrathole < SZ_VLONG)
887 if(a == AMOVQ || a == AMOVS || a == AMOVT)
894 gins(int a, Node *f, Node *t)
908 gopcode(int o, Node *f1, Node *f2, Node *t)
915 if(f1 != Z && f1->type != T) {
916 if(f1->op == OCONST && t != Z && t->type != T)
919 et = f1->type->etype;
936 if(et == TVLONG || et == TUVLONG)
949 if(et == TVLONG || et == TUVLONG)
971 if(et == TVLONG || et == TUVLONG)
978 if(et == TVLONG || et == TUVLONG)
985 if(et == TVLONG || et == TUVLONG)
1004 if(et == TVLONG || et == TUVLONG)
1017 if(et == TVLONG || et == TUVLONG)
1024 if(et == TVLONG || et == TUVLONG)
1031 if(et == TVLONG || et == TUVLONG)
1038 if(et == TVLONG || et == TUVLONG)
1047 else if (vconst(t) == 0) {
1048 a = (o == OEQ) ? ABEQ : ABNE;
1059 else if (vconst(t) == 0) {
1060 a = (o == OLT) ? ABLT : ABGE;
1072 if(vconst(t) == 0) {
1073 a = (o == OLE)? ABLE: ABGT;
1094 regalloc(&nod, t, Z);
1095 naddr(&nod, &p->to);
1098 if(o == OEQ || o == OLT || o == OLE || o == OLO || o == OLS)
1099 a = typefd[et]? AFBNE: ABNE;
1101 a = typefd[et]? AFBEQ: ABEQ;
1104 naddr(&nod, &p->from);
1111 diag(Z, "bad in gopcode %O", o);
1115 naddr(f1, &p->from);
1119 if(ta.type == D_CONST && ta.offset == 0)
1128 samaddr(Node *f, Node *t)
1136 if(f->reg != t->reg)
1159 diag(Z, "bad in gbranch %O", o);
1166 patch(Prog *op, long pc)
1170 op->to.type = D_BRANCH;
1174 gpseudo(int a, Sym *s, Node *n)
1179 p->from.type = D_OREG;
1182 p->reg = (profileflg ? 0 : NOPROF);
1183 p->from.name = D_EXTERN;
1184 if(s->class == CSTATIC)
1185 p->from.name = D_STATIC;
1187 if(a == ADATA || a == AGLOBL)
1196 if(n->op == OCONST) {
1197 if(!typefd[n->type->etype]) {
1199 if(vv >= -32766LL && vv < 32766LL)
1209 if(v >= -32766L && v < 32766L)
1218 if(v >= 0LL && v < 256LL)
1228 if(n->op == OCONST) {
1229 if(!typefd[n->type->etype]) {
1231 if(vv >= 0LL && vv < 256LL)
1243 if(typechlp[t->etype]) {
1244 if(exregoffset <= 12)
1250 if(typefd[t->etype]) {
1251 if(exfregoffset <= 19)
1253 o = exfregoffset + NREG;
1260 schar ewidth[NTYPE] =
1263 SZ_CHAR, /* [TCHAR] */
1264 SZ_CHAR, /* [TUCHAR] */
1265 SZ_SHORT, /* [TSHORT] */
1266 SZ_SHORT, /* [TUSHORT] */
1267 SZ_INT, /* [TINT] */
1268 SZ_INT, /* [TUINT] */
1269 SZ_LONG, /* [TLONG] */
1270 SZ_LONG, /* [TULONG] */
1271 SZ_VLONG, /* [TVLONG] */
1272 SZ_VLONG, /* [TUVLONG] */
1273 SZ_FLOAT, /* [TFLOAT] */
1274 SZ_DOUBLE, /* [TDOUBLE] */
1275 SZ_IND, /* [TIND] */
1281 SZ_INT, /* [TENUM] */
1287 BCHAR|BUCHAR, /* [TCHAR] */
1288 BCHAR|BUCHAR, /* [TUCHAR] */
1289 BSHORT|BUSHORT, /* [TSHORT] */
1290 BSHORT|BUSHORT, /* [TUSHORT] */
1291 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
1292 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
1293 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
1294 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
1295 BVLONG|BUVLONG, /* [TVLONG] */
1296 BVLONG|BUVLONG, /* [TUVLONG] */
1297 BFLOAT, /* [TFLOAT] */
1298 BDOUBLE, /* [TDOUBLE] */
1299 BLONG|BULONG|BIND, /* [TIND] */
1303 BSTRUCT, /* [TSTRUCT] */
1304 BUNION, /* [TUNION] */