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 %lld", 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)
313 string[mnstring] = *s++;
316 if(mnstring >= NSNAME) {
317 gpseudo(ADATA, symstring, D_SCONST, 0L);
318 memmove(p->to.sval, string, NSNAME);
319 p->from.offset = nstring - NSNAME;
320 p->from.displace = NSNAME;
329 outlstring(Rune *s, long n)
331 char buf[sizeof(Rune)];
335 while(nstring % sizeof buf)
340 if(align(0, types[TCHAR], Aarg1)) {
341 for(i = sizeof buf; i > 0; c >>= 8)
344 for(i = 0; i < sizeof buf; c >>= 8)
347 outstring(buf, sizeof buf);
354 doinc(Node *n, int f)
447 p->from.type = D_CONST;
458 p->from.type = D_CONST;
468 if(n->addable <= INDEXED)
481 if(n->addable >= INDEXED)
483 g = regalloc(n->type, g);
488 void outhist(Biobuf*);
489 void zname(Biobuf*, Sym*, int);
490 void zaddr(Biobuf*, Adr*, int);
491 void zwrite(Biobuf*, Prog*, int, int);
496 struct { Sym *sym; short type; } h[NSYM];
499 int f, sf, st, t, sym;
503 for(p = firstp; p != P; p = p->link)
504 if(p->as != ADATA && p->as != AGLOBL)
506 for(p = firstp; p != P; p = p->link) {
508 if(p->as != ADATA && p->as != AGLOBL)
512 f = open(outfile, OWRITE);
514 diag(Z, "cant open %s", outfile);
517 Binit(&b, f, OWRITE);
520 for(sym=0; sym<NSYM; sym++) {
525 for(p = firstp; p != P; p = p->link) {
531 if(sf < 0 || sf >= NSYM)
533 t = p->from.type & D_MASK;
551 if(st < 0 || st >= NSYM)
553 t = p->to.type & D_MASK;
569 zwrite(&b, p, sf, st);
578 zwrite(Biobuf *b, Prog *p, int sf, int st)
590 zaddr(b, &p->from, sf);
591 zaddr(b, &p->to, st);
595 zname(Biobuf *b, Sym *s, int t)
600 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
603 Bputc(b, ASIGNAME>>8);
611 Bputc(b, ANAME); /* as */
612 Bputc(b, ANAME>>8); /* as */
614 Bputc(b, t); /* type */
615 Bputc(b, s->sym); /* sym */
625 zaddr(Biobuf *b, Adr *a, int s)
635 if(a->index != D_NONE)
658 if(t & T_FIELD) { /* implies field */
663 if(t & T_INDEX) { /* implies index, scale, displace */
674 if(t & T_OFFSET) { /* implies offset */
681 if(t & T_SYM) /* implies sym */
684 ieeedtod(&e, a->dval);
699 for(i=0; i<NSNAME; i++) {
724 for(h = hist; h != H; h = h->link) {
727 /* on windows skip drive specifier in pathname */
728 if(systemtype(Windows) && p && p[1] == ':'){
732 if(p && p[0] != c && h->offset == 0 && pathname){
733 /* on windows skip drive specifier in pathname */
734 if(systemtype(Windows) && pathname[1] == ':') {
738 } else if(pathname[0] == c){
748 n = 1; /* leading "/" */
749 *p = '/'; /* don't emit "\" on windows */
772 pg.to.type = zprog.to.type;
773 pg.to.offset = h->offset;
775 pg.to.type = D_CONST;
777 zwrite(b, &pg, 0, 0);
782 ieeedtod(Ieee *ieee, double native)
788 ieeedtod(ieee, -native);
789 ieee->h |= 0x80000000L;
797 fr = frexp(native, &exp);
798 f = 2097152L; /* shouldnt use fp constants here */
799 fr = modf(fr*f, &ho);
802 ieee->h |= (exp+1022L) << 20;
804 fr = modf(fr*f, &ho);
807 ieee->l |= (long)(fr*f);
811 nodalloc(Type *t, int g, Node *n)
819 n->reg = g | I_INDIR;
825 mulcon(Node *n, Node *c, int result, Node *nn)
829 if(typefd[n->type->etype])
832 if(mulcon1(n, v, result, nn))
838 shlcon(Node *n, Node *c, int result, Node *nn)
843 return mulcon1(n, v, result, nn);
847 mulcon1(Node *n, long v, int result, Node *nn)
849 int g, g1, a1, a2, neg;
866 if(v < multab[g1].val) {
870 if(v > multab[g1].val) {
877 strncat(code, multab[g1].code, sizeof(multab[0].code));
881 g = regalloc(n->type, result);
884 gopcode(ONEG, n->type, D_NONE, n, g, n);
885 g1 = regalloc(n->type, D_NONE);
890 gmove(n->type, nn->type, g, n, result, nn);
910 if(*p == 1 || *p == 3)
913 if(*p == 0 || *p == 3)
915 gopcode(o, n->type, a1, n, a2, n);
925 gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n);
932 nullwarn(Node *l, Node *r)
934 warn(Z, "result of operation not used");
942 sextern(Sym *s, Node *a, long o, long w)
946 for(e=0; e<w; e+=NSNAME) {
950 gpseudo(ADATA, s, D_SCONST, 0L);
951 p->from.offset += o+e;
952 p->from.displace = lw;
953 memmove(p->to.sval, a->cstring+e, lw);
958 gextern(Sym *s, Node *a, long o, long w)
960 if(a->op == OCONST && typev[a->type->etype]) {
961 gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32));
963 p->from.displace = 4;
964 gpseudo(ADATA, s, D_CONST, (long)(a->vconst));
965 p->from.offset += o + 4;
966 p->from.displace = 4;
969 gpseudotree(ADATA, s, a);
971 p->from.displace = w;
975 align(long i, Type *t, int op)
985 diag(Z, "unknown align opcode %d", op);
988 case Asu2: /* padding at end of a struct */
994 case Ael1: /* initial allign of struct element */
995 for(v=t; v->etype==TARRAY; v=v->link)
997 w = ewidth[v->etype];
998 if(w <= 0 || w >= SZ_SHORT)
1004 case Ael2: /* width of a struct element */
1008 case Aarg0: /* initial passbyptr argument in arg list */
1009 if(typesuv[t->etype]) {
1010 o = align(o, types[TIND], Aarg1);
1011 o = align(o, types[TIND], Aarg2);
1015 case Aarg1: /* initial allign of parameter */
1016 w = ewidth[t->etype];
1017 if(w <= 0 || w >= SZ_LONG) {
1021 o += SZ_LONG - w; /* big endian adjustment */
1025 case Aarg2: /* width of a parameter */
1030 case Aaut3: /* total allign of automatic */
1031 o = align(o, t, Ael1);
1032 o = align(o, t, Ael2);
1037 print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
1042 maxround(long max, long v)
1046 max = round(v, SZ_LONG);