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");
324 n->complex = 0; /* already in registers */
328 n->left = alloc(sizeof(Node));
329 n->right = alloc(sizeof(Node));
330 if(o != Z && o->op == OREGPAIR) {
331 regalloc(n->left, ®node, o->left);
332 regalloc(n->right, ®node, o->right);
334 regalloc(n->left, ®node, Z);
335 regalloc(n->right, ®node, Z);
337 n->right->type = types[TULONG];
338 if(tn->type->etype == TUVLONG)
339 n->left->type = types[TULONG];
342 diag(tn, "unknown type in regalloc: %T", tn->type);
349 //print("+ %R %d\n", i, reg[i]);
353 regialloc(Node *n, Node *tn, Node *o)
358 nod.type = types[TIND];
359 regalloc(n, &nod, o);
367 if(n->op == OREGPAIR) {
374 if(n->op != OREGISTER && n->op != OINDREG)
377 if(i < 0 || i >= sizeof(reg))
382 //print("- %R %d\n", i, reg[i]);
385 diag(n, "error in regfree: %R", i);
389 regsalloc(Node *n, Node *nn)
391 cursafe = align(cursafe, nn->type, Aaut3);
392 maxargsafe = maxround(maxargsafe, cursafe+curarg);
394 n->xoffset = -(stkoff + cursafe);
396 n->etype = nn->type->etype;
397 n->lineno = nn->lineno;
401 regaalloc1(Node *n, Node *nn)
406 diag(n, "regaalloc1");
410 nodreg(n, nn, REGARG);
412 curarg = align(curarg, nn->type, Aarg1);
413 curarg = align(curarg, nn->type, Aarg2);
414 maxargsafe = maxround(maxargsafe, cursafe+curarg);
419 regaalloc(Node *n, Node *nn)
421 curarg = align(curarg, nn->type, Aarg1);
428 curarg = align(curarg, nn->type, Aarg2);
429 maxargsafe = maxround(maxargsafe, cursafe+curarg);
433 regind(Node *n, Node *nn)
436 if(n->op != OREGISTER) {
437 diag(n, "regind not OREGISTER");
445 naddr(Node *n, Adr *a)
455 diag(n, "bad in naddr: %O %D", n->op, a);
456 //prtree(n, "naddr");
465 a->type = D_INDIR + D_GS;
466 a->offset = n->reg - 1;
472 if(a->type >= D_AX && a->type <= D_DI)
475 if(a->type == D_CONST)
476 a->type = D_NONE+D_INDIR;
478 if(a->type == D_ADDR) {
487 if(n->left->op == OADDR || n->left->op == OCONST)
489 if(a->type >= D_AX && a->type <= D_DI)
492 if(a->type == D_CONST)
493 a->type = D_NONE+D_INDIR;
495 if(a->type == D_ADDR) {
502 a->offset += n->xoffset;
506 a->type = n->reg+D_INDIR;
508 a->offset = n->xoffset;
515 a->offset = n->xoffset;
516 if(n->class == CSTATIC)
518 if(n->class == CEXTERN || n->class == CGLOBL) {
522 if(n->class == CAUTO) {
526 if(n->class == CPARAM) {
533 if(typefd[n->type->etype]) {
540 a->offset = n->vconst;
545 if(a->type >= D_INDIR) {
549 if(a->type == D_EXTERN || a->type == D_STATIC ||
550 a->type == D_AUTO || a->type == D_PARAM)
551 if(a->index == D_NONE) {
559 if(n->right->op == OCONST) {
560 v = n->right->vconst;
563 if(n->left->op == OCONST) {
574 #define CASE(a,b) ((a<<8)|(b<<0))
577 gmove(Node *f, Node *t)
586 print("gop: %O %O[%s],%O[%s]\n", OAS,
587 f->op, tnames[ft], t->op, tnames[tt]);
588 if(typefd[ft] && f->op == OCONST) {
595 gins(AFMOVD, f, &fregnode0);
596 gmove(&fregnode0, t);
602 if(f->op == ONAME || f->op == OINDREG ||
603 f->op == OIND || f->op == OINDEX)
613 gins(AFMOVW, f, &fregnode0);
614 gmove(&fregnode0, t);
625 gins(AFMOVL, f, &fregnode0);
626 gmove(&fregnode0, t);
634 regalloc(&nod, f, t);
651 if(t->op == ONAME || t->op == OINDREG ||
652 t->op == OIND || t->op == OINDEX)
668 if(f->op == OCONST) {
672 regalloc(&nod, t, f);
689 switch(CASE(ft,tt)) {
696 case CASE( TCHAR, TCHAR):
697 case CASE( TUCHAR, TCHAR):
698 case CASE( TSHORT, TCHAR):
699 case CASE( TUSHORT,TCHAR):
700 case CASE( TINT, TCHAR):
701 case CASE( TUINT, TCHAR):
702 case CASE( TLONG, TCHAR):
703 case CASE( TULONG, TCHAR):
704 case CASE( TIND, TCHAR):
706 case CASE( TCHAR, TUCHAR):
707 case CASE( TUCHAR, TUCHAR):
708 case CASE( TSHORT, TUCHAR):
709 case CASE( TUSHORT,TUCHAR):
710 case CASE( TINT, TUCHAR):
711 case CASE( TUINT, TUCHAR):
712 case CASE( TLONG, TUCHAR):
713 case CASE( TULONG, TUCHAR):
714 case CASE( TIND, TUCHAR):
716 case CASE( TSHORT, TSHORT):
717 case CASE( TUSHORT,TSHORT):
718 case CASE( TINT, TSHORT):
719 case CASE( TUINT, TSHORT):
720 case CASE( TLONG, TSHORT):
721 case CASE( TULONG, TSHORT):
722 case CASE( TIND, TSHORT):
724 case CASE( TSHORT, TUSHORT):
725 case CASE( TUSHORT,TUSHORT):
726 case CASE( TINT, TUSHORT):
727 case CASE( TUINT, TUSHORT):
728 case CASE( TLONG, TUSHORT):
729 case CASE( TULONG, TUSHORT):
730 case CASE( TIND, TUSHORT):
732 case CASE( TINT, TINT):
733 case CASE( TUINT, TINT):
734 case CASE( TLONG, TINT):
735 case CASE( TULONG, TINT):
736 case CASE( TIND, TINT):
738 case CASE( TINT, TUINT):
739 case CASE( TUINT, TUINT):
740 case CASE( TLONG, TUINT):
741 case CASE( TULONG, TUINT):
742 case CASE( TIND, TUINT):
744 case CASE( TINT, TLONG):
745 case CASE( TUINT, TLONG):
746 case CASE( TLONG, TLONG):
747 case CASE( TULONG, TLONG):
748 case CASE( TIND, TLONG):
750 case CASE( TINT, TULONG):
751 case CASE( TUINT, TULONG):
752 case CASE( TLONG, TULONG):
753 case CASE( TULONG, TULONG):
754 case CASE( TIND, TULONG):
756 case CASE( TINT, TIND):
757 case CASE( TUINT, TIND):
758 case CASE( TLONG, TIND):
759 case CASE( TULONG, TIND):
760 case CASE( TIND, TIND):
765 case CASE( TSHORT, TINT):
766 case CASE( TSHORT, TUINT):
767 case CASE( TSHORT, TLONG):
768 case CASE( TSHORT, TULONG):
769 case CASE( TSHORT, TIND):
771 if(f->op == OCONST) {
773 if(f->vconst & 0x8000)
774 f->vconst |= 0xffff0000;
779 case CASE( TUSHORT,TINT):
780 case CASE( TUSHORT,TUINT):
781 case CASE( TUSHORT,TLONG):
782 case CASE( TUSHORT,TULONG):
783 case CASE( TUSHORT,TIND):
785 if(f->op == OCONST) {
791 case CASE( TCHAR, TSHORT):
792 case CASE( TCHAR, TUSHORT):
793 case CASE( TCHAR, TINT):
794 case CASE( TCHAR, TUINT):
795 case CASE( TCHAR, TLONG):
796 case CASE( TCHAR, TULONG):
797 case CASE( TCHAR, TIND):
799 if(f->op == OCONST) {
802 f->vconst |= 0xffffff00;
807 case CASE( TUCHAR, TSHORT):
808 case CASE( TUCHAR, TUSHORT):
809 case CASE( TUCHAR, TINT):
810 case CASE( TUCHAR, TUINT):
811 case CASE( TUCHAR, TLONG):
812 case CASE( TUCHAR, TULONG):
813 case CASE( TUCHAR, TIND):
815 if(f->op == OCONST) {
824 case CASE( TFLOAT, TCHAR):
825 case CASE( TFLOAT, TUCHAR):
826 case CASE( TFLOAT, TSHORT):
827 case CASE( TFLOAT, TUSHORT):
828 case CASE( TFLOAT, TINT):
829 case CASE( TFLOAT, TLONG):
830 case CASE( TFLOAT, TIND):
832 case CASE( TDOUBLE,TCHAR):
833 case CASE( TDOUBLE,TUCHAR):
834 case CASE( TDOUBLE,TSHORT):
835 case CASE( TDOUBLE,TUSHORT):
836 case CASE( TDOUBLE,TINT):
837 case CASE( TDOUBLE,TLONG):
838 case CASE( TDOUBLE,TIND):
840 regsalloc(&nod, ®node);
841 gins(AFMOVLP, f, &nod);
845 regsalloc(&nod, ®node);
846 regsalloc(&nod1, ®node);
847 gins(AFSTCW, Z, &nod1);
849 gins(AMOVW, nodconst(0xf7f), &nod1);
850 gins(AFLDCW, &nod1, Z);
851 gins(AFMOVLP, f, &nod);
853 gins(AFLDCW, &nod1, Z);
860 case CASE( TDOUBLE, TULONG):
861 case CASE( TFLOAT, TULONG):
862 case CASE( TDOUBLE, TUINT):
863 case CASE( TFLOAT, TUINT):
864 regsalloc(&nod, ®node);
865 gmove(f, &fregnode0);
866 gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
867 gins(AFMOVLP, f, &nod);
868 gins(ASUBL, nodconst(-2147483648), &nod);
875 case CASE( TULONG, TDOUBLE):
876 case CASE( TULONG, TFLOAT):
877 case CASE( TUINT, TDOUBLE):
878 case CASE( TUINT, TFLOAT):
879 regalloc(&nod, f, f);
881 regsalloc(&nod1, ®node);
883 gins(AFMOVL, &nod1, &fregnode0);
884 gins(ACMPL, &nod, nodconst(0));
887 gins(AFADDD, nodfconst(4294967296.), &fregnode0);
895 case CASE( TCHAR, TFLOAT):
896 case CASE( TUCHAR, TFLOAT):
897 case CASE( TSHORT, TFLOAT):
898 case CASE( TUSHORT,TFLOAT):
899 case CASE( TINT, TFLOAT):
900 case CASE( TLONG, TFLOAT):
901 case CASE( TIND, TFLOAT):
903 case CASE( TCHAR, TDOUBLE):
904 case CASE( TUCHAR, TDOUBLE):
905 case CASE( TSHORT, TDOUBLE):
906 case CASE( TUSHORT,TDOUBLE):
907 case CASE( TINT, TDOUBLE):
908 case CASE( TLONG, TDOUBLE):
909 case CASE( TIND, TDOUBLE):
910 regsalloc(&nod, ®node);
912 gins(AFMOVL, &nod, &fregnode0);
918 case CASE( TFLOAT, TFLOAT):
919 case CASE( TDOUBLE,TFLOAT):
921 case CASE( TFLOAT, TDOUBLE):
922 case CASE( TDOUBLE,TDOUBLE):
925 if(a == AMOVL || a == AFMOVD)
940 if(n->left->complex >= FNX)
941 print("botch in doindex\n");
943 regalloc(&nod, ®node, Z);
944 v = constnode.vconst;
945 cgen(n->right, &nod);
947 if(n->left->op == OCONST)
949 else if(n->left->op == OREGISTER)
950 // else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
951 idx.ptr = n->left->reg;
952 else if(n->left->op != OADDR) {
953 reg[D_BP]++; // cant be used as a base
954 regalloc(&nod1, ®node, Z);
955 cgen(n->left, &nod1);
962 constnode.vconst = v;
966 gins(int a, Node *f, Node *t)
969 if(f != Z && f->op == OINDEX)
971 if(t != Z && t->op == OINDEX)
984 fgopcode(int o, Node *f, Node *t, int pop, int rev)
990 if(f != Z && f->type != T)
993 diag(f, "fop: integer %O", o);
997 if(t != Z && t->type != T)
998 print("gop: %O %O-%s Z\n", o, f->op, tnames[et]);
1000 print("gop: %O %O-%s %O-%s\n", o,
1001 f->op, tnames[et], t->op, tnames[t->type->etype]);
1094 regalloc(&nod, ®node, Z);
1095 if(nod.reg != D_AX) {
1098 gins(APUSHL, &nod, Z);
1100 gins(AFSTSW, Z, &nod);
1102 gins(APOPL, Z, &nod);
1105 gins(AFSTSW, Z, &nod);
1110 case OEQ: a = AJEQ; break;
1111 case ONE: a = AJNE; break;
1112 case OLT: a = AJCS; break;
1113 case OLE: a = AJLS; break;
1114 case OGE: a = AJCC; break;
1115 case OGT: a = AJHI; break;
1121 diag(Z, "bad in gopcode %O", o);
1126 gopcode(int o, Type *ty, Node *f, Node *t)
1133 if(typefd[et] && o != OADDR && o != OFUNC) {
1134 diag(f, "gop: float %O", o);
1138 if(f != Z && f->type != T)
1139 print("gop: %O %O[%s],", o, f->op, tnames[et]);
1141 print("gop: %O Z,", o);
1142 if(t != Z && t->type != T)
1143 print("%O[%s]\n", t->op, tnames[t->type->etype]);
1151 if(et == TCHAR || et == TUCHAR)
1153 if(et == TSHORT || et == TUSHORT)
1159 if(et == TCHAR || et == TUCHAR)
1161 if(et == TSHORT || et == TUSHORT)
1172 if(et == TCHAR || et == TUCHAR)
1174 if(et == TSHORT || et == TUSHORT)
1181 if(et == TCHAR || et == TUCHAR)
1183 if(et == TSHORT || et == TUSHORT)
1190 if(et == TCHAR || et == TUCHAR)
1192 if(et == TSHORT || et == TUSHORT)
1199 if(et == TCHAR || et == TUCHAR)
1201 if(et == TSHORT || et == TUSHORT)
1208 if(et == TCHAR || et == TUCHAR)
1210 if(et == TSHORT || et == TUSHORT)
1217 if(et == TCHAR || et == TUCHAR)
1219 if(et == TSHORT || et == TUSHORT)
1226 if(et == TCHAR || et == TUCHAR)
1228 if(et == TSHORT || et == TUSHORT)
1235 if(et == TCHAR || et == TUCHAR)
1237 if(et == TSHORT || et == TUSHORT)
1243 if(et == TCHAR || et == TUCHAR)
1245 if(et == TSHORT || et == TUSHORT)
1255 if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1290 if(et == TCHAR || et == TUCHAR)
1292 if(et == TSHORT || et == TUSHORT)
1296 case OEQ: a = AJEQ; break;
1297 case ONE: a = AJNE; break;
1298 case OLT: a = AJLT; break;
1299 case OLE: a = AJLE; break;
1300 case OGE: a = AJGE; break;
1301 case OGT: a = AJGT; break;
1302 case OLO: a = AJCS; break;
1303 case OLS: a = AJLS; break;
1304 case OHS: a = AJCC; break;
1305 case OHI: a = AJHI; break;
1311 diag(Z, "bad in gopcode %O", o);
1316 samaddr(Node *f, Node *t)
1324 if(f->reg != t->reg)
1347 diag(Z, "bad in gbranch %O", o);
1354 patch(Prog *op, long pc)
1358 op->to.type = D_BRANCH;
1362 gpseudo(int a, Sym *s, Node *n)
1367 p->from.type = D_EXTERN;
1369 p->from.scale = (profileflg ? 0 : NOPROF);
1370 if(s->class == CSTATIC)
1371 p->from.type = D_STATIC;
1373 if(a == ADATA || a == AGLOBL)
1382 if(n->op == OCONST && !typefd[n->type->etype]) {
1384 if(v >= -32766L && v < 32766L)
1396 if(typechlp[t->etype]){
1397 if(exregoffset >= 32)
1401 return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
1406 schar ewidth[NTYPE] =
1409 SZ_CHAR, /*[TCHAR]*/
1410 SZ_CHAR, /*[TUCHAR]*/
1411 SZ_SHORT, /*[TSHORT]*/
1412 SZ_SHORT, /*[TUSHORT]*/
1415 SZ_LONG, /*[TLONG]*/
1416 SZ_LONG, /*[TULONG]*/
1417 SZ_VLONG, /*[TVLONG]*/
1418 SZ_VLONG, /*[TUVLONG]*/
1419 SZ_FLOAT, /*[TFLOAT]*/
1420 SZ_DOUBLE, /*[TDOUBLE]*/
1432 BCHAR|BUCHAR, /*[TCHAR]*/
1433 BCHAR|BUCHAR, /*[TUCHAR]*/
1434 BSHORT|BUSHORT, /*[TSHORT]*/
1435 BSHORT|BUSHORT, /*[TUSHORT]*/
1436 BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/
1437 BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/
1438 BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/
1439 BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/
1440 BVLONG|BUVLONG, /*[TVLONG]*/
1441 BVLONG|BUVLONG, /*[TUVLONG]*/
1442 BFLOAT, /*[TFLOAT]*/
1443 BDOUBLE, /*[TDOUBLE]*/
1444 BLONG|BULONG|BIND, /*[TIND]*/
1448 BSTRUCT, /*[TSTRUCT]*/
1449 BUNION, /*[TUNION]*/