23 tfield = types[TLONG];
25 typeswitch = typechlv;
29 zprog.from.type = D_NONE;
30 zprog.from.index = D_NONE;
32 zprog.to = zprog.from;
34 regnode.op = OREGISTER;
35 regnode.class = CEXREG;
39 regnode.type = types[TLONG];
43 fregnode0.type = types[TDOUBLE];
45 fregnode1 = fregnode0;
46 fregnode1.reg = D_F0+1;
48 constnode.op = OCONST;
49 constnode.class = CXXX;
50 constnode.complex = 0;
51 constnode.addable = 20;
52 constnode.type = types[TLONG];
54 fconstnode.op = OCONST;
55 fconstnode.class = CXXX;
56 fconstnode.complex = 0;
57 fconstnode.addable = 20;
58 fconstnode.type = types[TDOUBLE];
60 nodsafe = new(ONAME, Z, Z);
61 nodsafe->sym = slookup(".safe");
62 nodsafe->type = types[TINT];
63 nodsafe->etype = types[TINT]->etype;
64 nodsafe->class = CAUTO;
67 t = typ(TARRAY, types[TCHAR]);
68 symrathole = slookup(".rathole");
69 symrathole->class = CGLOBL;
72 nodrat = new(ONAME, Z, Z);
73 nodrat->sym = symrathole;
74 nodrat->type = types[TIND];
75 nodrat->etype = TVOID;
76 nodrat->class = CGLOBL;
80 nodret = new(ONAME, Z, Z);
81 nodret->sym = slookup(".ret");
82 nodret->type = types[TIND];
84 nodret->class = CPARAM;
85 nodret = new(OIND, nodret, Z);
90 for(i=0; i<nelem(reg); i++) {
92 if(i >= D_AX && i <= D_DI && i != D_SP)
104 for(i=D_AX; i<=D_DI; i++)
106 diag(Z, "reg %R left allocated", i);
109 symstring->type->width = nstring;
110 symrathole->type->width = nrathole;
111 for(i=0; i<NHASH; i++)
112 for(s = hash[i]; s != S; s = s->link) {
115 if(s->type->width == 0)
117 if(s->class != CGLOBL && s->class != CSTATIC)
119 if(s->type == types[TENUM])
121 gpseudo(AGLOBL, s, nodconst(s->type->width));
132 p = alloc(sizeof(*p));
146 gargs(Node *n, Node *tn1, Node *tn2)
149 Node fnxargs[20], *fnxp;
154 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
158 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
169 for(i=D_AX; i<=D_DI; i++)
172 if(notbp && reg[D_BP] == 0)
178 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
185 garg1(n->left, tn1, tn2, f, fnxp);
186 garg1(n->right, tn1, tn2, f, fnxp);
190 if(n->complex >= FNX) {
202 if(typesu[n->type->etype] || typev[n->type->etype]) {
204 if(n->complex >= FNX) {
205 sugen(*fnxp, tn2, n->type->width);
208 sugen(n, tn2, n->type->width);
211 if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) {
213 if(n->complex >= FNX) {
226 if(n->complex >= FNX) {
239 constnode.vconst = v;
246 fconstnode.fconst = d;
251 isreg(Node *n, int r)
254 if(n->op == OREGISTER)
261 nodreg(Node *n, Node *nn, int r)
270 n->lineno = nn->lineno;
271 if(nn->op == OREGISTER)
279 regret(Node *n, Node *nn)
284 if(typefd[nn->type->etype])
291 regalloc(Node *n, Node *tn, Node *o)
295 switch(tn->type->etype) {
305 if(o != Z && o->op == OREGISTER) {
307 if(i >= D_AX && i <= D_DI)
310 for(i=D_AX; i<=D_DI; i++)
313 diag(tn, "out of fixed registers");
325 n->complex = 0; /* already in registers */
329 n->left = alloc(sizeof(Node));
330 n->right = alloc(sizeof(Node));
331 if(o != Z && o->op == OREGPAIR) {
332 regalloc(n->left, ®node, o->left);
333 regalloc(n->right, ®node, o->right);
335 regalloc(n->left, ®node, Z);
336 regalloc(n->right, ®node, Z);
338 n->right->type = types[TULONG];
339 if(tn->type->etype == TUVLONG)
340 n->left->type = types[TULONG];
343 diag(tn, "unknown type in regalloc: %T", tn->type);
350 //print("+ %R %d\n", i, reg[i]);
354 regialloc(Node *n, Node *tn, Node *o)
359 nod.type = types[TIND];
360 regalloc(n, &nod, o);
368 if(n->op == OREGPAIR) {
375 if(n->op != OREGISTER && n->op != OINDREG)
378 if(i < 0 || i >= sizeof(reg))
383 //print("- %R %d\n", i, reg[i]);
386 diag(n, "error in regfree: %R", i);
390 regsalloc(Node *n, Node *nn)
392 cursafe = align(cursafe, nn->type, Aaut3);
393 maxargsafe = maxround(maxargsafe, cursafe+curarg);
395 n->xoffset = -(stkoff + cursafe);
397 n->etype = nn->type->etype;
398 n->lineno = nn->lineno;
402 regaalloc1(Node *n, Node *nn)
407 diag(n, "regaalloc1");
411 nodreg(n, nn, REGARG);
413 curarg = align(curarg, nn->type, Aarg1);
414 curarg = align(curarg, nn->type, Aarg2);
415 maxargsafe = maxround(maxargsafe, cursafe+curarg);
420 regaalloc(Node *n, Node *nn)
422 curarg = align(curarg, nn->type, Aarg1);
429 curarg = align(curarg, nn->type, Aarg2);
430 maxargsafe = maxround(maxargsafe, cursafe+curarg);
434 regind(Node *n, Node *nn)
437 if(n->op != OREGISTER) {
438 diag(n, "regind not OREGISTER");
446 naddr(Node *n, Adr *a)
456 diag(n, "bad in naddr: %O %D", n->op, a);
457 //prtree(n, "naddr");
466 a->type = D_INDIR + D_GS;
467 a->offset = n->reg - 1;
473 if(a->type >= D_AX && a->type <= D_DI)
476 if(a->type == D_CONST)
477 a->type = D_NONE+D_INDIR;
479 if(a->type == D_ADDR) {
488 if(n->left->op == OADDR || n->left->op == OCONST)
490 if(a->type >= D_AX && a->type <= D_DI)
493 if(a->type == D_CONST)
494 a->type = D_NONE+D_INDIR;
496 if(a->type == D_ADDR) {
503 a->offset += n->xoffset;
507 a->type = n->reg+D_INDIR;
509 a->offset = n->xoffset;
516 a->offset = n->xoffset;
517 if(n->class == CSTATIC)
519 if(n->class == CEXTERN || n->class == CGLOBL) {
523 if(n->class == CAUTO) {
527 if(n->class == CPARAM) {
534 if(typefd[n->type->etype]) {
541 a->offset = n->vconst;
546 if(a->type >= D_INDIR) {
550 if(a->type == D_EXTERN || a->type == D_STATIC ||
551 a->type == D_AUTO || a->type == D_PARAM)
552 if(a->index == D_NONE) {
560 if(n->right->op == OCONST) {
561 v = n->right->vconst;
564 if(n->left->op == OCONST) {
575 #define CASE(a,b) ((a<<8)|(b<<0))
578 gmove(Node *f, Node *t)
587 print("gop: %O %O[%s],%O[%s]\n", OAS,
588 f->op, tnames[ft], t->op, tnames[tt]);
589 if(typefd[ft] && f->op == OCONST) {
596 gins(AFMOVD, f, &fregnode0);
597 gmove(&fregnode0, t);
603 if(f->op == ONAME || f->op == OINDREG ||
604 f->op == OIND || f->op == OINDEX)
614 gins(AFMOVW, f, &fregnode0);
615 gmove(&fregnode0, t);
629 gins(AFMOVL, f, &fregnode0);
630 gmove(&fregnode0, t);
636 regalloc(&nod, f, t);
637 nod.type = types[TLONG];
654 if(t->op == ONAME || t->op == OINDREG ||
655 t->op == OIND || t->op == OINDEX)
671 if(f->op == OCONST) {
675 regalloc(&nod, t, f);
692 switch(CASE(ft,tt)) {
699 case CASE( TCHAR, TCHAR):
700 case CASE( TUCHAR, TCHAR):
701 case CASE( TSHORT, TCHAR):
702 case CASE( TUSHORT,TCHAR):
703 case CASE( TINT, TCHAR):
704 case CASE( TUINT, TCHAR):
705 case CASE( TLONG, TCHAR):
706 case CASE( TULONG, TCHAR):
707 case CASE( TIND, TCHAR):
709 case CASE( TCHAR, TUCHAR):
710 case CASE( TUCHAR, TUCHAR):
711 case CASE( TSHORT, TUCHAR):
712 case CASE( TUSHORT,TUCHAR):
713 case CASE( TINT, TUCHAR):
714 case CASE( TUINT, TUCHAR):
715 case CASE( TLONG, TUCHAR):
716 case CASE( TULONG, TUCHAR):
717 case CASE( TIND, TUCHAR):
719 case CASE( TSHORT, TSHORT):
720 case CASE( TUSHORT,TSHORT):
721 case CASE( TINT, TSHORT):
722 case CASE( TUINT, TSHORT):
723 case CASE( TLONG, TSHORT):
724 case CASE( TULONG, TSHORT):
725 case CASE( TIND, TSHORT):
727 case CASE( TSHORT, TUSHORT):
728 case CASE( TUSHORT,TUSHORT):
729 case CASE( TINT, TUSHORT):
730 case CASE( TUINT, TUSHORT):
731 case CASE( TLONG, TUSHORT):
732 case CASE( TULONG, TUSHORT):
733 case CASE( TIND, TUSHORT):
735 case CASE( TINT, TINT):
736 case CASE( TUINT, TINT):
737 case CASE( TLONG, TINT):
738 case CASE( TULONG, TINT):
739 case CASE( TIND, TINT):
741 case CASE( TINT, TUINT):
742 case CASE( TUINT, TUINT):
743 case CASE( TLONG, TUINT):
744 case CASE( TULONG, TUINT):
745 case CASE( TIND, TUINT):
747 case CASE( TINT, TLONG):
748 case CASE( TUINT, TLONG):
749 case CASE( TLONG, TLONG):
750 case CASE( TULONG, TLONG):
751 case CASE( TIND, TLONG):
753 case CASE( TINT, TULONG):
754 case CASE( TUINT, TULONG):
755 case CASE( TLONG, TULONG):
756 case CASE( TULONG, TULONG):
757 case CASE( TIND, TULONG):
759 case CASE( TINT, TIND):
760 case CASE( TUINT, TIND):
761 case CASE( TLONG, TIND):
762 case CASE( TULONG, TIND):
763 case CASE( TIND, TIND):
768 case CASE( TSHORT, TINT):
769 case CASE( TSHORT, TUINT):
770 case CASE( TSHORT, TLONG):
771 case CASE( TSHORT, TULONG):
772 case CASE( TSHORT, TIND):
774 if(f->op == OCONST) {
776 if(f->vconst & 0x8000)
777 f->vconst |= 0xffff0000;
782 case CASE( TUSHORT,TINT):
783 case CASE( TUSHORT,TUINT):
784 case CASE( TUSHORT,TLONG):
785 case CASE( TUSHORT,TULONG):
786 case CASE( TUSHORT,TIND):
788 if(f->op == OCONST) {
794 case CASE( TCHAR, TSHORT):
795 case CASE( TCHAR, TUSHORT):
796 case CASE( TCHAR, TINT):
797 case CASE( TCHAR, TUINT):
798 case CASE( TCHAR, TLONG):
799 case CASE( TCHAR, TULONG):
800 case CASE( TCHAR, TIND):
802 if(f->op == OCONST) {
805 f->vconst |= 0xffffff00;
810 case CASE( TUCHAR, TSHORT):
811 case CASE( TUCHAR, TUSHORT):
812 case CASE( TUCHAR, TINT):
813 case CASE( TUCHAR, TUINT):
814 case CASE( TUCHAR, TLONG):
815 case CASE( TUCHAR, TULONG):
816 case CASE( TUCHAR, TIND):
818 if(f->op == OCONST) {
827 case CASE( TFLOAT, TCHAR):
828 case CASE( TFLOAT, TUCHAR):
829 case CASE( TFLOAT, TSHORT):
830 case CASE( TFLOAT, TUSHORT):
831 case CASE( TFLOAT, TINT):
832 case CASE( TFLOAT, TLONG):
833 case CASE( TFLOAT, TIND):
835 case CASE( TDOUBLE,TCHAR):
836 case CASE( TDOUBLE,TUCHAR):
837 case CASE( TDOUBLE,TSHORT):
838 case CASE( TDOUBLE,TUSHORT):
839 case CASE( TDOUBLE,TINT):
840 case CASE( TDOUBLE,TLONG):
841 case CASE( TDOUBLE,TIND):
843 regsalloc(&nod, ®node);
844 gins(AFMOVLP, f, &nod);
848 regsalloc(&nod, ®node);
849 regsalloc(&nod1, ®node);
850 gins(AFSTCW, Z, &nod1);
852 gins(AMOVW, nodconst(0xf7f), &nod1);
853 gins(AFLDCW, &nod1, Z);
854 gins(AFMOVLP, f, &nod);
856 gins(AFLDCW, &nod1, Z);
863 case CASE( TDOUBLE, TULONG):
864 case CASE( TFLOAT, TULONG):
865 case CASE( TDOUBLE, TUINT):
866 case CASE( TFLOAT, TUINT):
867 regsalloc(&nod, ®node);
868 gmove(f, &fregnode0);
869 gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
870 gins(AFMOVLP, f, &nod);
871 gins(ASUBL, nodconst(-2147483648), &nod);
878 case CASE( TULONG, TDOUBLE):
879 case CASE( TULONG, TFLOAT):
880 case CASE( TUINT, TDOUBLE):
881 case CASE( TUINT, TFLOAT):
882 regalloc(&nod, f, f);
884 regsalloc(&nod1, ®node);
886 gins(AFMOVL, &nod1, &fregnode0);
887 gins(ACMPL, &nod, nodconst(0));
890 gins(AFADDD, nodfconst(4294967296.), &fregnode0);
898 case CASE( TCHAR, TFLOAT):
899 case CASE( TUCHAR, TFLOAT):
900 case CASE( TSHORT, TFLOAT):
901 case CASE( TUSHORT,TFLOAT):
902 case CASE( TINT, TFLOAT):
903 case CASE( TLONG, TFLOAT):
904 case CASE( TIND, TFLOAT):
906 case CASE( TCHAR, TDOUBLE):
907 case CASE( TUCHAR, TDOUBLE):
908 case CASE( TSHORT, TDOUBLE):
909 case CASE( TUSHORT,TDOUBLE):
910 case CASE( TINT, TDOUBLE):
911 case CASE( TLONG, TDOUBLE):
912 case CASE( TIND, TDOUBLE):
913 regsalloc(&nod, ®node);
915 gins(AFMOVL, &nod, &fregnode0);
921 case CASE( TFLOAT, TFLOAT):
922 case CASE( TDOUBLE,TFLOAT):
924 case CASE( TFLOAT, TDOUBLE):
925 case CASE( TDOUBLE,TDOUBLE):
928 if(a == AMOVL || a == AFMOVD)
943 if(n->left->complex >= FNX)
944 print("botch in doindex\n");
946 regalloc(&nod, ®node, Z);
947 v = constnode.vconst;
948 cgen(n->right, &nod);
950 if(n->left->op == OCONST)
952 else if(n->left->op == OREGISTER)
953 // else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
954 idx.ptr = n->left->reg;
955 else if(n->left->op != OADDR) {
956 reg[D_BP]++; // cant be used as a base
957 regalloc(&nod1, ®node, Z);
958 cgen(n->left, &nod1);
965 constnode.vconst = v;
969 gins(int a, Node *f, Node *t)
972 if(f != Z && f->op == OINDEX)
974 if(t != Z && t->op == OINDEX)
987 fgopcode(int o, Node *f, Node *t, int pop, int rev)
993 if(f != Z && f->type != T)
996 diag(f, "fop: integer %O", o);
1000 if(t != Z && t->type != T)
1001 print("gop: %O %O-%s Z\n", o, f->op, tnames[et]);
1003 print("gop: %O %O-%s %O-%s\n", o,
1004 f->op, tnames[et], t->op, tnames[t->type->etype]);
1097 regalloc(&nod, ®node, Z);
1098 if(nod.reg != D_AX) {
1101 gins(APUSHL, &nod, Z);
1103 gins(AFSTSW, Z, &nod);
1105 gins(APOPL, Z, &nod);
1108 gins(AFSTSW, Z, &nod);
1113 case OEQ: a = AJEQ; break;
1114 case ONE: a = AJNE; break;
1115 case OLT: a = AJCS; break;
1116 case OLE: a = AJLS; break;
1117 case OGE: a = AJCC; break;
1118 case OGT: a = AJHI; break;
1124 diag(Z, "bad in gopcode %O", o);
1129 gopcode(int o, Type *ty, Node *f, Node *t)
1136 if(typefd[et] && o != OADDR && o != OFUNC) {
1137 diag(f, "gop: float %O", o);
1141 if(f != Z && f->type != T)
1142 print("gop: %O %O[%s],", o, f->op, tnames[et]);
1144 print("gop: %O Z,", o);
1145 if(t != Z && t->type != T)
1146 print("%O[%s]\n", t->op, tnames[t->type->etype]);
1154 if(et == TCHAR || et == TUCHAR)
1156 if(et == TSHORT || et == TUSHORT)
1162 if(et == TCHAR || et == TUCHAR)
1164 if(et == TSHORT || et == TUSHORT)
1175 if(et == TCHAR || et == TUCHAR)
1177 if(et == TSHORT || et == TUSHORT)
1184 if(et == TCHAR || et == TUCHAR)
1186 if(et == TSHORT || et == TUSHORT)
1193 if(et == TCHAR || et == TUCHAR)
1195 if(et == TSHORT || et == TUSHORT)
1202 if(et == TCHAR || et == TUCHAR)
1204 if(et == TSHORT || et == TUSHORT)
1211 if(et == TCHAR || et == TUCHAR)
1213 if(et == TSHORT || et == TUSHORT)
1220 if(et == TCHAR || et == TUCHAR)
1222 if(et == TSHORT || et == TUSHORT)
1229 if(et == TCHAR || et == TUCHAR)
1231 if(et == TSHORT || et == TUSHORT)
1238 if(et == TCHAR || et == TUCHAR)
1240 if(et == TSHORT || et == TUSHORT)
1250 if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1285 if(et == TCHAR || et == TUCHAR)
1287 if(et == TSHORT || et == TUSHORT)
1291 case OEQ: a = AJEQ; break;
1292 case ONE: a = AJNE; break;
1293 case OLT: a = AJLT; break;
1294 case OLE: a = AJLE; break;
1295 case OGE: a = AJGE; break;
1296 case OGT: a = AJGT; break;
1297 case OLO: a = AJCS; break;
1298 case OLS: a = AJLS; break;
1299 case OHS: a = AJCC; break;
1300 case OHI: a = AJHI; break;
1306 diag(Z, "bad in gopcode %O", o);
1311 samaddr(Node *f, Node *t)
1319 if(f->reg != t->reg)
1342 diag(Z, "bad in gbranch %O", o);
1349 patch(Prog *op, long pc)
1353 op->to.type = D_BRANCH;
1357 gpseudo(int a, Sym *s, Node *n)
1362 p->from.type = D_EXTERN;
1364 p->from.scale = (profileflg ? 0 : NOPROF);
1365 if(s->class == CSTATIC)
1366 p->from.type = D_STATIC;
1368 if(a == ADATA || a == AGLOBL)
1377 if(n->op == OCONST && !typefd[n->type->etype]) {
1379 if(v >= -32766L && v < 32766L)
1391 if(typechlp[t->etype]){
1392 if(exregoffset >= 32)
1396 return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
1401 schar ewidth[NTYPE] =
1404 SZ_CHAR, /*[TCHAR]*/
1405 SZ_CHAR, /*[TUCHAR]*/
1406 SZ_SHORT, /*[TSHORT]*/
1407 SZ_SHORT, /*[TUSHORT]*/
1410 SZ_LONG, /*[TLONG]*/
1411 SZ_LONG, /*[TULONG]*/
1412 SZ_VLONG, /*[TVLONG]*/
1413 SZ_VLONG, /*[TUVLONG]*/
1414 SZ_FLOAT, /*[TFLOAT]*/
1415 SZ_DOUBLE, /*[TDOUBLE]*/
1427 BCHAR|BUCHAR, /*[TCHAR]*/
1428 BCHAR|BUCHAR, /*[TUCHAR]*/
1429 BSHORT|BUSHORT, /*[TSHORT]*/
1430 BSHORT|BUSHORT, /*[TUSHORT]*/
1431 BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/
1432 BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/
1433 BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/
1434 BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/
1435 BVLONG|BUVLONG, /*[TVLONG]*/
1436 BVLONG|BUVLONG, /*[TUVLONG]*/
1437 BFLOAT, /*[TFLOAT]*/
1438 BDOUBLE, /*[TDOUBLE]*/
1439 BLONG|BULONG|BIND, /*[TIND]*/
1443 BSTRUCT, /*[TSTRUCT]*/
1444 BUNION, /*[TUNION]*/