4 swcmp(const void *a1, const void *a2)
12 return p1->val > p2->val;
16 doswit(int g, Node *n)
24 for(c = cases; c->link != C; c = c->link) {
27 diag(n, "more than one default in switch");
34 iq = alloc(nc*sizeof(C1));
36 for(c = cases; c->link != C; c = c->link) {
43 qsort(iq, nc, sizeof(C1), swcmp);
47 if(iq[i].val == iq[i+1].val)
48 diag(n, "duplicate cases in switch %ld", iq[i].val);
49 swit1(iq, nc, def, g, n);
52 #define N1 4 /* ncase: always linear */
53 #define N2 5 /* min ncase: direct */
54 #define N3 4 /* range/ncase: direct */
57 swit1(C1 *q, int nc, long def, int g, Node *n)
64 /* note that g and g+1 are not allocated */
67 y = 23*nc/100 + 5; /* number of cases needed to make */
68 if(y < N2) /* direct switch worthwile */
69 y = N2; /* try to do better than n**2 here */
70 for(m=nc; m>=y; m--) { /* m is number of cases */
73 for(l=nc-m; l>=0; l--) { /* l is base of contig cases */
75 range = s->val - r->val;
76 if(range > 0 && range <= N3*m)
89 if(v >= -128 && v < 128) {
90 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
91 gopcode(OEQ, n->type, g, n, g+1, n);
93 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
102 swit1(q, i, def, g, n);
105 swit1(r+1, nc-i-1, def, g, n);
109 /* compare low bound */
111 if(v >= -128 && v < 128) {
112 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
113 gopcode(OEQ, n->type, g, n, g+1, n);
115 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
119 /* compare high bound */
121 if(v >= -128 && v < 128) {
122 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
123 gopcode(OEQ, n->type, g, n, g+1, n);
125 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
131 gpseudo(AMOVW, symstatic, D_R0, 0L);
132 p->from.offset = nstatic - v*2;
133 p->from.index = g|I_INDEX1;
139 for(i=0; i<=range; i++) {
146 p->from.type = D_STATIC;
147 p->from.sym = symstatic;
148 p->from.offset = nstatic;
149 nstatic += types[TSHORT]->width;
155 print("smelly direct switch\n");
159 swit1(q, l, def, g, n);
166 swit1(q+m, nc-m, def, g, n);
173 for(i=0; i<nc; i++) {
175 if(v >= -128 && v < 128) {
176 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
177 gopcode(OEQ, n->type, g+1, n, g, n);
179 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
193 c = alloc(sizeof(*c));
200 bitload(Node *b, int n1, int n2, int n3, Node *nn)
208 * n1 gets adjusted/masked value
209 * n2 gets address of cell
210 * n3 gets contents of cell
220 gmove(t, t, n2, l, g, l);
221 gmove(t, t, g, l, n1, l);
224 if(b->type->shift == 0 && typeu[b->type->etype]) {
225 v = ~0 + (1L << b->type->nbits);
226 gopcode(OAND, t, D_CONST, nodconst(v), g, l);
228 sh = 32 - b->type->shift - b->type->nbits;
231 gs = regalloc(t, D_NONE);
232 gmove(t, t, D_CONST, nodconst(sh), gs, l);
233 gopcode(OASHL, t, gs, l, g, l);
237 gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
238 sh += b->type->shift;
242 gs = regalloc(t, D_NONE);
243 gmove(t, t, D_CONST, nodconst(sh), gs, l);
245 if(typeu[b->type->etype])
246 gopcode(OLSHR, t, gs, l, g, l);
248 gopcode(OASHR, t, gs, l, g, l);
251 if(typeu[b->type->etype])
252 gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l);
254 gopcode(OASHR, t, D_CONST, nodconst(sh), g, l);
262 bitstore(Node *b, int n1, int n2, int n3, int result, Node *nn)
270 * n1 has adjusted/masked value
271 * n2 has address of cell
272 * n3 has contents of cell
277 g = regalloc(t, D_NONE);
278 v = ~0 + (1L << b->type->nbits);
279 gopcode(OAND, t, D_CONST, nodconst(v), n1, l);
280 gmove(t, t, n1, l, g, l);
282 gmove(t, nn->type, n1, l, result, nn);
286 gs = regalloc(t, D_NONE);
287 gmove(t, t, D_CONST, nodconst(sh), gs, l);
288 gopcode(OASHL, t, gs, l, g, l);
291 gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
294 gopcode(OAND, t, D_CONST, nodconst(~v), n3, l);
295 gopcode(OOR, t, n3, l, g, l);
296 gmove(t, t, g, l, n2|I_INDIR, l);
305 outstring(char *s, long n)
311 string[mnstring] = *s++;
314 if(mnstring >= NSNAME) {
315 gpseudo(ADATA, symstring, D_SCONST, 0L);
316 memmove(p->to.sval, string, NSNAME);
317 p->from.offset = nstring - NSNAME;
318 p->from.displace = NSNAME;
327 outlstring(ushort *s, long n)
338 if(align(0, types[TCHAR], Aarg1)) {
352 doinc(Node *n, int f)
445 p->from.type = D_CONST;
456 p->from.type = D_CONST;
466 if(n->addable <= INDEXED)
479 if(n->addable >= INDEXED)
481 g = regalloc(n->type, g);
486 void outhist(Biobuf*);
487 void zname(Biobuf*, Sym*, int);
488 void zaddr(Biobuf*, Adr*, int);
489 void zwrite(Biobuf*, Prog*, int, int);
494 struct { Sym *sym; short type; } h[NSYM];
497 int f, sf, st, t, sym;
501 for(p = firstp; p != P; p = p->link)
502 if(p->as != ADATA && p->as != AGLOBL)
504 for(p = firstp; p != P; p = p->link) {
506 if(p->as != ADATA && p->as != AGLOBL)
510 f = open(outfile, OWRITE);
512 diag(Z, "cant open %s", outfile);
515 Binit(&b, f, OWRITE);
518 for(sym=0; sym<NSYM; sym++) {
523 for(p = firstp; p != P; p = p->link) {
529 if(sf < 0 || sf >= NSYM)
531 t = p->from.type & D_MASK;
549 if(st < 0 || st >= NSYM)
551 t = p->to.type & D_MASK;
567 zwrite(&b, p, sf, st);
576 zwrite(Biobuf *b, Prog *p, int sf, int st)
588 zaddr(b, &p->from, sf);
589 zaddr(b, &p->to, st);
593 zname(Biobuf *b, Sym *s, int t)
598 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
601 Bputc(b, ASIGNAME>>8);
609 Bputc(b, ANAME); /* as */
610 Bputc(b, ANAME>>8); /* as */
612 Bputc(b, t); /* type */
613 Bputc(b, s->sym); /* sym */
623 zaddr(Biobuf *b, Adr *a, int s)
633 if(a->index != D_NONE)
656 if(t & T_FIELD) { /* implies field */
661 if(t & T_INDEX) { /* implies index, scale, displace */
672 if(t & T_OFFSET) { /* implies offset */
679 if(t & T_SYM) /* implies sym */
682 ieeedtod(&e, a->dval);
697 for(i=0; i<NSNAME; i++) {
722 for(h = hist; h != H; h = h->link) {
725 /* on windows skip drive specifier in pathname */
726 if(systemtype(Windows) && p && p[1] == ':'){
730 if(p && p[0] != c && h->offset == 0 && pathname){
731 /* on windows skip drive specifier in pathname */
732 if(systemtype(Windows) && pathname[1] == ':') {
736 } else if(pathname[0] == c){
746 n = 1; /* leading "/" */
747 *p = '/'; /* don't emit "\" on windows */
770 pg.to.type = zprog.to.type;
771 pg.to.offset = h->offset;
773 pg.to.type = D_CONST;
775 zwrite(b, &pg, 0, 0);
780 ieeedtod(Ieee *ieee, double native)
786 ieeedtod(ieee, -native);
787 ieee->h |= 0x80000000L;
795 fr = frexp(native, &exp);
796 f = 2097152L; /* shouldnt use fp constants here */
797 fr = modf(fr*f, &ho);
800 ieee->h |= (exp+1022L) << 20;
802 fr = modf(fr*f, &ho);
805 ieee->l |= (long)(fr*f);
809 nodalloc(Type *t, int g, Node *n)
817 n->reg = g | I_INDIR;
823 mulcon(Node *n, Node *c, int result, Node *nn)
827 if(typefd[n->type->etype])
830 if(mulcon1(n, v, result, nn))
836 shlcon(Node *n, Node *c, int result, Node *nn)
841 return mulcon1(n, v, result, nn);
845 mulcon1(Node *n, long v, int result, Node *nn)
847 int g, g1, a1, a2, neg;
864 if(v < multab[g1].val) {
868 if(v > multab[g1].val) {
875 strncat(code, multab[g1].code, sizeof(multab[0].code));
879 g = regalloc(n->type, result);
882 gopcode(ONEG, n->type, D_NONE, n, g, n);
883 g1 = regalloc(n->type, D_NONE);
888 gmove(n->type, nn->type, g, n, result, nn);
908 if(*p == 1 || *p == 3)
911 if(*p == 0 || *p == 3)
913 gopcode(o, n->type, a1, n, a2, n);
923 gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n);
930 nullwarn(Node *l, Node *r)
932 warn(Z, "result of operation not used");
940 sextern(Sym *s, Node *a, long o, long w)
944 for(e=0; e<w; e+=NSNAME) {
948 gpseudo(ADATA, s, D_SCONST, 0L);
949 p->from.offset += o+e;
950 p->from.displace = lw;
951 memmove(p->to.sval, a->cstring+e, lw);
956 gextern(Sym *s, Node *a, long o, long w)
958 if(a->op == OCONST && typev[a->type->etype]) {
959 gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32));
961 p->from.displace = 4;
962 gpseudo(ADATA, s, D_CONST, (long)(a->vconst));
963 p->from.offset += o + 4;
964 p->from.displace = 4;
967 gpseudotree(ADATA, s, a);
969 p->from.displace = w;
973 align(long i, Type *t, int op)
983 diag(Z, "unknown align opcode %d", op);
986 case Asu2: /* padding at end of a struct */
992 case Ael1: /* initial allign of struct element */
993 for(v=t; v->etype==TARRAY; v=v->link)
995 w = ewidth[v->etype];
996 if(w <= 0 || w >= SZ_SHORT)
1002 case Ael2: /* width of a struct element */
1006 case Aarg0: /* initial passbyptr argument in arg list */
1007 if(typesuv[t->etype]) {
1008 o = align(o, types[TIND], Aarg1);
1009 o = align(o, types[TIND], Aarg2);
1013 case Aarg1: /* initial allign of parameter */
1014 w = ewidth[t->etype];
1015 if(w <= 0 || w >= SZ_LONG) {
1019 o += SZ_LONG - w; /* big endian adjustment */
1023 case Aarg2: /* width of a parameter */
1028 case Aaut3: /* total allign of automatic */
1029 o = align(o, t, Ael1);
1030 o = align(o, t, Ael2);
1035 print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
1040 maxround(long max, long v)
1044 max = round(v, SZ_LONG);