shithub: mc

Download patch

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;
--