diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-04-27 12:51:13 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-04-27 12:51:13 +0100 |
| commit | d67b7dad77bb8aa973dad1f7c3ab0c309b114278 (patch) | |
| tree | 6794120fb327d6de19cf05eed53f80d877781a3e /utils/qc/swt.c | |
| parent | 09da2e137d5eb0c940df35d989e4c31ec0654fc4 (diff) | |
20100427-1251
Diffstat (limited to 'utils/qc/swt.c')
| -rw-r--r-- | utils/qc/swt.c | 231 |
1 files changed, 85 insertions, 146 deletions
diff --git a/utils/qc/swt.c b/utils/qc/swt.c index 9bf0e58e..0170bad1 100644 --- a/utils/qc/swt.c +++ b/utils/qc/swt.c @@ -1,59 +1,20 @@ #include "gc.h" -int -swcmp(void *a1, void *a2) -{ - C1 *p1, *p2; - - p1 = a1; - p2 = a2; - if(p1->val < p2->val) - return -1; - return p1->val > p2->val; -} +int hasdoubled; +static int doubleflag; void -doswit(Node *n) +swit1(C1 *q, int nc, long def, Node *n) { - Case *c; - C1 *q, *iq; - long def, nc, i; Node tn; - - def = 0; - nc = 0; - for(c = cases; c->link != C; c = c->link) { - if(c->def) { - if(def) - diag(n, "more than one default in switch"); - def = c->label; - continue; - } - nc++; - } - - iq = alloc(nc*sizeof(C1)); - q = iq; - for(c = cases; c->link != C; c = c->link) { - if(c->def) - continue; - q->label = c->label; - q->val = c->val; - q++; - } - qsort(iq, nc, sizeof(C1), swcmp); - if(def == 0) - def = breakpc; - for(i=0; i<nc-1; i++) - if(iq[i].val == iq[i+1].val) - diag(n, "duplicate cases in switch %ld", iq[i].val); + regalloc(&tn, ®node, Z); - swit1(iq, nc, def, n, &tn); + swit2(q, nc, def, n, &tn); regfree(&tn); } void -swit1(C1 *q, int nc, long def, Node *n, Node *tn) +swit2(C1 *q, int nc, long def, Node *n, Node *tn) { C1 *r; int i; @@ -87,20 +48,10 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) gbranch(OGOTO); p->as = ABEQ; patch(p, r->label); - swit1(q, i, def, n, tn); + swit2(q, i, def, n, tn); patch(sp, pc); - swit1(r+1, nc-i-1, def, n, tn); -} - -void -cas(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; + swit2(r+1, nc-i-1, def, n, tn); } void @@ -200,33 +151,6 @@ outstring(char *s, long n) return r; } -long -outlstring(ushort *s, long n) -{ - char buf[2]; - int c; - long r; - - if(suppress) - return nstring; - while(nstring & 1) - outstring("", 1); - r = nstring; - while(n > 0) { - c = *s++; - if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; - } else { - buf[0] = c; - buf[1] = c>>8; - } - outstring(buf, 2); - n -= sizeof(ushort); - } - return r; -} - int mulcon(Node *n, Node *nn) { @@ -317,16 +241,6 @@ loop: } void -nullwarn(Node *l, Node *r) -{ - warn(Z, "result of operation not used"); - if(l != Z) - cgen(l, Z); - if(r != Z) - cgen(r, Z); -} - -void sextern(Sym *s, Node *a, long o, long w) { long e, lw; @@ -454,13 +368,14 @@ zwrite(Biobuf *b, Prog *p, int sf, int st) long l; bf[0] = p->as; - bf[1] = p->reg; + bf[1] = p->as>>8; + bf[2] = p->reg; l = p->lineno; - bf[2] = l; - bf[3] = l>>8; - bf[4] = l>>16; - bf[5] = l>>24; - bp = zaddr(bf+6, &p->from, sf); + bf[3] = l; + bf[4] = l>>8; + bf[5] = l>>16; + bf[6] = l>>24; + bp = zaddr(bf+7, &p->from, sf); bp = zaddr(bp, &p->to, st); Bwrite(b, bf, bp-bf); } @@ -510,6 +425,7 @@ outhist(Biobuf *b) } if(n) { Bputc(b, ANAME); + Bputc(b, ANAME>>8); Bputc(b, D_FILE); Bputc(b, 1); Bputc(b, '<'); @@ -535,27 +451,29 @@ outhist(Biobuf *b) void zname(Biobuf *b, Sym *s, int t) { - char *n, bf[7]; + char *n, bf[8]; ulong sig; n = s->name; if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){ sig = sign(s); bf[0] = ASIGNAME; - bf[1] = sig; - bf[2] = sig>>8; - bf[3] = sig>>16; - bf[4] = sig>>24; - bf[5] = t; - bf[6] = s->sym; - Bwrite(b, bf, 7); + bf[1] = ASIGNAME>>8; + bf[2] = sig; + bf[3] = sig>>8; + bf[4] = sig>>16; + bf[5] = sig>>24; + bf[6] = t; + bf[7] = s->sym; + Bwrite(b, bf, 8); s->sig = SIGDONE; } else{ bf[0] = ANAME; - bf[1] = t; /* type */ - bf[2] = s->sym; /* sym */ - Bwrite(b, bf, 3); + bf[1] = ANAME>>8; + bf[2] = t; /* type */ + bf[3] = s->sym; /* sym */ + Bwrite(b, bf, 4); } Bwrite(b, n, strlen(n)+1); } @@ -616,33 +534,32 @@ zaddr(char *bp, Adr *a, int s) return bp; } -void -ieeedtod(Ieee *ieee, double native) +static int +doubled(Type *t) { - double fr, ho, f; - int exp; + Type *v; - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; + if(debug['4']) + return 0; + if(t->nbits != 0) + return 0; + switch(t->etype){ + case TDOUBLE: + return 1; + + case TARRAY: + for(v=t; v->etype==TARRAY; v=v->link) + ; + return v->etype == TDOUBLE; + + case TSTRUCT: + case TUNION: + for(v = t->link; v != T; v = v->down) + if(doubled(v)) + return 1; + break; } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (long)(fr*f); + return 0; } long @@ -650,27 +567,33 @@ align(long i, Type *t, int op) { long o; Type *v; - int w; + int w, pc; o = i; w = 1; + pc = 0; switch(op) { default: diag(Z, "unknown align opcode %d", op); break; case Asu2: /* padding at end of a struct */ - w = SZ_LONG; + w = doubled(t)? SZ_DOUBLE: SZ_LONG; if(packflg) w = packflg; break; - case Ael1: /* initial allign of struct element */ + case Ael1: /* initial align of struct element (also automatic) */ for(v=t; v->etype==TARRAY; v=v->link) ; w = ewidth[v->etype]; - if(w <= 0 || w >= SZ_LONG) - w = SZ_LONG; + if(w <= 0 || w >= SZ_LONG){ + if(doubled(v)){ + w = SZ_DOUBLE; + doubleflag = 1; + }else + w = SZ_LONG; + } if(packflg) w = packflg; break; @@ -686,10 +609,15 @@ align(long i, Type *t, int op) } break; - case Aarg1: /* initial allign of parameter */ + case Aarg1: /* initial align of parameter */ w = ewidth[t->etype]; if(w <= 0 || w >= SZ_LONG) { - w = SZ_LONG; + if(doubled(t)){ + w = SZ_DOUBLE; + pc = SZ_LONG; /* alignment must account for pc */ + hasdoubled = 1; + }else + w = SZ_LONG; break; } o += SZ_LONG - w; /* big endian adjustment */ @@ -699,14 +627,20 @@ align(long i, Type *t, int op) case Aarg2: /* width of a parameter */ o += t->width; w = SZ_LONG; + if(doubled(t)){ + pc = SZ_LONG; + hasdoubled = 1; + } break; - case Aaut3: /* total allign of automatic */ + case Aaut3: /* total align of automatic */ + doubleflag = 0; o = align(o, t, Ael1); o = align(o, t, Ael2); + hasdoubled |= doubleflag; break; } - o = round(o, w); + o = round(o+pc, w)-pc; if(debug['A']) print("align %s %ld %T = %ld\n", bnames[op], i, t, o); return o; @@ -715,8 +649,13 @@ align(long i, Type *t, int op) long maxround(long max, long v) { - v += SZ_LONG-1; + int w; + + w = SZ_LONG; + if((debug['8'] || hasdoubled) && !debug['4']) + w = SZ_DOUBLE; + v += w-1; if(v > max) - max = round(v, SZ_LONG); + max = round(v, w); return max; } |
