summaryrefslogtreecommitdiff
path: root/utils/8c
diff options
context:
space:
mode:
authorforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
committerforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
commit45a20ab721a513710138340faff3d59a31c3e01e (patch)
treeeea29d2684c51cc73725b8992a2125bede48e118 /utils/8c
parentcd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff)
sync compilers with Plan 9
remove 1[acl] 2[acl]
Diffstat (limited to 'utils/8c')
-rw-r--r--utils/8c/8.out.h60
-rw-r--r--utils/8c/cgen.c83
-rw-r--r--utils/8c/cgen64.c84
-rw-r--r--utils/8c/enam.c47
-rw-r--r--utils/8c/gc.h17
-rw-r--r--utils/8c/list.c51
-rw-r--r--utils/8c/machcap.c5
-rw-r--r--utils/8c/peep.c10
-rw-r--r--utils/8c/reg.c25
-rw-r--r--utils/8c/sgen.c4
-rw-r--r--utils/8c/swt.c33
-rw-r--r--utils/8c/txt.c68
12 files changed, 292 insertions, 195 deletions
diff --git a/utils/8c/8.out.h b/utils/8c/8.out.h
index c38ab83f..a87341a2 100644
--- a/utils/8c/8.out.h
+++ b/utils/8c/8.out.h
@@ -2,6 +2,7 @@
#define NSNAME 8
#define NOPROF (1<<0)
#define DUPOK (1<<1)
+#define NOSPLIT (1<<2)
enum as
{
@@ -353,6 +354,58 @@ enum as
ASIGNAME,
+ AFCOMI,
+ AFCOMIP,
+ AFUCOMI,
+ AFUCOMIP,
+ ACMPXCHGB,
+ ACMPXCHGL,
+ ACMPXCHGW,
+
+ /* conditional move */
+ ACMOVLCC,
+ ACMOVLCS,
+ ACMOVLEQ,
+ ACMOVLGE,
+ ACMOVLGT,
+ ACMOVLHI,
+ ACMOVLLE,
+ ACMOVLLS,
+ ACMOVLLT,
+ ACMOVLMI,
+ ACMOVLNE,
+ ACMOVLOC,
+ ACMOVLOS,
+ ACMOVLPC,
+ ACMOVLPL,
+ ACMOVLPS,
+ ACMOVWCC,
+ ACMOVWCS,
+ ACMOVWEQ,
+ ACMOVWGE,
+ ACMOVWGT,
+ ACMOVWHI,
+ ACMOVWLE,
+ ACMOVWLS,
+ ACMOVWLT,
+ ACMOVWMI,
+ ACMOVWNE,
+ ACMOVWOC,
+ ACMOVWOS,
+ ACMOVWPC,
+ ACMOVWPL,
+ ACMOVWPS,
+
+ AFCMOVCC,
+ AFCMOVCS,
+ AFCMOVEQ,
+ AFCMOVHI,
+ AFCMOVLS,
+ AFCMOVNE,
+ AFCMOVNU,
+ AFCMOVUN,
+
+ /* add new operations here. nowhere else. here. */
ALAST
};
@@ -378,6 +431,7 @@ enum
D_DI,
D_F0 = 16,
+ D_F7 = D_F0 + 7,
D_CS = 24,
D_SS,
@@ -413,12 +467,18 @@ enum
D_INDIR, /* additive */
+ D_CONST2 = D_INDIR+D_INDIR,
+
+ D_SIZE, /* 8l internal */
+
T_TYPE = 1<<0,
T_INDEX = 1<<1,
T_OFFSET = 1<<2,
T_FCONST = 1<<3,
T_SYM = 1<<4,
T_SCONST = 1<<5,
+ T_OFFSET2 = 1<<6,
+ T_GOTYPE = 1<<7,
REGARG = -1,
REGRET = D_AX,
diff --git a/utils/8c/cgen.c b/utils/8c/cgen.c
index c8511e2c..fac3b5d8 100644
--- a/utils/8c/cgen.c
+++ b/utils/8c/cgen.c
@@ -25,6 +25,12 @@ cgen(Node *n, Node *nn)
l = n->left;
r = n->right;
o = n->op;
+// Go's version does the following, but it's the wrong place: doesn't allow assignment
+// if(o == OEXREG || nn != Z && nn->op == OEXREG) {
+// gmove(n, nn);
+// return;
+// }
+
if(n->addable >= INDEXED) {
if(nn == Z) {
switch(o) {
@@ -244,7 +250,7 @@ cgen(Node *n, Node *nn)
if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
c = l->right->vconst;
- if(c > 0 && c <= 3) {
+ if(c > 0 && c <= 3 && nareg(1) >= 4) {
if(l->left->complex >= r->complex) {
regalloc(&nod, l->left, nn);
cgen(l->left, &nod);
@@ -309,7 +315,7 @@ cgen(Node *n, Node *nn)
if(typefd[n->type->etype])
goto fop;
if(r->op == OCONST) {
- SET(v);
+ v = 0;
switch(o) {
case ODIV:
case OMOD:
@@ -361,20 +367,27 @@ cgen(Node *n, Node *nn)
t = l;
l = r;
r = t;
+ goto imula;
}
- /* should favour AX */
- regalloc(&nod, l, nn);
- cgen(l, &nod);
- if(r->addable < INDEXED) {
+ else if(r->addable >= INDEXED) {
+ imula:
+/* should favour AX */
+ regalloc(&nod, l, nn);
+ cgen(l, &nod);
+ gopcode(OMUL, n->type, r, &nod);
+ }
+ else {
+/* should favour AX */
+ regalloc(&nod, l, nn);
+ cgen(l, &nod);
regalloc(&nod1, r, Z);
cgen(r, &nod1);
gopcode(OMUL, n->type, &nod1, &nod);
regfree(&nod1);
- }else
- gopcode(OMUL, n->type, r, &nod); /* addressible */
+ }
gmove(&nod, nn);
regfree(&nod);
- break;
+ goto done;
}
/*
@@ -427,21 +440,33 @@ cgen(Node *n, Node *nn)
}
reg[D_AX]++;
- if(r->op == OCONST && (o == ODIV || o == OLDIV)) {
- reg[D_DX]++;
- if(l->addable < INDEXED) {
- regalloc(&nod2, l, Z);
- cgen(l, &nod2);
- l = &nod2;
- }
- if(o == ODIV)
+ if(r->op == OCONST) {
+ switch(o) {
+ case ODIV:
+ reg[D_DX]++;
+ if(l->addable < INDEXED) {
+ regalloc(&nod2, l, Z);
+ cgen(l, &nod2);
+ l = &nod2;
+ }
sdivgen(l, r, &nod, &nod1);
- else
+ gmove(&nod1, nn);
+ if(l == &nod2)
+ regfree(l);
+ goto freeaxdx;
+ case OLDIV:
+ reg[D_DX]++;
+ if(l->addable < INDEXED) {
+ regalloc(&nod2, l, Z);
+ cgen(l, &nod2);
+ l = &nod2;
+ }
udivgen(l, r, &nod, &nod1);
- gmove(&nod1, nn);
- if(l == &nod2)
- regfree(l);
- goto freeaxdx;
+ gmove(&nod1, nn);
+ if(l == &nod2)
+ regfree(l);
+ goto freeaxdx;
+ }
}
if(l->complex >= r->complex) {
@@ -572,7 +597,7 @@ cgen(Node *n, Node *nn)
if(typefd[n->type->etype]||typefd[r->type->etype])
goto asfop;
if(r->op == OCONST) {
- SET(v);
+ v = 0;
switch(o) {
case OASDIV:
case OASMOD:
@@ -631,7 +656,7 @@ cgen(Node *n, Node *nn)
}
if(o == OASMUL) {
- /* should favour AX */
+/* should favour AX */
regalloc(&nod, l, nn);
if(r->complex >= FNX) {
regalloc(&nod1, r, Z);
@@ -661,7 +686,7 @@ cgen(Node *n, Node *nn)
regfree(&nod);
if(hardleft)
regfree(&nod2);
- break;
+ goto done;
}
/*
@@ -868,6 +893,7 @@ cgen(Node *n, Node *nn)
break;
case OFUNC:
+ l = uncomma(l);
if(l->complex >= FNX) {
if(l->op != OIND)
diag(n, "bad function call");
@@ -1617,7 +1643,6 @@ copy:
case OASMUL:
case OASLMUL:
-
case OASASHL:
case OASASHR:
case OASLSHR:
@@ -1806,6 +1831,12 @@ copy:
gins(ACLD, Z, Z);
gins(AREP, Z, Z);
gins(AMOVSL, Z, Z);
+ if(w & (SZ_LONG-1)) {
+ /* odd length of packed structure */
+ gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
+ gins(AREP, Z, Z);
+ gins(AMOVSB, Z, Z);
+ }
if(c & 4) {
gins(APOPL, Z, &nod3);
reg[D_CX]--;
diff --git a/utils/8c/cgen64.c b/utils/8c/cgen64.c
index dd82adfa..6c4be5aa 100644
--- a/utils/8c/cgen64.c
+++ b/utils/8c/cgen64.c
@@ -188,70 +188,6 @@ storepair(Node *n, Node *nn, int f)
freepair(n);
}
-/* generate a cast t from n to tt */
-static void
-cast(Node *n, Type *t, Node *nn)
-{
- Node *r;
-
- r = new(OCAST, n, Z);
- r->type = t;
- sugen(r, nn, 8);
-}
-
-static void
-swapregs(Node *a, Node *b)
-{
- int t;
-
- t = a->reg;
- a->reg = b->reg;
- b->reg = t;
-}
-
-static void
-swappairs(Node *a, Node *b)
-{
- swapregs(a->left, b->left);
- swapregs(a->right, b->right);
-}
-
-static int
-saveme(Node *n)
-{
- int r;
-
- r = n->reg;
- return r >= D_AX && r <= D_DI;
-}
-
-static void
-saveit(Node *n, Node *t, Node *r)
-{
- Node nod;
-
- if(saveme(n)) {
- t->reg = n->reg;
- gins(AMOVL, t, r);
- r->xoffset += SZ_LONG;
- if(n->reg == D_AX) {
- regalloc(&nod, n, Z);
- regfree(n);
- n->reg = nod.reg;
- }
- }
-}
-
-static void
-restoreit(Node *n, Node *t, Node *r)
-{
- if(saveme(n)) {
- t->reg = n->reg;
- gins(AMOVL, r, t);
- r->xoffset += SZ_LONG;
- }
-}
-
enum
{
/* 4 only, see WW */
@@ -319,26 +255,6 @@ vfunc(Node *n, Node *nn)
return t;
}
-static int
-forcereg(Node *d, int r, int o, Node *t)
-{
- int a;
-
- if(d->reg != D_NONE)
- diag(Z, "force alloc");
- d->reg = r;
- a = 0;
- if(reg[r]) {
- reg[o]++;
- regalloc(t, d, Z);
- a = 1;
- gins(AMOVL, d, t);
- reg[o]--;
- }
- reg[r]++;
- return a;
-}
-
/* try to steal a reg */
static int
getreg(Node **np, Node *t, int r)
diff --git a/utils/8c/enam.c b/utils/8c/enam.c
index 3e293a28..cc6d0bf1 100644
--- a/utils/8c/enam.c
+++ b/utils/8c/enam.c
@@ -333,5 +333,52 @@ char* anames[] =
"DYNT",
"INIT",
"SIGNAME",
+ "FCOMI",
+ "FCOMIP",
+ "FUCOMI",
+ "FUCOMIP",
+ "CMPXCHGB",
+ "CMPXCHGL",
+ "CMPXCHGW",
+ "CMOVLCC",
+ "CMOVLCS",
+ "CMOVLEQ",
+ "CMOVLGE",
+ "CMOVLGT",
+ "CMOVLHI",
+ "CMOVLLE",
+ "CMOVLLS",
+ "CMOVLLT",
+ "CMOVLMI",
+ "CMOVLNE",
+ "CMOVLOC",
+ "CMOVLOS",
+ "CMOVLPC",
+ "CMOVLPL",
+ "CMOVLPS",
+ "CMOVWCC",
+ "CMOVWCS",
+ "CMOVWEQ",
+ "CMOVWGE",
+ "CMOVWGT",
+ "CMOVWHI",
+ "CMOVWLE",
+ "CMOVWLS",
+ "CMOVWLT",
+ "CMOVWMI",
+ "CMOVWNE",
+ "CMOVWOC",
+ "CMOVWOS",
+ "CMOVWPC",
+ "CMOVWPL",
+ "CMOVWPS",
+ "FCMOVCC",
+ "FCMOVCS",
+ "FCMOVEQ",
+ "FCMOVHI",
+ "FCMOVLS",
+ "FCMOVNE",
+ "FCMOVNU",
+ "FCMOVUN",
"LAST",
};
diff --git a/utils/8c/gc.h b/utils/8c/gc.h
index b7257962..f635ed76 100644
--- a/utils/8c/gc.h
+++ b/utils/8c/gc.h
@@ -61,7 +61,7 @@ struct Prog
struct Case
{
Case* link;
- long val;
+ vlong val;
long label;
char def;
char isv;
@@ -70,7 +70,7 @@ struct Case
struct C1
{
- long val;
+ vlong val;
long label;
};
@@ -240,6 +240,7 @@ void nextpc(void);
void gargs(Node*, Node*, Node*);
void garg1(Node*, Node*, Node*, int, Node**);
Node* nodconst(long);
+int nareg(int);
Node* nodfconst(double);
int nodreg(Node*, Node*, int);
int isreg(Node*, int);
@@ -266,7 +267,7 @@ void gpseudo(int, Sym*, Node*);
/*
* swt.c
*/
-int swcmp(const void*, const void*);
+int swcmp(void*, void*);
void doswit(Node*);
void swit1(C1*, int, long, Node*);
void casf(void);
@@ -274,7 +275,6 @@ void bitload(Node*, Node*, Node*, Node*, Node*);
void bitstore(Node*, Node*, Node*, Node*, Node*);
long outstring(char*, long);
void nullwarn(Node*, Node*);
-void sextern(Sym*, Node*, long, long);
void gextern(Sym*, Node*, long, long);
void outcode(void);
void ieeedtod(Ieee*, double);
@@ -295,10 +295,10 @@ int Bconv(Fmt*);
* reg.c
*/
Reg* rega(void);
-int rcmp(const void*, const void*);
+int rcmp(void*, void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
-Bits mkvar(Reg*, Adr*);
+Bits mkvar(Reg*, Adr*, int);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, long);
void synch(Reg*, Bits);
@@ -336,11 +336,6 @@ int BtoF(long);
#define D_LO D_NONE
/*
- * bound
- */
-void comtarg(void);
-
-/*
* com64
*/
int cond(int);
diff --git a/utils/8c/list.c b/utils/8c/list.c
index 84466942..4251a387 100644
--- a/utils/8c/list.c
+++ b/utils/8c/list.c
@@ -27,7 +27,7 @@ Bconv(Fmt *fp)
if(str[0])
strcat(str, " ");
if(var[i].sym == S) {
- sprint(ss, "$%ld", var[i].offset);
+ snprint(ss, sizeof(ss), "$%ld", var[i].offset);
s = ss;
} else
s = var[i].sym->name;
@@ -47,13 +47,13 @@ Pconv(Fmt *fp)
p = va_arg(fp->args, Prog*);
if(p->as == ADATA)
- sprint(str, " %A %D/%d,%D",
+ snprint(str, sizeof(str), " %A %D/%d,%D",
p->as, &p->from, p->from.scale, &p->to);
else if(p->as == ATEXT)
- sprint(str, " %A %D,%d,%D",
+ snprint(str, sizeof(str), " %A %D,%d,%D",
p->as, &p->from, p->from.scale, &p->to);
else
- sprint(str, " %A %D,%D",
+ snprint(str, sizeof(str), " %A %D,%D",
p->as, &p->from, &p->to);
return fmtstrcpy(fp, str);
}
@@ -70,7 +70,7 @@ Aconv(Fmt *fp)
int
Dconv(Fmt *fp)
{
- char str[STRINGSZ], s[STRINGSZ];
+ char str[40], s[20];
Adr *a;
int i;
@@ -78,18 +78,18 @@ Dconv(Fmt *fp)
i = a->type;
if(i >= D_INDIR) {
if(a->offset)
- sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
+ snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
else
- sprint(str, "(%R)", i-D_INDIR);
+ snprint(str, sizeof(str), "(%R)", i-D_INDIR);
goto brk;
}
switch(i) {
default:
if(a->offset)
- sprint(str, "$%ld,%R", a->offset, i);
+ snprint(str, sizeof(str), "$%ld,%R", a->offset, i);
else
- sprint(str, "%R", i);
+ snprint(str, sizeof(str), "%R", i);
break;
case D_NONE:
@@ -97,53 +97,54 @@ Dconv(Fmt *fp)
break;
case D_BRANCH:
- sprint(str, "%ld(PC)", a->offset-pc);
+ snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
break;
case D_EXTERN:
- sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
+ snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
break;
case D_STATIC:
- sprint(str, "%s<>+%ld(SB)", a->sym->name,
+ snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name,
a->offset);
break;
case D_AUTO:
- sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
+ snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
break;
case D_PARAM:
if(a->sym)
- sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
+ snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
else
- sprint(str, "%ld(FP)", a->offset);
+ snprint(str, sizeof(str), "%ld(FP)", a->offset);
break;
case D_CONST:
- sprint(str, "$%ld", a->offset);
+ snprint(str, sizeof(str), "$%ld", a->offset);
break;
case D_FCONST:
- sprint(str, "$(%.17e)", a->dval);
+ snprint(str, sizeof(str), "$(%.17e)", a->dval);
break;
case D_SCONST:
- sprint(str, "$\"%S\"", a->sval);
+ snprint(str, sizeof(str), "$\"%S\"", a->sval);
break;
case D_ADDR:
a->type = a->index;
a->index = D_NONE;
- sprint(str, "$%D", a);
+ snprint(str, sizeof(str), "$%D", a);
a->index = a->type;
a->type = D_ADDR;
goto conv;
}
brk:
if(a->index != D_NONE) {
- sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
+ fmtstrcpy(fp, str);
+ snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
+ return fmtstrcpy(fp, s);
}
conv:
return fmtstrcpy(fp, str);
@@ -224,14 +225,14 @@ char* regstr[] =
int
Rconv(Fmt *fp)
{
- char str[STRINGSZ];
+ char str[20];
int r;
r = va_arg(fp->args, int);
if(r >= D_AL && r <= D_NONE)
- sprint(str, "%s", regstr[r-D_AL]);
+ snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
else
- sprint(str, "gok(%d)", r);
+ snprint(str, sizeof(str), "gok(%d)", r);
return fmtstrcpy(fp, str);
}
@@ -240,7 +241,7 @@ int
Sconv(Fmt *fp)
{
int i, c;
- char str[STRINGSZ], *p, *a;
+ char str[30], *p, *a;
a = va_arg(fp->args, char*);
p = str;
diff --git a/utils/8c/machcap.c b/utils/8c/machcap.c
index 3a8831a7..1734e9c3 100644
--- a/utils/8c/machcap.c
+++ b/utils/8c/machcap.c
@@ -3,6 +3,7 @@
int
machcap(Node *n)
{
+// return 0;
if(n == Z)
return 1; /* test */
@@ -15,6 +16,8 @@ machcap(Node *n)
if(typechl[n->type->etype])
return 1;
if(typev[n->type->etype]) {
+// if(typev[n->type->etype] && n->right->op == OCONST) {
+// if(hi64v(n->right) == 0)
return 1;
}
break;
@@ -50,6 +53,7 @@ machcap(Node *n)
case OANDAND:
case OOROR:
case ONOT:
+ case ODOT:
return 1;
case OASADD:
@@ -80,6 +84,7 @@ machcap(Node *n)
case OHS:
case OLO:
case OLS:
+//print("%O\n", n->op);
return 1;
}
return 0;
diff --git a/utils/8c/peep.c b/utils/8c/peep.c
index 3d98b771..5f61925d 100644
--- a/utils/8c/peep.c
+++ b/utils/8c/peep.c
@@ -275,6 +275,9 @@ subprop(Reg *r0)
case ACWD:
case ACDQ:
+ case ASTOSB:
+ case ASTOSL:
+ case AMOVSB:
case AMOVSL:
case AFSTSW:
return 0;
@@ -645,11 +648,18 @@ copyu(Prog *p, Adr *v, Adr *s)
return 2;
goto caseread;
+ case AMOVSB:
case AMOVSL:
if(v->type == D_DI || v->type == D_SI)
return 2;
goto caseread;
+ case ASTOSB:
+ case ASTOSL:
+ if(v->type == D_AX || v->type == D_DI)
+ return 2;
+ goto caseread;
+
case AFSTSW:
if(v->type == D_AX)
return 2;
diff --git a/utils/8c/reg.c b/utils/8c/reg.c
index fe84f573..9677cd24 100644
--- a/utils/8c/reg.c
+++ b/utils/8c/reg.c
@@ -16,7 +16,7 @@ rega(void)
}
int
-rcmp(const void *a1, const void *a2)
+rcmp(void *a1, void *a2)
{
Rgn *p1, *p2;
int c1, c2;
@@ -119,7 +119,7 @@ regopt(Prog *p)
r1->s1 = R;
}
- bit = mkvar(r, &p->from);
+ bit = mkvar(r, &p->from, p->as==AMOVL);
if(bany(&bit))
switch(p->as) {
/*
@@ -139,7 +139,7 @@ regopt(Prog *p)
break;
}
- bit = mkvar(r, &p->to);
+ bit = mkvar(r, &p->to, 0);
if(bany(&bit))
switch(p->as) {
default:
@@ -639,7 +639,7 @@ doregbits(int r)
}
Bits
-mkvar(Reg *r, Adr *a)
+mkvar(Reg *r, Adr *a, int isro)
{
Var *v;
int i, t, n, et, z;
@@ -653,13 +653,21 @@ mkvar(Reg *r, Adr *a)
t = a->type;
r->regu |= doregbits(t);
r->regu |= doregbits(a->index);
+ et = a->etype;
switch(t) {
default:
goto none;
+ case D_INDIR+D_GS:
+ if(!isro || 1)
+ goto none;
+ n = t;
+ {static Sym er; a->sym = &er;}
+ a->sym->name = "$extreg";
+ break;
case D_ADDR:
a->type = a->index;
- bit = mkvar(r, a);
+ bit = mkvar(r, a, 0);
for(z=0; z<BITS; z++)
addrs.b[z] |= bit.b[z];
a->type = t;
@@ -676,7 +684,6 @@ mkvar(Reg *r, Adr *a)
goto none;
if(s->name[0] == '.')
goto none;
- et = a->etype;
o = a->offset;
v = var;
for(i=0; i<nvar; i++) {
@@ -1010,7 +1017,7 @@ paint1(Reg *r, int bn)
if(r->use1.b[z] & bb) {
change += CREF * r->loop;
- if(p->as == AFMOVL)
+ if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
change = -CINF;
if(debug['R'] && debug['v'])
@@ -1020,7 +1027,7 @@ paint1(Reg *r, int bn)
if((r->use2.b[z]|r->set.b[z]) & bb) {
change += CREF * r->loop;
- if(p->as == AFMOVL)
+ if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
change = -CINF;
if(debug['R'] && debug['v'])
@@ -1030,7 +1037,7 @@ paint1(Reg *r, int bn)
if(STORE(r) & r->regdiff.b[z] & bb) {
change -= CLOAD * r->loop;
- if(p->as == AFMOVL)
+ if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
change = -CINF;
if(debug['R'] && debug['v'])
diff --git a/utils/8c/sgen.c b/utils/8c/sgen.c
index df12f903..9ba278c8 100644
--- a/utils/8c/sgen.c
+++ b/utils/8c/sgen.c
@@ -88,6 +88,10 @@ xcom(Node *n)
n->addable = 11;
break;
+ case OEXREG:
+ n->addable = 12;
+ break;
+
case OREGISTER:
n->addable = 12;
break;
diff --git a/utils/8c/swt.c b/utils/8c/swt.c
index 46fd71eb..aad14717 100644
--- a/utils/8c/swt.c
+++ b/utils/8c/swt.c
@@ -9,8 +9,8 @@ swit1(C1 *q, int nc, long def, Node *n)
if(nc < 5) {
for(i=0; i<nc; i++) {
- if(debug['W'])
- print("case = %.8lux\n", q->val);
+ if(debug['K'])
+ print("case = %.8llux\n", q->val);
gopcode(OEQ, n->type, n, nodconst(q->val));
patch(p, q->label);
q++;
@@ -21,8 +21,8 @@ swit1(C1 *q, int nc, long def, Node *n)
}
i = nc / 2;
r = q+i;
- if(debug['W'])
- print("case > %.8lux\n", r->val);
+ if(debug['K'])
+ print("case > %.8llux\n", r->val);
gopcode(OGT, n->type, n, nodconst(r->val));
sp = p;
gbranch(OGOTO);
@@ -30,8 +30,8 @@ swit1(C1 *q, int nc, long def, Node *n)
patch(p, r->label);
swit1(q, i, def, n);
- if(debug['W'])
- print("case < %.8lux\n", r->val);
+ if(debug['K'])
+ print("case < %.8llux\n", r->val);
patch(sp, pc);
swit1(r+1, nc-i-1, def, n);
}
@@ -128,23 +128,6 @@ outstring(char *s, long n)
}
void
-sextern(Sym *s, Node *a, long o, long w)
-{
- long e, lw;
-
- for(e=0; e<w; e+=NSNAME) {
- lw = NSNAME;
- if(w-e < lw)
- lw = w-e;
- gpseudo(ADATA, s, nodconst(0L));
- p->from.offset += o+e;
- p->from.scale = lw;
- p->to.type = D_SCONST;
- memmove(p->to.sval, a->cstring+e, lw);
- }
-}
-
-void
gextern(Sym *s, Node *a, long o, long w)
{
if(a->op == OCONST && typev[a->type->etype]) {
@@ -512,8 +495,8 @@ align(long i, Type *t, int op)
long
maxround(long max, long v)
{
- v += SZ_LONG-1;
+ v = round(v, SZ_LONG);
if(v > max)
- max = round(v, SZ_LONG);
+ return v;
return max;
}
diff --git a/utils/8c/txt.c b/utils/8c/txt.c
index 44413d81..5415cef2 100644
--- a/utils/8c/txt.c
+++ b/utils/8c/txt.c
@@ -22,6 +22,8 @@ ginit(void)
lastp = P;
tfield = types[TLONG];
+ typeswitch = typechlv;
+
zprog.link = P;
zprog.as = AGOK;
zprog.from.type = D_NONE;
@@ -158,7 +160,8 @@ gargs(Node *n, Node *tn1, Node *tn2)
cursafe = regs;
}
-int nareg(void)
+int
+nareg(int notbp)
{
int i, n;
@@ -166,6 +169,8 @@ int nareg(void)
for(i=D_AX; i<=D_DI; i++)
if(reg[i] == 0)
n++;
+ if(notbp && reg[D_BP] == 0)
+ n--;
return n;
}
@@ -311,9 +316,29 @@ abort();
case TFLOAT:
case TDOUBLE:
- case TVLONG:
i = D_F0;
goto out;
+
+ case TVLONG:
+ case TUVLONG:
+ n->op = OREGPAIR;
+ n->complex = 0; /* already in registers */
+ n->addable = 11;
+ n->type = tn->type;
+ n->lineno = nearln;
+ n->left = alloc(sizeof(Node));
+ n->right = alloc(sizeof(Node));
+ if(o != Z && o->op == OREGPAIR) {
+ regalloc(n->left, &regnode, o->left);
+ regalloc(n->right, &regnode, o->right);
+ } else {
+ regalloc(n->left, &regnode, Z);
+ regalloc(n->right, &regnode, Z);
+ }
+ n->right->type = types[TULONG];
+ if(tn->type->etype == TUVLONG)
+ n->left->type = types[TULONG];
+ return;
}
diag(tn, "unknown type in regalloc: %T", tn->type);
err:
@@ -340,6 +365,12 @@ regfree(Node *n)
{
int i;
+ if(n->op == OREGPAIR) {
+ regfree(n->left);
+ regfree(n->right);
+ return;
+ }
+
i = 0;
if(n->op != OREGISTER && n->op != OINDREG)
goto err;
@@ -431,6 +462,11 @@ naddr(Node *n, Adr *a)
a->sym = S;
break;
+ case OEXREG:
+ a->type = D_INDIR + D_GS;
+ a->offset = n->reg - 1;
+ a->etype = n->etype;
+ break;
case OIND:
naddr(n->left, a);
@@ -610,9 +646,6 @@ gmove(Node *f, Node *t)
case TDOUBLE:
gins(AFMOVD, f, t);
return;
- case TVLONG:
- gins(AFMOVV, f, t);
- return;
}
/*
@@ -651,9 +684,6 @@ gmove(Node *f, Node *t)
case TDOUBLE:
gins(AFMOVDP, f, t);
return;
- case TVLONG:
- gins(AFMOVVP, f, t);
- return;
}
/*
@@ -838,7 +868,7 @@ gmove(Node *f, Node *t)
gmove(f, &fregnode0);
gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
gins(AFMOVLP, f, &nod);
- gins(ASUBL, nodconst(-2147483648), &nod);
+ gins(ASUBL, nodconst(-2147483648u), &nod);
gmove(&nod, t);
return;
@@ -981,7 +1011,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev)
if(et == TFLOAT)
a = AFADDF;
else
- if(et == TDOUBLE || et == TVLONG) {
+ if(et == TDOUBLE) {
a = AFADDD;
if(pop)
a = AFADDDP;
@@ -995,7 +1025,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev)
if(rev)
a = AFSUBRF;
} else
- if(et == TDOUBLE || et == TVLONG) {
+ if(et == TDOUBLE) {
a = AFSUBD;
if(pop)
a = AFSUBDP;
@@ -1012,7 +1042,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev)
if(et == TFLOAT)
a = AFMULF;
else
- if(et == TDOUBLE || et == TVLONG) {
+ if(et == TDOUBLE) {
a = AFMULD;
if(pop)
a = AFMULDP;
@@ -1028,7 +1058,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev)
if(rev)
a = AFDIVRF;
} else
- if(et == TDOUBLE || et == TVLONG) {
+ if(et == TDOUBLE) {
a = AFDIVD;
if(pop)
a = AFDIVDP;
@@ -1055,7 +1085,7 @@ fgopcode(int o, Node *f, Node *t, int pop, int rev)
a = AGOK;
}
} else
- if(et == TDOUBLE || et == TVLONG) {
+ if(et == TDOUBLE) {
a = AFCOMF;
if(pop) {
a = AFCOMDP;
@@ -1356,7 +1386,15 @@ long
exreg(Type *t)
{
- USED(t);
+ int o;
+
+ if(typechlp[t->etype]){
+ if(exregoffset >= 32)
+ return 0;
+ o = exregoffset;
+ exregoffset += 4;
+ return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
+ }
return 0;
}