summaryrefslogtreecommitdiff
path: root/sys/src/cmd/8c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-07-30 19:11:16 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-07-30 19:11:16 +0200
commit4f33c88a51587681b7be1ae57cfbc43b627c6bc4 (patch)
tree25560404dc80007e5dc268811242c9071f6a1017 /sys/src/cmd/8c
parentfcc5e75d07e5bc6cb3ddac6d9a437e7ec62d0d95 (diff)
import updated compilers from sources
Diffstat (limited to 'sys/src/cmd/8c')
-rw-r--r--sys/src/cmd/8c/8.out.h60
-rw-r--r--sys/src/cmd/8c/cgen.c15
-rw-r--r--sys/src/cmd/8c/cgen64.c84
-rw-r--r--sys/src/cmd/8c/div.c2
-rw-r--r--sys/src/cmd/8c/enam.c47
-rw-r--r--sys/src/cmd/8c/gc.h12
-rw-r--r--sys/src/cmd/8c/list.c45
-rw-r--r--sys/src/cmd/8c/machcap.c1
-rw-r--r--sys/src/cmd/8c/mkfile2
-rw-r--r--sys/src/cmd/8c/peep.c20
-rw-r--r--sys/src/cmd/8c/reg.c25
-rw-r--r--sys/src/cmd/8c/sgen.c4
-rw-r--r--sys/src/cmd/8c/swt.c7
-rw-r--r--sys/src/cmd/8c/txt.c67
14 files changed, 243 insertions, 148 deletions
diff --git a/sys/src/cmd/8c/8.out.h b/sys/src/cmd/8c/8.out.h
index c38ab83f3..a87341a2f 100644
--- a/sys/src/cmd/8c/8.out.h
+++ b/sys/src/cmd/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/sys/src/cmd/8c/cgen.c b/sys/src/cmd/8c/cgen.c
index 6fdaf6b01..9436ac698 100644
--- a/sys/src/cmd/8c/cgen.c
+++ b/sys/src/cmd/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);
@@ -887,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");
@@ -1824,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/sys/src/cmd/8c/cgen64.c b/sys/src/cmd/8c/cgen64.c
index dd82adfa2..6c4be5aa9 100644
--- a/sys/src/cmd/8c/cgen64.c
+++ b/sys/src/cmd/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/sys/src/cmd/8c/div.c b/sys/src/cmd/8c/div.c
index cb15ab2dd..65aa3570b 100644
--- a/sys/src/cmd/8c/div.c
+++ b/sys/src/cmd/8c/div.c
@@ -6,7 +6,7 @@
* SIGPLAN Notices, Vol. 29, June 1994, page 61.
*/
-#define TN(n) (1ULL << (n))
+#define TN(n) ((uvlong)1 << (n))
#define T31 TN(31)
#define T32 TN(32)
diff --git a/sys/src/cmd/8c/enam.c b/sys/src/cmd/8c/enam.c
index 3e293a283..cc6d0bf1d 100644
--- a/sys/src/cmd/8c/enam.c
+++ b/sys/src/cmd/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/sys/src/cmd/8c/gc.h b/sys/src/cmd/8c/gc.h
index b72579626..3c0c900d6 100644
--- a/sys/src/cmd/8c/gc.h
+++ b/sys/src/cmd/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);
@@ -298,7 +299,7 @@ Reg* rega(void);
int rcmp(const void*, const 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 +337,6 @@ int BtoF(long);
#define D_LO D_NONE
/*
- * bound
- */
-void comtarg(void);
-
-/*
* com64
*/
int cond(int);
diff --git a/sys/src/cmd/8c/list.c b/sys/src/cmd/8c/list.c
index 8ee833837..4251a3874 100644
--- a/sys/src/cmd/8c/list.c
+++ b/sys/src/cmd/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);
}
@@ -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);
@@ -229,9 +230,9 @@ Rconv(Fmt *fp)
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);
}
diff --git a/sys/src/cmd/8c/machcap.c b/sys/src/cmd/8c/machcap.c
index bf09cdcf7..1734e9c32 100644
--- a/sys/src/cmd/8c/machcap.c
+++ b/sys/src/cmd/8c/machcap.c
@@ -53,6 +53,7 @@ machcap(Node *n)
case OANDAND:
case OOROR:
case ONOT:
+ case ODOT:
return 1;
case OASADD:
diff --git a/sys/src/cmd/8c/mkfile b/sys/src/cmd/8c/mkfile
index 85abcd2e2..adc9786dd 100644
--- a/sys/src/cmd/8c/mkfile
+++ b/sys/src/cmd/8c/mkfile
@@ -2,7 +2,6 @@
TARG=8c
OFILES=\
- bound.$O\
cgen.$O\
cgen64.$O\
div.$O\
@@ -33,7 +32,6 @@ $LIB:
mk install
mk clean
-bound.$O: bound.h
%.$O: ../cc/%.c
$CC $CFLAGS ../cc/$stem.c
diff --git a/sys/src/cmd/8c/peep.c b/sys/src/cmd/8c/peep.c
index d67f75144..5f61925d7 100644
--- a/sys/src/cmd/8c/peep.c
+++ b/sys/src/cmd/8c/peep.c
@@ -67,8 +67,6 @@ peep(void)
pc = 0; /* speculating it won't kill */
loop1:
- if(debug['b'])
- comtarg();
t = 0;
for(r=firstr; r!=R; r=r->link) {
@@ -277,6 +275,9 @@ subprop(Reg *r0)
case ACWD:
case ACDQ:
+ case ASTOSB:
+ case ASTOSL:
+ case AMOVSB:
case AMOVSL:
case AFSTSW:
return 0;
@@ -641,10 +642,21 @@ copyu(Prog *p, Adr *v, Adr *s)
return 2;
goto caseread;
- case AMOVSL:
case AREP:
case AREPN:
- if(v->type == D_CX || v->type == D_DI || v->type == D_SI)
+ if(v->type == D_CX)
+ 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;
diff --git a/sys/src/cmd/8c/reg.c b/sys/src/cmd/8c/reg.c
index 12ad50ab7..c2bab2d02 100644
--- a/sys/src/cmd/8c/reg.c
+++ b/sys/src/cmd/8c/reg.c
@@ -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:
@@ -224,7 +224,9 @@ regopt(Prog *p)
*/
case AFMOVDP:
case AFMOVFP:
+ case AFMOVLP:
case AFMOVVP:
+ case AFMOVWP:
case ACALL:
for(z=0; z<BITS; z++)
addrs.b[z] |= bit.b[z];
@@ -637,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;
@@ -651,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;
@@ -674,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++) {
@@ -1008,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'])
@@ -1018,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'])
@@ -1028,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/sys/src/cmd/8c/sgen.c b/sys/src/cmd/8c/sgen.c
index df12f903b..9ba278c8c 100644
--- a/sys/src/cmd/8c/sgen.c
+++ b/sys/src/cmd/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/sys/src/cmd/8c/swt.c b/sys/src/cmd/8c/swt.c
index d2c48b40a..f469f18d4 100644
--- a/sys/src/cmd/8c/swt.c
+++ b/sys/src/cmd/8c/swt.c
@@ -10,7 +10,7 @@ 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);
+ print("case = %.8llux\n", q->val);
gopcode(OEQ, n->type, n, nodconst(q->val));
patch(p, q->label);
q++;
@@ -22,7 +22,7 @@ swit1(C1 *q, int nc, long def, Node *n)
i = nc / 2;
r = q+i;
if(debug['W'])
- print("case > %.8lux\n", r->val);
+ print("case > %.8llux\n", r->val);
gopcode(OGT, n->type, n, nodconst(r->val));
sp = p;
gbranch(OGOTO);
@@ -31,7 +31,7 @@ swit1(C1 *q, int nc, long def, Node *n)
swit1(q, i, def, n);
if(debug['W'])
- print("case < %.8lux\n", r->val);
+ print("case < %.8llux\n", r->val);
patch(sp, pc);
swit1(r+1, nc-i-1, def, n);
}
@@ -199,7 +199,6 @@ outcode(void)
return;
}
Binit(&b, f, OWRITE);
- Blethal(&b, nil);
Bseek(&b, 0L, 2);
outhist(&b);
for(sym=0; sym<NSYM; sym++) {
diff --git a/sys/src/cmd/8c/txt.c b/sys/src/cmd/8c/txt.c
index c6c4d1a18..13f62539f 100644
--- a/sys/src/cmd/8c/txt.c
+++ b/sys/src/cmd/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;
}
@@ -306,13 +311,34 @@ regalloc(Node *n, Node *tn, Node *o)
if(reg[i] == 0)
goto out;
diag(tn, "out of fixed registers");
+abort();
goto err;
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:
@@ -339,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;
@@ -430,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);
@@ -609,9 +646,6 @@ gmove(Node *f, Node *t)
case TDOUBLE:
gins(AFMOVD, f, t);
return;
- case TVLONG:
- gins(AFMOVV, f, t);
- return;
}
/*
@@ -650,9 +684,6 @@ gmove(Node *f, Node *t)
case TDOUBLE:
gins(AFMOVDP, f, t);
return;
- case TVLONG:
- gins(AFMOVVP, f, t);
- return;
}
/*
@@ -980,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;
@@ -994,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;
@@ -1011,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;
@@ -1027,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;
@@ -1054,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;
@@ -1355,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;
}