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 */
55 swit1(C1 *q, int nc, long def, int g, Node *n)
62 /* note that g and g+1 are not allocated */
73 if(v >= -128 && v < 128) {
74 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
75 gopcode(OEQ, n->type, g, n, g+1, n);
77 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
86 swit1(q, i, def, g, n);
89 swit1(r+1, nc-i-1, def, g, n);
95 if(v >= -128 && v < 128) {
96 gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
97 gopcode(OEQ, n->type, g+1, n, g, n);
99 gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
113 c = alloc(sizeof(*c));
120 bitload(Node *b, int n1, int n2, int n3, Node *nn)
128 * n1 gets adjusted/masked value
129 * n2 gets address of cell
130 * n3 gets contents of cell
140 gmove(t, t, n2, l, g, l);
141 gmove(t, t, g, l, n1, l);
144 if(b->type->shift == 0 && typeu[b->type->etype]) {
145 v = ~0 + (1L << b->type->nbits);
146 gopcode(OAND, t, D_CONST, nodconst(v), g, l);
148 sh = 32 - b->type->shift - b->type->nbits;
151 gs = regalloc(t, D_NONE);
152 gmove(t, t, D_CONST, nodconst(sh), gs, l);
153 gopcode(OASHL, t, gs, l, g, l);
157 gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
158 sh += b->type->shift;
162 gs = regalloc(t, D_NONE);
163 gmove(t, t, D_CONST, nodconst(sh), gs, l);
165 if(typeu[b->type->etype])
166 gopcode(OLSHR, t, gs, l, g, l);
168 gopcode(OASHR, t, gs, l, g, l);
171 if(typeu[b->type->etype])
172 gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l);
174 gopcode(OASHR, t, D_CONST, nodconst(sh), g, l);
182 bitstore(Node *b, int n1, int n2, int n3, int result, Node *nn)
190 * n1 has adjusted/masked value
191 * n2 has address of cell
192 * n3 has contents of cell
197 g = regalloc(t, D_NONE);
198 v = ~0 + (1L << b->type->nbits);
199 gopcode(OAND, t, D_CONST, nodconst(v), n1, l);
200 gmove(t, t, n1, l, g, l);
202 gmove(t, nn->type, n1, l, result, nn);
206 gs = regalloc(t, D_NONE);
207 gmove(t, t, D_CONST, nodconst(sh), gs, l);
208 gopcode(OASHL, t, gs, l, g, l);
211 gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);
214 gopcode(OAND, t, D_CONST, nodconst(~v), n3, l);
215 gopcode(OOR, t, n3, l, g, l);
216 gmove(t, t, g, l, n2|I_INDIR, l);
225 outstring(char *s, long n)
233 string[mnstring] = *s++;
236 if(mnstring >= NSNAME) {
237 gpseudo(ADATA, symstring, D_SCONST, 0L);
238 memmove(p->to.sval, string, NSNAME);
239 p->from.offset = nstring - NSNAME;
240 p->from.displace = NSNAME;
249 outlstring(Rune *s, long n)
251 char buf[sizeof(Rune)];
255 while(nstring % sizeof buf)
260 if(align(0, types[TCHAR], Aarg1)) {
261 for(i = sizeof buf; i > 0; c >>= 8)
264 for(i = 0; i < sizeof buf; c >>= 8)
267 outstring(buf, sizeof buf);
274 doinc(Node *n, int f)
367 p->from.type = D_CONST;
378 p->from.type = D_CONST;
388 if(n->addable <= INDEXED)
401 if(n->addable >= INDEXED)
403 g = regalloc(n->type, g);
408 void outhist(Biobuf*);
409 void zname(Biobuf*, Sym*, int);
410 void zaddr(Biobuf*, Adr*, int);
411 void zwrite(Biobuf*, Prog*, int, int);
416 struct { Sym *sym; short type; } h[NSYM];
419 int f, sf, st, t, sym;
423 for(p = firstp; p != P; p = p->link)
424 if(p->as != ADATA && p->as != AGLOBL)
426 for(p = firstp; p != P; p = p->link) {
428 if(p->as != ADATA && p->as != AGLOBL)
432 f = open(outfile, OWRITE);
434 diag(Z, "cant open %s", outfile);
437 Binit(&b, f, OWRITE);
440 for(sym=0; sym<NSYM; sym++) {
445 for(p = firstp; p != P; p = p->link) {
451 if(sf < 0 || sf >= NSYM)
453 t = p->from.type & D_MASK;
471 if(st < 0 || st >= NSYM)
473 t = p->to.type & D_MASK;
489 zwrite(&b, p, sf, st);
498 zwrite(Biobuf *b, Prog *p, int sf, int st)
510 zaddr(b, &p->from, sf);
511 zaddr(b, &p->to, st);
515 zname(Biobuf *b, Sym *s, int t)
520 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
523 Bputc(b, ASIGNAME>>8);
531 Bputc(b, ANAME); /* as */
532 Bputc(b, ANAME>>8); /* as */
534 Bputc(b, t); /* type */
535 Bputc(b, s->sym); /* sym */
545 zaddr(Biobuf *b, Adr *a, int s)
576 if(t & T_FIELD) { /* implies field */
581 if(t & T_INDEX) { /* implies index, scale, displace */
592 if(t & T_OFFSET) { /* implies offset */
599 if(t & T_SYM) /* implies sym */
602 ieeedtod(&e, a->dval);
617 for(i=0; i<NSNAME; i++) {
642 for(h = hist; h != H; h = h->link) {
645 /* on windows skip drive specifier in pathname */
646 if(systemtype(Windows) && p && p[1] == ':'){
650 if(p && p[0] != c && h->offset == 0 && pathname){
651 /* on windows skip drive specifier in pathname */
652 if(systemtype(Windows) && pathname[1] == ':') {
656 } else if(pathname[0] == c){
666 n = 1; /* leading "/" */
667 *p = '/'; /* don't emit "\" on windows */
690 pg.to.type = zprog.to.type;
691 pg.to.offset = h->offset;
693 pg.to.type = D_CONST;
695 zwrite(b, &pg, 0, 0);
700 ieeedtod(Ieee *ieee, double native)
706 ieeedtod(ieee, -native);
707 ieee->h |= 0x80000000L;
715 fr = frexp(native, &exp);
716 f = 2097152L; /* shouldnt use fp constants here */
717 fr = modf(fr*f, &ho);
720 ieee->h |= (exp+1022L) << 20;
722 fr = modf(fr*f, &ho);
725 ieee->l |= (long)(fr*f);
729 nodalloc(Type *t, int g, Node *n)
737 n->reg = g | I_INDIR;
743 mulcon(Node *n, Node *c, int result, Node *nn)
747 if(typefd[n->type->etype])
750 if(mulcon1(n, v, result, nn))
756 shlcon(Node *n, Node *c, int result, Node *nn)
761 return mulcon1(n, v, result, nn);
765 mulcon1(Node *n, long v, int result, Node *nn)
767 int g, g1, a1, a2, neg;
784 if(v < multab[g1].val) {
788 if(v > multab[g1].val) {
795 strncat(code, multab[g1].code, sizeof(multab[0].code));
799 g = regalloc(n->type, result);
802 gopcode(ONEG, n->type, D_NONE, n, g, n);
803 g1 = regalloc(n->type, D_NONE);
808 gmove(n->type, nn->type, g, n, result, nn);
828 if(*p == 1 || *p == 3)
831 if(*p == 0 || *p == 3)
833 gopcode(o, n->type, a1, n, a2, n);
843 gopcode(OASHL, n->type, D_CONST, nodconst(a1), a2, n);
850 nullwarn(Node *l, Node *r)
852 warn(Z, "result of operation not used");
860 sextern(Sym *s, Node *a, long o, long w)
864 for(e=0; e<w; e+=NSNAME) {
868 gpseudo(ADATA, s, D_SCONST, 0L);
869 p->from.offset += o+e;
870 p->from.displace = lw;
871 memmove(p->to.sval, a->cstring+e, lw);
876 gextern(Sym *s, Node *a, long o, long w)
878 if(a->op == OCONST && typev[a->type->etype]) {
879 gpseudo(ADATA, s, D_CONST, (long)(a->vconst>>32));
881 p->from.displace = 4;
882 gpseudo(ADATA, s, D_CONST, (long)(a->vconst));
883 p->from.offset += o + 4;
884 p->from.displace = 4;
887 gpseudotree(ADATA, s, a);
889 p->from.displace = w;
893 align(long i, Type *t, int op)
903 diag(Z, "unknown align opcode %d", op);
906 case Asu2: /* padding at end of a struct */
912 case Ael1: /* initial allign of struct element */
913 for(v=t; v->etype==TARRAY; v=v->link)
915 w = ewidth[v->etype];
916 if(w <= 0 || w >= SZ_SHORT)
922 case Ael2: /* width of a struct element */
926 case Aarg0: /* initial passbyptr argument in arg list */
927 if(typesuv[t->etype]) {
928 o = align(o, types[TIND], Aarg1);
929 o = align(o, types[TIND], Aarg2);
933 case Aarg1: /* initial allign of parameter */
934 w = ewidth[t->etype];
935 if(w <= 0 || w >= SZ_LONG) {
939 o += SZ_LONG - w; /* big endian adjustment */
943 case Aarg2: /* width of a parameter */
948 case Aaut3: /* total allign of automatic */
949 o = align(o, t, Ael1);
950 o = align(o, t, Ael2);
955 print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
960 maxround(long max, long v)
964 max = round(v, SZ_LONG);