summaryrefslogtreecommitdiff
path: root/utils/qc/swt.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/qc/swt.c')
-rw-r--r--utils/qc/swt.c231
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, &regnode, 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;
}