ref: ac3c0bd121fac595ebaeb9c364929697bb05cfe1
parent: fc8c0b717cd982deca8898f6e5f5c396e45230c1
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jul 30 19:49:16 EDT 2012
More work towards x64.
--- a/8/asm.h
+++ b/8/asm.h
@@ -1,7 +1,6 @@
-/* x86 sure likes 4 */
-#define Maxarg 4
-#define Wordsz 4
-#define K 4 /* 4 general purpose regs with all modes available */
+#define Maxarg 4 /* maximum number of args an insn can have */
+#define Ptrsz 8 /* the size of a machine word (ie, pointer size) */
+#define K 14 /* the number of allocatable registers */
typedef size_t regid;
@@ -181,6 +180,7 @@
Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode);
Loc *loclit(long val, Mode m);
Loc *loclitl(char *lbl);
+Loc *coreg(Reg r, Mode m);
void locprint(FILE *fd, Loc *l, char spec);
void iprintf(FILE *fd, Insn *insn);
--- a/8/insns.def
+++ b/8/insns.def
@@ -23,7 +23,7 @@
Insn(Imov, "\tmov%t %x,%x\n", Use(.l={1}), Def(.l={2}))
Insn(Imovz, "\tmovz%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
Insn(Imovs, "\tmovs%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Ilea, "\tlea%t %m,%r\n", Use(.l={1}), Def(.l={2}))
+Insn(Ilea, "\tlea%2t %m,%r\n", Use(.l={1}), Def(.l={2}))
Insn(Iadd, "\tadd%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
Insn(Isub, "\tsub%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
--- a/8/isel.c
+++ b/8/isel.c
@@ -53,7 +53,10 @@
static Mode mode(Node *n)
{
- switch (exprtype(n)->type) {
+ Type *t;
+
+ t = tybase(exprtype(n));
+ switch (t->type) {
case Tyfloat32: return ModeF; break;
case Tyfloat64: return ModeD; break;
default:
@@ -68,77 +71,9 @@
/* FIXME: huh. what should the mode for, say, structs
* be when we have no intention of loading /through/ the
* pointer? */
- return ModeL;
+ return ModeQ;
}
-static Loc *coreg(Reg r, Mode m)
-{
- Reg crtab[][Nmode + 1] = {
- [Ral] = {Rnone, Ral, Rax, Reax, Rrax},
- [Rcl] = {Rnone, Rcl, Rcx, Recx, Rrcx},
- [Rdl] = {Rnone, Rdl, Rdx, Redx, Rrdx},
- [Rbl] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
- [Rsil] = {Rnone, Rsil, Rsi, Resi, Rrsi},
- [Rdil] = {Rnone, Rdil, Rdi, Redi, Rrdi},
- [R8b] = {Rnone, R8b, R8w, R8d, R8},
- [R9b] = {Rnone, R9b, R9w, R9d, R9},
- [R10b] = {Rnone, R10b, R10w, R10d, R10},
- [R11b] = {Rnone, R11b, R11w, R11d, R11},
- [R12b] = {Rnone, R12b, R12w, R12d, R12},
- [R13b] = {Rnone, R13b, R13w, R13d, R13},
- [R14b] = {Rnone, R14b, R14w, R14d, R14},
- [R15b] = {Rnone, R15b, R15w, R15d, R15},
-
- [Rax] = {Rnone, Ral, Rax, Reax},
- [Rcx] = {Rnone, Rcl, Rcx, Recx},
- [Rdx] = {Rnone, Rdl, Rdx, Redx},
- [Rbx] = {Rnone, Rbl, Rbx, Rebx},
- [Rsi] = {Rnone, Rsil, Rsi, Resi},
- [Rdi] = {Rnone, Rsil, Rdi, Redi},
- [R8w] = {Rnone, R8b, R8w, R8d, R8},
- [R9w] = {Rnone, R9b, R9w, R9d, R9},
- [R10w] = {Rnone, R10b, R10w, R10d, R10},
- [R11w] = {Rnone, R11b, R11w, R11d, R11},
- [R12w] = {Rnone, R12b, R12w, R12d, R12},
- [R13w] = {Rnone, R13b, R13w, R13d, R13},
- [R14w] = {Rnone, R14b, R14w, R14d, R14},
- [R15w] = {Rnone, R15b, R15w, R15d, R15},
-
- [Reax] = {Rnone, Ral, Rax, Reax},
- [Recx] = {Rnone, Rcl, Rcx, Recx},
- [Redx] = {Rnone, Rdl, Rdx, Redx},
- [Rebx] = {Rnone, Rbl, Rbx, Rebx},
- [Resi] = {Rnone, Rsil, Rsi, Resi},
- [Redi] = {Rnone, Rsil, Rdi, Redi},
- [R8d] = {Rnone, R8b, R8w, R8d, R8},
- [R9d] = {Rnone, R9b, R9w, R9d, R9},
- [R10d] = {Rnone, R10b, R10w, R10d, R10},
- [R11d] = {Rnone, R11b, R11w, R11d, R11},
- [R12d] = {Rnone, R12b, R12w, R12d, R12},
- [R13d] = {Rnone, R13b, R13w, R13d, R13},
- [R14d] = {Rnone, R14b, R14w, R14d, R14},
- [R15d] = {Rnone, R15b, R15w, R15d, R15},
-
- [Rrax] = {Rnone, Ral, Rax, Reax},
- [Rrcx] = {Rnone, Rcl, Rcx, Recx},
- [Rrdx] = {Rnone, Rdl, Rdx, Redx},
- [Rrbx] = {Rnone, Rbl, Rbx, Rebx},
- [Rrsi] = {Rnone, Rsil, Rsi, Resi},
- [Rrdi] = {Rnone, Rsil, Rdi, Redi},
- [R8] = {Rnone, R8b, R8w, R8d, R8},
- [R9] = {Rnone, R9b, R9w, R9d, R9},
- [R10] = {Rnone, R10b, R10w, R10d, R10},
- [R11] = {Rnone, R11b, R11w, R11d, R11},
- [R12] = {Rnone, R12b, R12w, R12d, R12},
- [R13] = {Rnone, R13b, R13w, R13d, R13},
- [R14] = {Rnone, R14b, R14w, R14d, R14},
- [R15] = {Rnone, R15b, R15w, R15d, R15},
- };
-
- assert(crtab[r][m] != Rnone);
- return locphysreg(crtab[r][m]);
-}
-
static Loc *loc(Isel *s, Node *n)
{
Loc *l;
@@ -205,8 +140,7 @@
static void movz(Isel *s, Loc *src, Loc *dst)
{
- if (src->mode == dst->mode ||
- (src->mode == ModeL && dst->mode == ModeQ))
+ if (src->mode == dst->mode)
g(s, Imov, src, dst, NULL);
else
g(s, Imovz, src, dst, NULL);
@@ -361,9 +295,7 @@
scale = 1;
l = NULL;
args = e->expr.args;
- if (exprop(e) == Oaddr) {
- l = selexpr(s, args[0]);
- } else if (exprop(e) == Oadd) {
+ if (exprop(e) == Oadd) {
b = selexpr(s, args[0]);
if (ismergablemul(args[1], &scale))
o = selexpr(s, args[1]->expr.args[0]);
@@ -435,7 +367,7 @@
* We skip the first operand, since it's the function itself */
for (i = 1; i < n->expr.nargs; i++)
argsz += size(n->expr.args[i]);
- stkbump = loclit(argsz, ModeL);
+ stkbump = loclit(argsz, ModeQ);
if (argsz)
g(s, Isub, stkbump, rsp, NULL);
@@ -443,9 +375,9 @@
argoff = 0;
for (i = 1; i < n->expr.nargs; i++) {
arg = selexpr(s, n->expr.args[i]);
- if (size(n->expr.args[i]) > 4) {
- dst = locreg(ModeL);
- src = locreg(ModeL);
+ if (size(n->expr.args[i]) > Ptrsz) {
+ dst = locreg(ModeQ);
+ src = locreg(ModeQ);
g(s, Ilea, arg, src, NULL);
blit(s, rsp, src, argoff, 0, size(n->expr.args[i]));
} else {
@@ -540,8 +472,8 @@
case Oderef:
a = selexpr(s, args[0]);
a = inr(s, a);
- r = locreg(a->mode);
- c = locmem(0, a, Rnone, a->mode);
+ r = locreg(mode(n));
+ c = locmem(0, a, Rnone, mode(n));
g(s, Imov, c, r, NULL);
break;
@@ -550,7 +482,7 @@
if (a->type == Loclbl) {
r = loclitl(a->lbl);
} else {
- r = locreg(ModeL);
+ r = locreg(ModeQ);
g(s, Ilea, a, r, NULL);
}
break;
@@ -631,7 +563,7 @@
case Ozwiden:
a = selexpr(s, args[0]);
b = locreg(mode(n));
- g(s, Imovz, a, b, NULL);
+ movz(s, a, b);
r = b;
break;
case Oswiden:
@@ -713,6 +645,18 @@
int i;
int modeidx;
+ /* x64 has a quirk; it has no movzlq because mov zero extends. This
+ * means that we need to do a movl when we really want a movzlq. Since
+ * we don't know the name of the reg to use, we need to sub it in when
+ * writing... */
+ if (insn->op == Imovz) {
+ if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
+ if (insn->args[1]->reg.colour) {
+ insn->op = Imov;
+ insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
+ }
+ }
+ }
p = insnfmts[insn->op];
i = 0;
modeidx = 0;
@@ -790,12 +734,11 @@
static void epilogue(Isel *s)
{
- Loc *rsp, *rbp, *rax;
+ Loc *rsp, *rbp;
Loc *ret;
rsp = locphysreg(Rrsp);
rbp = locphysreg(Rrbp);
- rax = locphysreg(Rrax);
if (s->ret) {
ret = loc(s, s->ret);
g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
--- a/8/locs.c
+++ b/8/locs.c
@@ -74,7 +74,7 @@
l = zalloc(sizeof(Loc));
l->type = Loclbl;
- l->mode = ModeL;
+ l->mode = ModeQ;
l->lbl = strdup(lbl);
return l;
}
@@ -85,7 +85,7 @@
l = zalloc(sizeof(Loc));
l->type = Loclitl;
- l->mode = ModeL;
+ l->mode = ModeQ;
l->lbl = strdup(lbl);
return l;
}
@@ -99,7 +99,7 @@
Loc **locmap = NULL;
size_t maxregid = 0;
-Loc *locreg(Mode m)
+static Loc *locregid(regid id, Mode m)
{
Loc *l;
@@ -106,12 +106,17 @@
l = zalloc(sizeof(Loc));
l->type = Locreg;
l->mode = m;
- l->reg.id = maxregid++;
+ l->reg.id = id;
locmap = xrealloc(locmap, maxregid * sizeof(Loc*));
locmap[l->reg.id] = l;
return l;
}
+Loc *locreg(Mode m)
+{
+ return locregid(maxregid++, m);
+}
+
Loc *locphysreg(Reg r)
{
static Loc *physregs[Nreg] = {0,};
@@ -180,3 +185,72 @@
l->lit = val;
return l;
}
+
+Loc *coreg(Reg r, Mode m)
+{
+ Reg crtab[][Nmode + 1] = {
+ [Ral] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Rcl] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Rdl] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rbl] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Rsil] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Rdil] = {Rnone, Rdil, Rdi, Redi, Rrdi},
+ [R8b] = {Rnone, R8b, R8w, R8d, R8},
+ [R9b] = {Rnone, R9b, R9w, R9d, R9},
+ [R10b] = {Rnone, R10b, R10w, R10d, R10},
+ [R11b] = {Rnone, R11b, R11w, R11d, R11},
+ [R12b] = {Rnone, R12b, R12w, R12d, R12},
+ [R13b] = {Rnone, R13b, R13w, R13d, R13},
+ [R14b] = {Rnone, R14b, R14w, R14d, R14},
+ [R15b] = {Rnone, R15b, R15w, R15d, R15},
+
+ [Rax] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Rcx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Rdx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rbx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Rsi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Rdi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
+ [R8w] = {Rnone, R8b, R8w, R8d, R8},
+ [R9w] = {Rnone, R9b, R9w, R9d, R9},
+ [R10w] = {Rnone, R10b, R10w, R10d, R10},
+ [R11w] = {Rnone, R11b, R11w, R11d, R11},
+ [R12w] = {Rnone, R12b, R12w, R12d, R12},
+ [R13w] = {Rnone, R13b, R13w, R13d, R13},
+ [R14w] = {Rnone, R14b, R14w, R14d, R14},
+ [R15w] = {Rnone, R15b, R15w, R15d, R15},
+
+ [Reax] = {Rnone, Ral, Rax, Reax},
+ [Recx] = {Rnone, Rcl, Rcx, Recx},
+ [Redx] = {Rnone, Rdl, Rdx, Redx},
+ [Rebx] = {Rnone, Rbl, Rbx, Rebx},
+ [Resi] = {Rnone, Rsil, Rsi, Resi},
+ [Redi] = {Rnone, Rsil, Rdi, Redi},
+ [R8d] = {Rnone, R8b, R8w, R8d, R8},
+ [R9d] = {Rnone, R9b, R9w, R9d, R9},
+ [R10d] = {Rnone, R10b, R10w, R10d, R10},
+ [R11d] = {Rnone, R11b, R11w, R11d, R11},
+ [R12d] = {Rnone, R12b, R12w, R12d, R12},
+ [R13d] = {Rnone, R13b, R13w, R13d, R13},
+ [R14d] = {Rnone, R14b, R14w, R14d, R14},
+ [R15d] = {Rnone, R15b, R15w, R15d, R15},
+
+ [Rrax] = {Rnone, Ral, Rax, Reax},
+ [Rrcx] = {Rnone, Rcl, Rcx, Recx},
+ [Rrdx] = {Rnone, Rdl, Rdx, Redx},
+ [Rrbx] = {Rnone, Rbl, Rbx, Rebx},
+ [Rrsi] = {Rnone, Rsil, Rsi, Resi},
+ [Rrdi] = {Rnone, Rsil, Rdi, Redi},
+ [R8] = {Rnone, R8b, R8w, R8d, R8},
+ [R9] = {Rnone, R9b, R9w, R9d, R9},
+ [R10] = {Rnone, R10b, R10w, R10d, R10},
+ [R11] = {Rnone, R11b, R11w, R11d, R11},
+ [R12] = {Rnone, R12b, R12w, R12d, R12},
+ [R13] = {Rnone, R13b, R13w, R13d, R13},
+ [R14] = {Rnone, R14b, R14w, R14d, R14},
+ [R15] = {Rnone, R15b, R15w, R15d, R15},
+ };
+
+ assert(crtab[r][m] != Rnone);
+ return locphysreg(crtab[r][m]);
+}
+
--- a/8/ra.c
+++ b/8/ra.c
@@ -61,6 +61,16 @@
[Rcl] = 1,
[Rdl] = 2,
[Rbl] = 3,
+ [Rsil] = 4,
+ [Rdil] = 5,
+ [R8b] = 6,
+ [R9b] = 7,
+ [R10b] = 8,
+ [R11b] = 9,
+ [R12b] = 10,
+ [R13b] = 11,
+ [R14b] = 12,
+ [R15b] = 13,
/* word */
[Rax] = 0,
@@ -67,6 +77,16 @@
[Rcx] = 1,
[Rdx] = 2,
[Rbx] = 3,
+ [Rsi] = 4,
+ [Rdi] = 5,
+ [R8w] = 6,
+ [R9w] = 7,
+ [R10w] = 8,
+ [R11w] = 9,
+ [R12w] = 10,
+ [R13w] = 11,
+ [R14w] = 12,
+ [R15w] = 13,
/* dword */
[Reax] = 0,
@@ -73,8 +93,35 @@
[Recx] = 1,
[Redx] = 2,
[Rebx] = 3,
- [Resp] = 4,
- [Rebp] = 5,
+ [Resi] = 4,
+ [Redi] = 5,
+ [R8d] = 6,
+ [R9d] = 7,
+ [R10d] = 8,
+ [R11d] = 9,
+ [R12d] = 10,
+ [R13d] = 11,
+ [R14d] = 12,
+ [R15d] = 13,
+
+ /* qword */
+ [Rrax] = 0,
+ [Rrcx] = 1,
+ [Rrdx] = 2,
+ [Rrbx] = 3,
+ [Rrsi] = 4,
+ [Rrdi] = 5,
+ [R8] = 6,
+ [R9] = 7,
+ [R10] = 8,
+ [R11] = 9,
+ [R12] = 10,
+ [R13] = 11,
+ [R14] = 12,
+ [R15] = 13,
+
+ [Rrsp] = 14,
+ [Rrbp] = 15,
};
/* %esp, %ebp are not in the allocatable pool */
--- a/8/simp.c
+++ b/8/simp.c
@@ -53,11 +53,7 @@
static void declarelocal(Simp *s, Node *n);
/* useful constants */
-static Node *one;
-static Node *zero;
-static Node *ptrsz;
-static Node *wordsz;
-static Type *tyword;
+static Type *tyintptr;
static Type *tyvoid;
static Type *base(Type *t)
@@ -70,11 +66,21 @@
{
Node *n;
+ assert(size(a) == size(b));
n = mkexpr(a->line, Oadd, a, b, NULL);
n->expr.type = a->expr.type;
return n;
}
+static Node *addk(Node *n, uvlong v)
+{
+ Node *k;
+
+ k = mkintlit(n->line, v);
+ k->expr.type = exprtype(n);
+ return add(n, k);
+}
+
static Node *sub(Node *a, Node *b)
{
Node *n;
@@ -84,6 +90,15 @@
return n;
}
+static Node *subk(Node *n, uvlong v)
+{
+ Node *k;
+
+ k = mkintlit(n->line, v);
+ k->expr.type = exprtype(n);
+ return sub(n, k);
+}
+
static Node *mul(Node *a, Node *b)
{
Node *n;
@@ -127,15 +142,15 @@
return n;
}
-static Node *word(int line, uint v)
+static Node *disp(int line, uint v)
{
Node *n;
+
n = mkintlit(line, v);
- n->expr.type = tyword;
+ n->expr.type = tyintptr;
return n;
}
-
static size_t did(Node *n)
{
if (n->type == Ndecl) {
@@ -213,10 +228,12 @@
return 2;
case Tyint: case Tyint32:
case Tyuint: case Tyuint32:
- case Typtr: case Tyfunc:
case Tychar: /* utf32 */
return 4;
+ case Typtr: case Tyfunc:
+ return Ptrsz;
+
case Tyint64: case Tylong:
case Tyuint64: case Tyulong:
return 8;
@@ -243,15 +260,15 @@
break;
case Tystruct:
for (i = 0; i < t->nmemb; i++)
- sz += align(size(t->sdecls[i]), Wordsz);
+ sz += align(size(t->sdecls[i]), Ptrsz);
return sz;
break;
case Tyunion:
- sz = Wordsz;
+ sz = Ptrsz;
for (i = 0; i < t->nmemb; i++)
if (t->udecls[i]->etype)
- sz = max(sz, tysize(t->udecls[i]->etype) + Wordsz);
- return align(sz, Wordsz);
+ sz = max(sz, tysize(t->udecls[i]->etype) + Ptrsz);
+ return align(sz, Ptrsz);
break;
case Tybad: case Tyvar: case Typaram: case Tyname: case Ntypes:
die("Type %s does not have size; why did it get down to here?", tystr(t));
@@ -404,10 +421,10 @@
Ucon *uc;
if (exprop(n) != Ocons)
- return load(add(addr(n, tyword), word(n->line, off)));
+ return load(add(addr(n, tyintptr), disp(n->line, off)));
uc = finducon(n);
- return word(uc->line, uc->id);
+ return disp(uc->line, uc->id);
}
static Node *uval(Node *n, size_t off)
@@ -418,8 +435,8 @@
return n;
else
/* FIXME: WRONG WRONG WRONG. Union vals
- * aren't only words. */
- return load(add(addr(n, tyword), word(n->line, off)));
+ * aren't only disps. */
+ return load(add(addr(n, tyintptr), disp(n->line, off)));
}
static Node *ucompare(Simp *s, Node *a, Node *b, Type *t, size_t off)
@@ -445,7 +462,7 @@
x = uval(a, off);
y = uval(b, off);
r = mkexpr(a->line, Oeq, x, y, NULL);
- r->expr.type = tyword;
+ r->expr.type = tyintptr;
break;
case Tyunion:
x = uconid(a, off);
@@ -455,12 +472,12 @@
uc = finducon(b);
r = mkexpr(a->line, Oeq, x, y, NULL);
- r->expr.type = tyword;
+ r->expr.type = tyintptr;
if (uc->etype) {
- off += Wordsz;
+ off += Ptrsz;
v = ucompare(s, a, b, uc->etype, off);
r = mkexpr(a->line, Oland, r, v, NULL);
- r->expr.type = tyword;
+ r->expr.type = tyintptr;
r = rval(s, r, NULL); /* Oland needs to be reduced */
}
break;
@@ -469,7 +486,6 @@
}
-
FILE *f;
static void simpmatch(Simp *s, Node *n)
{
@@ -553,6 +569,18 @@
return -1;
}
+static Node *ptrsized(Simp *s, Node *v)
+{
+ if (size(v) == Ptrsz)
+ return v;
+ else if (size(v) < Ptrsz)
+ v = mkexpr(v->line, Ozwiden, v, NULL);
+ else if (size(v) > Ptrsz)
+ v = mkexpr(v->line, Otrunc, v, NULL);
+ v->expr.type = tyintptr;
+ return v;
+}
+
static Node *membaddr(Simp *s, Node *n)
{
Node *t, *u, *r;
@@ -566,7 +594,7 @@
} else {
t = addr(args[0], exprtype(n));
}
- u = word(n->line, offset(args[0], args[1]));
+ u = disp(n->line, offset(args[0], args[1]));
r = add(t, u);
r->expr.type = mktyptr(n->line, n->expr.type);
return r;
@@ -590,8 +618,9 @@
die("Can't index type %s\n", tystr(n->expr.type));
assert(t->expr.type->type == Typtr);
u = rval(s, args[1], NULL);
+ u = ptrsized(s, u);
sz = size(n);
- v = mul(u, word(n->line, sz));
+ v = mul(u, disp(n->line, sz));
r = add(t, v);
return r;
}
@@ -611,7 +640,7 @@
}
/* safe: all types we allow here have a sub[0] that we want to grab */
sz = tysize(n->expr.type->sub[0]);
- v = mul(off, word(n->line, sz));
+ v = mul(off, disp(n->line, sz));
return add(u, v);
}
@@ -618,7 +647,7 @@
static Node *slicelen(Simp *s, Node *sl)
{
/* *(&sl + 4) */
- return load(add(addr(sl, tyword), ptrsz));
+ return load(addk(addr(sl, tyintptr), Ptrsz));
}
Node *lval(Simp *s, Node *n)
@@ -674,9 +703,9 @@
start = rval(s, n->expr.args[1], NULL);
end = rval(s, n->expr.args[2], NULL);
len = sub(end, start);
- stbase = store(addr(t, tyword), base);
+ stbase = store(addr(t, tyintptr), base);
/* *(&slice + ptrsz) = len */
- sz = add(addr(t, tyword), ptrsz);
+ sz = addk(addr(t, tyintptr), Ptrsz);
stlen = store(sz, len);
append(s, stbase);
append(s, stlen);
@@ -686,6 +715,7 @@
static Node *lowercast(Simp *s, Node *n)
{
Node **args;
+ Node *sz;
Node *r;
Type *t;
int issigned;
@@ -703,11 +733,12 @@
t = tybase(exprtype(args[0]));
switch (t->type) {
case Tyslice:
- if (t->type != Typtr)
- r = slicebase(s, args[0], zero);
- else
+ if (t->type == Typtr)
fatal(n->line, "Bad cast from %s to %s",
tystr(exprtype(args[0])), tystr(exprtype(n)));
+ sz = mkintlit(n->line, Ptrsz);
+ sz->expr.type = exprtype(args[0]);
+ r = slicebase(s, args[0], sz);
break;
case Tyint8: case Tyint16: case Tyint32: case Tyint64:
case Tyint: case Tylong:
@@ -771,9 +802,9 @@
off = 0;
for (i = 0; i < lhs->expr.nargs; i++) {
lv = lval(s, args[i]);
- prv = add(addr(rhs, exprtype(args[i])), word(rhs->line, off));
- if (size(args[i]) > Wordsz) {
- sz = word(lhs->line, size(lv));
+ prv = add(addr(rhs, exprtype(args[i])), disp(rhs->line, off));
+ if (size(args[i]) > Ptrsz) {
+ sz = disp(lhs->line, size(lv));
plv = addr(lv, exprtype(lv));
stor = mkexpr(lhs->line, Oblit, plv, prv, sz, NULL);
} else {
@@ -800,10 +831,10 @@
* so we know our work is done. */
if (u == t) {
r = t;
- } else if (size(lhs) > Wordsz) {
+ } else if (size(lhs) > Ptrsz) {
t = addr(t, exprtype(lhs));
u = addr(u, exprtype(lhs));
- v = word(lhs->line, size(lhs));
+ v = disp(lhs->line, size(lhs));
r = mkexpr(lhs->line, Oblit, t, u, v, NULL);
} else if (exprop(lhs) == Ovar) {
r = mkexpr(lhs->line, Oset, t, u, NULL);
@@ -828,9 +859,9 @@
off = 0;
for (i = 0; i < n->expr.nargs; i++) {
val = rval(s, args[i], NULL);
- pdst = add(r, word(n->line, off));
- if (size(args[i]) > Wordsz) {
- sz = word(n->line, size(val));
+ pdst = add(r, disp(n->line, off));
+ if (size(args[i]) > Ptrsz) {
+ sz = disp(n->line, size(val));
pval = addr(val, exprtype(val));
stor = mkexpr(n->line, Oblit, pdst, pval, sz, NULL);
} else {
@@ -867,16 +898,16 @@
else
tmp = temp(s, n);
u = addr(tmp, exprtype(n));
- tag = word(n->line, uc->id);
+ tag = disp(n->line, uc->id);
append(s, store(u, tag));
if (!uc->etype)
return tmp;
elt = rval(s, n->expr.args[1], NULL);
- u = add(u, wordsz);
- if (tysize(uc->etype) > Wordsz) {
+ u = addk(u, Ptrsz);
+ if (tysize(uc->etype) > Ptrsz) {
elt = addr(elt, uc->etype);
- sz = word(n->line, tysize(uc->utype));
+ sz = disp(n->line, tysize(uc->utype));
r = mkexpr(n->line, Oblit, u, elt, sz, NULL);
} else {
r = store(u, elt);
@@ -914,7 +945,7 @@
simplazy(s, n, r);
break;
case Osize:
- r = word(n->line, size(args[0]));
+ r = disp(n->line, size(args[0]));
break;
case Oslice:
r = lowerslice(s, n, dst);
@@ -964,12 +995,12 @@
* => args[0] = args[0] + 1
* expr(x) */
case Opreinc:
- v = assign(s, args[0], add(args[0], one));
+ v = assign(s, args[0], addk(args[0], 1));
append(s, v);
r = rval(s, args[0], NULL);
break;
case Opredec:
- v = assign(s, args[0], sub(args[0], one));
+ v = assign(s, args[0], subk(args[0], 1));
append(s, v);
r = rval(s, args[0], NULL);
break;
@@ -981,12 +1012,12 @@
*/
case Opostinc:
r = rval(s, args[0], NULL);
- t = store(lval(s, args[0]), add(r, one));
+ t = store(lval(s, args[0]), addk(r, 1));
lappend(&s->incqueue, &s->nqueue, t);
break;
case Opostdec:
r = rval(s, args[0], NULL);
- t = store(lval(s, args[0]), sub(r, one));
+ t = store(lval(s, args[0]), subk(r, 1));
lappend(&s->incqueue, &s->nqueue, t);
break;
case Olit:
@@ -1009,7 +1040,7 @@
if (s->isbigret) {
t = rval(s, args[0], NULL);
t = addr(t, exprtype(args[0]));
- u = word(n->line, size(args[0]));
+ u = disp(n->line, size(args[0]));
v = mkexpr(n->line, Oblit, s->ret, t, u, NULL);
append(s, v);
} else if (n->expr.nargs && n->expr.args[0]) {
@@ -1023,7 +1054,7 @@
r = assign(s, args[0], args[1]);
break;
case Ocall:
- if (exprtype(n)->type != Tyvoid && size(n) > Wordsz) {
+ if (exprtype(n)->type != Tyvoid && size(n) > Ptrsz) {
r = temp(s, n);
linsert(&n->expr.args, &n->expr.nargs, 1, addr(r, exprtype(n)));
for (i = 0; i < n->expr.nargs; i++)
@@ -1050,7 +1081,7 @@
{
assert(n->type == Ndecl);
s->stksz += size(n);
- s->stksz = align(s->stksz, min(size(n), Wordsz));
+ s->stksz = align(s->stksz, min(size(n), Ptrsz));
if (debug)
printf("declare %s:%s(%zd) at %zd\n", declname(n), tystr(decltype(n)), n->decl.did, s->stksz);
htput(s->locs, n, (void*)s->stksz);
@@ -1059,10 +1090,10 @@
static void declarearg(Simp *s, Node *n)
{
assert(n->type == Ndecl);
- s->argsz = align(s->argsz, min(size(n), Wordsz));
+ s->argsz = align(s->argsz, min(size(n), Ptrsz));
if (debug)
- printf("declare %s(%zd) at %zd\n", declname(n), n->decl.did, -(s->argsz + 8));
- htput(s->locs, n, (void*)-(s->argsz + 8));
+ printf("declare %s(%zd) at %zd\n", declname(n), n->decl.did, -(s->argsz + 2*Ptrsz));
+ htput(s->locs, n, (void*)-(s->argsz + 2*Ptrsz));
s->argsz += size(n);
}
@@ -1124,7 +1155,7 @@
assert(f->type == Nfunc);
ty = f->func.type->sub[0];
- if (ty->type != Tyvoid && tysize(ty) > Wordsz) {
+ if (ty->type != Tyvoid && tysize(ty) > Ptrsz) {
s->isbigret = 1;
s->ret = gentemp(s, f, mktyptr(f->line, ty), &dcl);
declarearg(s, dcl);
@@ -1254,12 +1285,8 @@
FILE *fd;
/* declare useful constants */
- tyword = mkty(-1, Tyint);
+ tyintptr = mkty(-1, Tyuint64);
tyvoid = mkty(-1, Tyvoid);
- one = word(-1, 1);
- zero = word(-1, 0);
- ptrsz = word(-1, Wordsz);
- wordsz = word(-1, Wordsz);
fn = NULL;
nfn = 0;
--
⑨