4 tindex(Type *tf, Type *tt)
37 for(i=0; i<NREG; i++) {
44 for(i=0; i<sizeof(regbase); i++)
46 for(i=0; i<NREG; i++) {
47 regbase[D_R0+i] = D_R0+i;
48 regbase[D_A0+i] = D_A0+i;
49 regbase[D_F0+i] = D_F0+i;
51 regbase[D_TOS] = D_TOS;
53 for(i=0; i<NTYPE; i++)
54 for(j=0; j<NTYPE; j++) {
59 if(!(typechlp[i] && typechlp[j]))
70 txtp->postext = AEXTBW;
73 txtp->postext = AEXTBL;
75 txtp->postext = AEXTWL;
87 for(i=0; i<ALLOP; i++)
88 for(j=0; j<NTYPE; j++)
90 oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
92 oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
93 oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
94 oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
95 oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
96 oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
97 oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
98 oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
99 oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
100 oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
101 oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
102 oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
103 oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
104 oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
105 oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
106 oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
107 oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
108 oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
109 oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
110 oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
111 oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
112 oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
113 oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
114 oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
115 oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
116 oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
117 oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
118 oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
119 oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
120 oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
121 oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
122 oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
123 oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
124 oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
125 oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
126 oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
127 oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
128 oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
129 oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
130 oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
131 oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
132 oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
133 oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
134 oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
135 oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
136 oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
137 oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
138 oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
139 oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
140 oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
152 tfield = types[TLONG];
156 zprog.from.type = D_NONE;
157 zprog.from.index = D_NONE;
158 zprog.to = zprog.from;
160 nodret = new(ONAME, Z, Z);
161 nodret->sym = slookup(".ret");
162 nodret->type = types[TIND];
163 nodret->etype = types[TIND]->etype;
164 nodret->class = CPARAM;
165 nodret = new(OIND, nodret, Z);
168 symrathole = slookup(".rathole");
169 symrathole->class = CGLOBL;
170 symrathole->type = typ(TARRAY, types[TCHAR]);
171 nodrat = new(ONAME, Z, Z);
172 nodrat->sym = symrathole;
173 nodrat->type = types[TIND];
174 nodrat->etype = TVOID;
175 nodrat->class = CGLOBL;
177 nodrat->type = symrathole->type;
181 symstatic = slookup(".static");
182 symstatic->class = CSTATIC;
183 symstatic->type = typ(TARRAY, types[TLONG]);
194 for(i=0; i<NREG; i++) {
196 diag(Z, "missing R%d", i);
198 diag(Z, "missing A%d", i);
200 diag(Z, "missing F%d", i);
205 symstring->type->width = nstring;
206 symstatic->type->width = nstatic;
207 symrathole->type->width = nrathole;
208 for(i=0; i<NHASH; i++)
209 for(s = hash[i]; s != S; s = s->link) {
212 if(s->type->width == 0)
214 if(s->class != CGLOBL && s->class != CSTATIC)
216 if(s->type == types[TENUM])
218 gpseudo(AGLOBL, s, D_CONST, s->type->width);
227 oinit(int o, int ab, int aw, int al, int af, int ad)
233 diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP);
237 opxt[i][TUCHAR] = ab;
238 opxt[i][TSHORT] = aw;
239 opxt[i][TUSHORT] = aw;
243 opxt[i][TULONG] = al;
245 opxt[i][TFLOAT] = af;
246 opxt[i][TDOUBLE] = ad;
254 p = alloc(sizeof(*p));
290 argoff = s + n->type->width;
294 naddr(Node *n, Adr *a, int x)
302 diag(n, "bad in naddr: %O", n->op);
307 naddr(n->left, a, x);
313 a->offset = n->xoffset;
321 a->offset = n->xoffset;
323 if(n->class == CSTATIC)
325 if(n->class == CEXTERN || n->class == CGLOBL) {
329 if(n->class == CAUTO) {
333 if(n->class == CPARAM) {
340 naddr(n->left, a, x);
341 switch(n->left->addable) {
346 a->index = x | I_INDEX1;
352 a->index = x | I_INDEX2;
360 if(typefd[n->type->etype]) {
366 a->offset = n->vconst;
371 if(l->addable == 20) {
373 naddr(n->right, a, x);
377 if(l->addable == 20) {
379 naddr(n->left, a, x);
403 a->index = D_NONE|I_INDEX3;
433 naddr(n->left, a, x);
439 regalloc(Type *t, int g)
445 if(typefd[t->etype]) {
446 if(g >= D_F0 && g < D_F0+NREG) {
450 for(g=0; g<NREG; g++)
451 if(fregused[g] == 0) {
456 if(g >= D_R0 && g < D_R0+NREG) {
460 for(g=0; g<NREG; g++)
461 if(regused[g] == 0) {
466 diag(Z, "out of registers");
474 if(g >= D_A0 && g < D_A0+NREG) {
478 for(g=0; g<NREG; g++)
479 if(aregused[g] == 0) {
483 diag(Z, "out of addr registers");
491 if(g >= D_R0+1 && g < D_R0+NREG)
492 if(!regused[g-D_R0-1]) {
497 if(g >= D_R0 && g < D_R0+NREG-1)
498 if(!regused[g-D_R0+1]) {
503 for(g = 0; g < NREG-1; g++)
510 diag(Z, "out of register pairs");
530 if(g == D_TOS || g == D_TREE || g == D_NONE)
532 if(g >= D_R0 && g < D_R0+NREG) {
536 if(g >= D_A0 && g < D_A0+NREG) {
540 if(g >= D_F0 && g < D_F0+NREG) {
544 diag(Z, "bad in regfree: %d", g);
548 gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
555 if(gf >= D_R0 && gf < D_R0+NREG)
556 if(txtp->preclr < 0) {
557 gmove(tt, tt, gf, f, gt, t);
560 g = regalloc(types[TLONG], gt);
562 g = regalloc(types[TLONG], D_NONE);
566 gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
567 gopcode(OAS, tf, gf, f, g, Z);
569 gopcode(OAS, tt, g, Z, gt, t);
575 if(gf >= D_R0 && gf < D_R0+NREG)
576 g = regalloc(types[TLONG], gf);
578 g = regalloc(types[TLONG], gt);
580 gopcode(OAS, tf, gf, f, g, Z);
587 gopcode(OAS, tt, g, Z, gt, t);
591 if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
592 (gf == D_TREE && gt == D_TREE && f == t))
594 if(typefd[tf->etype] || typefd[tt->etype]) {
595 if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
596 a = regalloc(types[TLONG], D_NONE);
597 gmove(tf, types[TLONG], gf, f, a, t);
598 if(tf->etype == TULONG) {
599 b = regalloc(types[TDOUBLE], D_NONE);
600 gmove(types[TLONG], tt, a, t, b, t);
601 gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
604 gopcode(OASADD, types[TDOUBLE],
605 D_CONST, nodconst(100), b, t);
606 p->from.dval = 4294967296.;
608 gmove(types[TDOUBLE], tt, b, t, gt, t);
611 gmove(types[TLONG], tt, a, t, gt, t);
615 if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
616 a = regalloc(types[TLONG], D_NONE);
617 gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
618 gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
620 if(gf < D_F0 || gf >= D_F0+NREG) {
621 g = regalloc(types[TDOUBLE], gt);
622 gopcode(OFAS, tf, gf, f, g, t);
624 gopcode(OFAS, tt, g, t, gt, t);
627 gopcode(OFAS, tt, gf, f, gt, t);
628 if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
629 gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
634 gopcode(OAS, tt, gf, f, gt, t);
638 gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
645 if(gf != D_TREE || f == t)
650 if(f->op == OINDEX) {
651 fidx = regalloc(types[TIND], fidx);
652 cgen(f->right, fidx, f->right);
657 if(t->op == OINDEX) {
659 tidx = regalloc(types[TIND], tidx);
660 cgen(t->right, tidx, t->right);
673 naddr(f, &p->from, fidx);
677 p->from.offset = (long)(uintptr)f;
679 p->from.type = D_FCONST;
680 p->from.dval = (long)(uintptr)f;
686 naddr(t, &p->to, tidx);
690 p->to.offset = (long)(uintptr)t;
693 p->from.field = f->type->nbits;
694 p->to.field = f->type->shift;
695 if(p->from.field == 0)
696 diag(Z, "BIT zero width bit field");
698 if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
703 diag(Z, "GOK in gopcode: %s", onames[o]);
723 if(p->from.type == D_CONST) {
726 p->from.type = D_NONE;
741 if(p->as == AMOVL && p->to.type == D_TOS && p->from.index == D_NONE)
742 switch(p->from.type) {
744 p->from.type |= I_INDIR;
746 p->from = zprog.from;
750 case I_ADDR|D_EXTERN:
751 case I_ADDR|D_STATIC:
752 p->from.type &= ~I_ADDR;
754 p->from = zprog.from;
764 if(p->as == AMOVL && p->from.type == D_CONST)
765 if(v >= -128 && v < 128)
766 if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
767 g = regalloc(types[TLONG], D_NONE);
788 case ORETURN: a = ARTS; break;
789 case OGOTO: a = ABRA; break;
790 case OEQ: a = ABEQ; break;
791 case ONE: a = ABNE; break;
792 case OLE: a = ABLE; break;
793 case OLS: a = ABLS; break;
794 case OLT: a = ABLT; break;
795 case OLO: a = ABCS; break;
796 case OGE: a = ABGE; break;
797 case OHS: a = ABCC; break;
798 case OGT: a = ABGT; break;
799 case OHI: a = ABHI; break;
800 case OBIT: a = ABCS; break;
801 case OCASE: a = ABCASE; break;
804 p->from.type = D_NONE;
816 case ABEQ: a = AFBEQ; break;
817 case ABNE: a = AFBNE; break;
818 case ABLE: a = AFBLE; break;
819 case ABLT: a = AFBLT; break;
820 case ABGE: a = AFBGE; break;
821 case ABGT: a = AFBGT; break;
827 patch(Prog *op, long pc)
831 op->to.type = D_BRANCH;
835 gpseudo(int a, Sym *s, int g, long v)
843 abort(); /* obsolete */
847 p->from.type = D_EXTERN;
848 if(s->class == CSTATIC)
849 p->from.type = D_STATIC;
853 gpseudotree(int a, Sym *s, Node *n)
859 naddr(n, &p->to, D_NONE);
861 p->from.type = D_EXTERN;
862 if(s->class == CSTATIC)
863 p->from.type = D_STATIC;
871 if(typechl[t->etype]) {
874 o = exregoffset + D_R0;
878 if(t->etype == TIND) {
879 if(exaregoffset <= 3)
881 o = exaregoffset + D_A0;
885 if(typefd[t->etype]) {
886 if(exfregoffset <= 5)
888 o = exfregoffset + D_F0;
895 schar ewidth[NTYPE] =
898 SZ_CHAR, /* [TCHAR] */
899 SZ_CHAR, /* [TUCHAR] */
900 SZ_SHORT, /* [TSHORT] */
901 SZ_SHORT, /* [TUSHORT] */
903 SZ_INT, /* [TUINT] */
904 SZ_LONG, /* [TLONG] */
905 SZ_LONG, /* [TULONG] */
906 SZ_VLONG, /* [TVLONG] */
907 SZ_VLONG, /* [TUVLONG] */
908 SZ_FLOAT, /* [TFLOAT] */
909 SZ_DOUBLE, /* [TDOUBLE] */
916 SZ_INT, /* [TENUM] */
921 BCHAR|BUCHAR, /* [TCHAR] */
922 BCHAR|BUCHAR, /* [TUCHAR] */
923 BSHORT|BUSHORT, /* [TSHORT] */
924 BSHORT|BUSHORT, /* [TUSHORT] */
925 BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
926 BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
927 BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
928 BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
929 BVLONG|BUVLONG, /* [TVLONG] */
930 BVLONG|BUVLONG, /* [TUVLONG] */
931 BFLOAT, /* [TFLOAT] */
932 BDOUBLE, /* [TDOUBLE] */
933 BLONG|BULONG|BIND, /* [TIND] */
937 BSTRUCT, /* [TSTRUCT] */
938 BUNION, /* [TUNION] */