]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: factor newly-portable code into gc directory
authorRuss Cox <rsc@golang.org>
Fri, 30 Jan 2015 04:50:10 +0000 (23:50 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 11 Feb 2015 20:36:27 +0000 (20:36 +0000)
This isn't everything, but it's a start.
Still producing bit-identical compiler output.

The semantics of the old back ends is preserved,
even when they are probably buggy.
There are some TODOs in gc/gsubr.c to
remove special cases to preserve bugs in 5g and 8g.

Change-Id: I28ae295fbfc94ef9df43e13ab96bd6fc2f194bc4
Reviewed-on: https://go-review.googlesource.com/3802
Reviewed-by: Austin Clements <austin@google.com>
39 files changed:
include/link.h
src/cmd/5g/galign.c
src/cmd/5g/gg.h
src/cmd/5g/ggen.c
src/cmd/5g/gobj.c [deleted file]
src/cmd/5g/gsubr.c
src/cmd/5g/reg.c
src/cmd/5l/5.out.h
src/cmd/6g/galign.c
src/cmd/6g/gg.h
src/cmd/6g/ggen.c
src/cmd/6g/gobj.c [deleted file]
src/cmd/6g/gsubr.c
src/cmd/6l/6.out.h
src/cmd/8g/galign.c
src/cmd/8g/gg.h
src/cmd/8g/ggen.c
src/cmd/8g/gobj.c [deleted file]
src/cmd/8g/gsubr.c
src/cmd/8l/8.out.h
src/cmd/9g/galign.c
src/cmd/9g/gg.h
src/cmd/9g/ggen.c
src/cmd/9g/gobj.c [deleted file]
src/cmd/9g/gsubr.c
src/cmd/9l/9.out.h
src/cmd/gc/gen.c
src/cmd/gc/go.h
src/cmd/gc/gsubr.c [new file with mode: 0644]
src/cmd/gc/obj.c
src/cmd/gc/pgen.c
src/cmd/gc/plive.c
src/cmd/gc/reflect.c
src/cmd/gc/sinit.c
src/cmd/gc/walk.c
src/liblink/asm5.c
src/liblink/go.c
src/liblink/obj5.c
src/liblink/obj6.c

index 91993986b3f24b4cb8b243d980378ffc62423d40..4d2ec776478f8978b818755ba73c3704c0ee4fc3 100644 (file)
@@ -277,6 +277,9 @@ enum {
        A_ARCHSPECIFIC, // first architecture-specific opcode value
 };
 
+void   nopout(Prog*);
+void   nocache(Prog*);
+
 // prevent incompatible type signatures between liblink and 8l on Plan 9
 #pragma incomplete struct Section
 
index 85ad347833a157edd1c0f0d4e73e632d2d7e5337..1af6df06a8f93b759315ac72968d5bb6b1a15f9f 100644 (file)
@@ -46,8 +46,9 @@ main(int argc, char **argv)
        arch.thestring = thestring;
        arch.thelinkarch = thelinkarch;
        arch.typedefs = typedefs;
+       arch.REGSP = REGSP;
+       arch.REGCTXT = REGCTXT;
        arch.MAXWIDTH = MAXWIDTH;
-       arch.afunclit = afunclit;
        arch.anyregalloc = anyregalloc;
        arch.betypeinit = betypeinit;
        arch.bgen = bgen;
@@ -57,37 +58,15 @@ main(int argc, char **argv)
        arch.cgen_callinter = cgen_callinter;
        arch.cgen_ret = cgen_ret;
        arch.clearfat = clearfat;
-       arch.clearp = clearp;
-       arch.defframe = defframe;
-       arch.dgostringptr = dgostringptr;
-       arch.dgostrlitptr = dgostrlitptr;
-       arch.dsname = dsname;
-       arch.dsymptr = dsymptr;
-       arch.dumpdata = dumpdata;
        arch.dumpit = dumpit;
        arch.excise = excise;
        arch.expandchecks = expandchecks;
-       arch.fixautoused = fixautoused;
        arch.gclean = gclean;
-       arch.gdata = gdata;
-       arch.gdatacomplex = gdatacomplex;
-       arch.gdatastring = gdatastring;
-       arch.ggloblnod = ggloblnod;
-       arch.ggloblsym = ggloblsym;
        arch.ginit = ginit;
        arch.gins = gins;
        arch.ginscall = ginscall;
-       arch.gjmp = gjmp;
-       arch.gtrack = gtrack;
-       arch.gused = gused;
        arch.igen = igen;
-       arch.isfat = isfat;
        arch.linkarchinit = linkarchinit;
-       arch.markautoused = markautoused;
-       arch.naddr = naddr;
-       arch.newplist = newplist;
-       arch.nodarg = nodarg;
-       arch.patch = patch;
        arch.proginfo = proginfo;
        arch.regalloc = regalloc;
        arch.regfree = regfree;
@@ -96,7 +75,6 @@ main(int argc, char **argv)
        arch.sameaddr = sameaddr;
        arch.smallindir = smallindir;
        arch.stackaddr = stackaddr;
-       arch.unpatch = unpatch;
        
        gcmain(argc, argv);
 }
index 8a75311d734857ac8240ed334187ecc7127f714b..912c224b317b896359ae38db469409cd348ac95e 100644 (file)
@@ -17,10 +17,7 @@ enum
        REGALLOC_FMAX = FREGEXT,
 };
 
-EXTERN int32   dynloc;
 EXTERN uchar   reg[REGALLOC_FMAX+1];
-EXTERN int32   pcloc;          // instruction counter
-EXTERN Strlit  emptystring;
 extern long    unmappedzero;
 
 /*
index b7c621be3287d6a2d50462576213ec1bf25eef50..e65523730b3edb3385e22c126a904ff71dfddbaf 100644 (file)
@@ -117,52 +117,6 @@ appendpp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int tre
        return q;       
 }
 
-// Sweep the prog list to mark any used nodes.
-void
-markautoused(Prog* p)
-{
-       for (; p; p = p->link) {
-               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
-                       continue;
-
-               if (p->from.node)
-                       ((Node*)(p->from.node))->used = 1;
-
-               if (p->to.node)
-                       ((Node*)(p->to.node))->used = 1;
-       }
-}
-
-// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
-void
-fixautoused(Prog* p)
-{
-       Prog **lp;
-
-       for (lp=&p; (p=*lp) != P; ) {
-               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
-                       *lp = p->link;
-                       continue;
-               }
-               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
-                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
-                       // VARDEFs are interspersed with other code, and a jump might be using the
-                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
-                       // the no-ops.
-                       nopout(p);
-                       continue;
-               }
-
-               if (p->from.name == NAME_AUTO && p->from.node)
-                       p->from.offset += ((Node*)(p->from.node))->stkdelta;
-
-               if (p->to.name == NAME_AUTO && p->to.node)
-                       p->to.offset += ((Node*)(p->to.node))->stkdelta;
-
-               lp = &p->link;
-       }
-}
-
 /*
  * generate:
  *     call f
@@ -176,7 +130,7 @@ void
 ginscall(Node *f, int proc)
 {
        Prog *p;
-       Node n1, r, r1, con;
+       Node r, r1, con;
        int32 extra;
 
        if(f->type != T) {
@@ -238,10 +192,7 @@ ginscall(Node *f, int proc)
                p->to.reg = REGSP;
                p->to.offset = 4;
 
-               memset(&n1, 0, sizeof n1);
-               n1.op = OADDR;
-               n1.left = f;
-               gins(AMOVW, &n1, &r);
+               gins(AMOVW, f, &r);
                p = gins(AMOVW, &r, N);
                p->to.type = TYPE_MEM;
                p->to.reg = REGSP;
@@ -615,18 +566,6 @@ ret:
        ;
 }
 
-int
-samereg(Node *a, Node *b)
-{
-       if(a->op != OREGISTER)
-               return 0;
-       if(b->op != OREGISTER)
-               return 0;
-       if(a->val.u.reg != b->val.u.reg)
-               return 0;
-       return 1;
-}
-
 /*
  * generate high multiply
  *  res = (nl * nr) >> wordsize
diff --git a/src/cmd/5g/gobj.c b/src/cmd/5g/gobj.c
deleted file mode 100644 (file)
index 13d06ef..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-// Derived from Inferno utils/5c/swt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/swt.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-int
-dsname(Sym *sym, int off, char *t, int n)
-{
-       Prog *p;
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.etype = TINT32;
-       p->from.offset = off;
-       p->from.reg = 0;
-       p->from.sym = linksym(sym);
-       
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = n;
-       
-       p->to.type = TYPE_SCONST;
-       p->to.name = NAME_NONE;
-       p->to.reg = 0;
-       p->to.offset = 0;
-       memmove(p->to.u.sval, t, n);
-       return off + n;
-}
-
-/*
- * make a refer to the data s, s+len
- * emitting DATA if needed.
- */
-void
-datastring(char *s, int len, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(s, len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->etype = TINT32;
-       a->offset = widthptr+4;  // skip header
-       a->reg = 0;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-}
-
-/*
- * make a refer to the string sval,
- * emitting DATA if needed.
- */
-void
-datagostring(Strlit *sval, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(sval->s, sval->len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->etype = TSTRING;
-       a->offset = 0;  // header
-       a->reg = 0;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-}
-
-void
-gdata(Node *nam, Node *nr, int wid)
-{
-       Prog *p;
-       vlong v;
-
-       if(nr->op == OLITERAL) {
-               switch(nr->val.ctype) {
-               case CTCPLX:
-                       gdatacomplex(nam, nr->val.u.cval);
-                       return;
-               case CTSTR:
-                       gdatastring(nam, nr->val.u.sval);
-                       return;
-               }
-       }
-
-       if(wid == 8 && is64(nr->type)) {
-               v = mpgetfix(nr->val.u.xval);
-               p = gins(ADATA, nam, nodintconst(v));
-               p->from3.type = TYPE_CONST;
-               p->from3.offset = 4;
-               p = gins(ADATA, nam, nodintconst(v>>32));
-               p->from3.type = TYPE_CONST;
-               p->from3.offset = 4;
-               p->from.offset += 4;
-               return;
-       }
-       p = gins(ADATA, nam, nr);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = wid;
-}
-
-void
-gdatacomplex(Node *nam, Mpcplx *cval)
-{
-       Prog *p;
-       int w;
-
-       w = cplxsubtype(nam->type->etype);
-       w = types[w]->width;
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->real);
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->from.offset += w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->imag);
-}
-
-void
-gdatastring(Node *nam, Strlit *sval)
-{
-       Prog *p;
-       Node nod1;
-
-       p = gins(ADATA, nam, N);
-       datastring(sval->s, sval->len, &p->to);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[tptr]->width;
-       p->to.type = TYPE_CONST;
-       p->to.etype = TINT32;
-//print("%P\n", p);
-
-       nodconst(&nod1, types[TINT32], sval->len);
-       p = gins(ADATA, nam, &nod1);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[TINT32]->width;
-       p->from.offset += types[tptr]->width;
-}
-
-int
-dstringptr(Sym *s, int off, char *str)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-
-       datastring(str, strlen(str)+1, &p->to);
-       p->to.type = TYPE_CONST;
-       p->to.etype = TINT32;
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostrlitptr(Sym *s, int off, Strlit *lit)
-{
-       Prog *p;
-
-       if(lit == nil)
-               return duintptr(s, off, 0);
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       datagostring(lit, &p->to);
-       p->to.type = TYPE_CONST;
-       p->to.etype = TINT32;
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostringptr(Sym *s, int off, char *str)
-{
-       int n;
-       Strlit *lit;
-
-       if(str == nil)
-               return duintptr(s, off, 0);
-
-       n = strlen(str);
-       lit = mal(sizeof *lit + n);
-       strcpy(lit->s, str);
-       lit->len = n;
-       return dgostrlitptr(s, off, lit);
-}
-
-int
-dsymptr(Sym *s, int off, Sym *x, int xoff)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       p->to.type = TYPE_ADDR;
-       p->to.name = NAME_EXTERN;
-       p->to.sym = linksym(x);
-       p->to.offset = xoff;
-       off += widthptr;
-
-       return off;
-}
-
-void
-nopout(Prog *p)
-{
-       p->as = ANOP;
-       p->scond = zprog.scond;
-       p->from = zprog.from;
-       p->to = zprog.to;
-       p->reg = zprog.reg;
-}
index dbcfc233bed6b22051644d0d1e4ac62366966dfa..b7a177d4eac3aa2c57abc5fb442ac136d104b25d 100644 (file)
 // At the same time, can raise StackBig in ../../runtime/stack.h.
 long unmappedzero = 4096;
 
-void
-clearp(Prog *p)
-{
-       p->as = AEND;
-       p->reg = 0;
-       p->scond = C_SCOND_NONE;
-       p->from.type = TYPE_NONE;
-       p->from.name = NAME_NONE;
-       p->from.reg = 0;
-       p->to.type = TYPE_NONE;
-       p->to.name = NAME_NONE;
-       p->to.reg = 0;
-       p->pc = pcloc;
-       pcloc++;
-}
-
-static int ddumped;
-static Prog *dfirst;
-static Prog *dpc;
-
-/*
- * generate and return proc with p->as = as,
- * linked into program.  pc is next instruction.
- */
-Prog*
-prog(int as)
-{
-       Prog *p;
-
-       if(as == ADATA || as == AGLOBL) {
-               if(ddumped)
-                       fatal("already dumped data");
-               if(dpc == nil) {
-                       dpc = mal(sizeof(*dpc));
-                       dfirst = dpc;
-               }
-               p = dpc;
-               dpc = mal(sizeof(*dpc));
-               p->link = dpc;
-               p->reg = 0;  // used for flags
-       } else {
-               p = pc;
-               pc = mal(sizeof(*pc));
-               clearp(pc);
-               p->link = pc;
-       }
-
-       if(lineno == 0) {
-               if(debug['K'])
-                       warn("prog: line 0");
-       }
-
-       p->as = as;
-       p->lineno = lineno;
-       return p;
-}
-
-void
-dumpdata(void)
-{
-       ddumped = 1;
-       if(dfirst == nil)
-               return;
-       newplist();
-       *pc = *dfirst;
-       pc = dpc;
-       clearp(pc);
-}
-
-/*
- * generate a branch.
- * t is ignored.
- * likely values are for branch prediction:
- *     -1 unlikely
- *     0 no opinion
- *     +1 likely
- */
-Prog*
-gbranch(int as, Type *t, int likely)
-{
-       Prog *p;
-
-       USED(t);
-       USED(likely);  // TODO: record this for linker
-
-       p = prog(as);
-       p->to.type = TYPE_BRANCH;
-       p->to.u.branch = P;
-       return p;
-}
-
-/*
- * patch previous branch to jump to to.
- */
-void
-patch(Prog *p, Prog *to)
-{
-       if(p->to.type != TYPE_BRANCH)
-               fatal("patch: not a branch");
-       p->to.u.branch = to;
-       p->to.offset = to->pc;
-}
-
-Prog*
-unpatch(Prog *p)
-{
-       Prog *q;
-
-       if(p->to.type != TYPE_BRANCH)
-               fatal("unpatch: not a branch");
-       q = p->to.u.branch;
-       p->to.u.branch = P;
-       p->to.offset = 0;
-       return q;
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-newplist(void)
-{
-       Plist *pl;
-
-       pl = linknewplist(ctxt);
-
-       pc = mal(sizeof(*pc));
-       clearp(pc);
-       pl->firstpc = pc;
-
-       return pl;
-}
-
-void
-gused(Node *n)
-{
-       gins(ANOP, n, N);       // used
-}
-
-Prog*
-gjmp(Prog *to)
-{
-       Prog *p;
-
-       p = gbranch(AB, T, 0);
-       if(to != P)
-               patch(p, to);
-       return p;
-}
-
-void
-ggloblnod(Node *nam)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, nam, N);
-       p->lineno = nam->lineno;
-       p->from.sym->gotype = linksym(ngotype(nam));
-       p->to.sym = nil;
-       p->to.type = TYPE_CONST;
-       p->to.offset = nam->type->width;
-       if(nam->readonly)
-               p->from3.offset = RODATA;
-       if(nam->type != T && !haspointers(nam->type))
-               p->from3.offset |= NOPTR;
-}
-
-void
-ggloblsym(Sym *s, int32 width, int8 flags)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->to.type = TYPE_CONST;
-       p->to.name = NAME_NONE;
-       p->to.offset = width;
-       p->from3.offset = flags;
-}
-
-void
-gtrack(Sym *s)
-{
-       Prog *p;
-       
-       p = gins(AUSEFIELD, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-}
-
-int
-isfat(Type *t)
-{
-       if(t != T)
-       switch(t->etype) {
-       case TSTRUCT:
-       case TARRAY:
-       case TSTRING:
-       case TINTER:    // maybe remove later
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * naddr of func generates code for address of func.
- * if using opcode that can take address implicitly,
- * call afunclit to fix up the argument.
- * also fix up direct register references to be TYPE_MEM.
- */
-void
-afunclit(Addr *a, Node *n)
-{
-       if(a->type == TYPE_ADDR && a->name == NAME_EXTERN || a->type == TYPE_REG) {
-               a->type = TYPE_MEM;
-               if(n->op == ONAME)
-                       a->sym = linksym(n->sym);
-       }
-}
-
 static int     resvd[] =
 {
        9,     // reserved for m
@@ -426,101 +203,6 @@ regfree(Node *n)
                regpc[i] = 0;
 }
 
-/*
- * initialize n to be register r of type t.
- */
-void
-nodreg(Node *n, Type *t, int r)
-{
-       if(t == T)
-               fatal("nodreg: t nil");
-
-       memset(n, 0, sizeof(*n));
-       n->op = OREGISTER;
-       n->addable = 1;
-       ullmancalc(n);
-       n->val.u.reg = r;
-       n->type = t;
-}
-
-/*
- * initialize n to be indirect of register r; n is type t.
- */
-void
-nodindreg(Node *n, Type *t, int r)
-{
-       nodreg(n, t, r);
-       n->op = OINDREG;
-}
-
-Node*
-nodarg(Type *t, int fp)
-{
-       Node *n;
-       NodeList *l;
-       Type *first;
-       Iter savet;
-
-       // entire argument struct, not just one arg
-       if(t->etype == TSTRUCT && t->funarg) {
-               n = nod(ONAME, N, N);
-               n->sym = lookup(".args");
-               n->type = t;
-               first = structfirst(&savet, &t);
-               if(first == nil)
-                       fatal("nodarg: bad struct");
-               if(first->width == BADWIDTH)
-                       fatal("nodarg: offset not computed for %T", t);
-               n->xoffset = first->width;
-               n->addable = 1;
-               goto fp;
-       }
-
-       if(t->etype != TFIELD)
-               fatal("nodarg: not field %T", t);
-
-       if(fp == 1) {
-               for(l=curfn->dcl; l; l=l->next) {
-                       n = l->n;
-                       if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
-                               return n;
-               }
-       }
-
-       n = nod(ONAME, N, N);
-       n->type = t->type;
-       n->sym = t->sym;
-       if(t->width == BADWIDTH)
-               fatal("nodarg: offset not computed for %T", t);
-       n->xoffset = t->width;
-       n->addable = 1;
-       n->orig = t->nname;
-
-fp:
-       // Rewrite argument named _ to __,
-       // or else the assignment to _ will be
-       // discarded during code generation.
-       if(isblank(n))
-               n->sym = lookup("__");
-
-       switch(fp) {
-       default:
-               fatal("nodarg %T %d", t, fp);
-
-       case 0:         // output arg for calling another function
-               n->op = OINDREG;
-               n->val.u.reg = REGSP;
-               n->xoffset += 4;
-               break;
-
-       case 1:         // input arg to current function
-               n->class = PPARAM;
-               break;
-       }
-       n->typecheck = 1;
-       return n;
-}
-
 /*
  * return constant i node.
  * overwritten by next call, but useful in calls to gins.
@@ -536,22 +218,6 @@ ncon(uint32 i)
        return &n;
 }
 
-/*
- * Is this node a memory operand?
- */
-int
-ismem(Node *n)
-{
-       switch(n->op) {
-       case OINDREG:
-       case ONAME:
-       case OPARAM:
-       case OCLOSUREVAR:
-               return 1;
-       }
-       return 0;
-}
-
 Node sclean[10];
 int nsclean;
 
@@ -1181,228 +847,6 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
        return p;
 }
 
-/*
- * generate code to compute n;
- * make a refer to result.
- */
-void
-naddr(Node *n, Addr *a, int canemitcode)
-{
-       Sym *s;
-
-       a->type = TYPE_NONE;
-       a->name = NAME_NONE;
-       a->reg = 0;
-       a->gotype = nil;
-       a->node = N;
-       a->etype = 0;
-       if(n == N)
-               return;
-
-       if(n->type != T && n->type->etype != TIDEAL) {
-               dowidth(n->type);
-               a->width = n->type->width;
-       }
-
-       switch(n->op) {
-       default:
-               fatal("naddr: bad %O %D", n->op, a);
-               break;
-
-       case OREGISTER:
-               a->type = TYPE_REG;
-               a->reg = n->val.u.reg;
-               a->sym = nil;
-               break;
-
-       case OINDEX:
-       case OIND:
-               fatal("naddr: OINDEX");
-//             naddr(n->left, a);
-//             if(a->type >= D_AX && a->type <= D_DI)
-//                     a->type += D_INDIR;
-//             else
-//             if(a->type == TYPE_ADDR)
-//                     a->type = TYPE_NONE+D_INDIR;
-//             else
-//             if(a->type == TYPE_ADDR) {
-//                     a->type = a->index;
-//                     a->index = TYPE_NONE;
-//             } else
-//                     goto bad;
-//             if(n->op == OINDEX) {
-//                     a->index = idx.reg;
-//                     a->scale = n->scale;
-//             }
-//             break;
-
-       case OINDREG:
-               a->type = TYPE_MEM;
-               a->reg = n->val.u.reg;
-               a->sym = linksym(n->sym);
-               a->offset = n->xoffset;
-               break;
-
-       case OPARAM:
-               // n->left is PHEAP ONAME for stack parameter.
-               // compute address of actual parameter on stack.
-               a->etype = simtype[n->left->type->etype];
-               a->width = n->left->type->width;
-               a->offset = n->xoffset;
-               a->sym = linksym(n->left->sym);
-               a->type = TYPE_MEM;
-               a->name = NAME_PARAM;
-               a->node = n->left->orig;
-               break;
-       
-       case OCLOSUREVAR:
-               if(!curfn->needctxt)
-                       fatal("closurevar without needctxt");
-               a->type = TYPE_MEM;
-               a->reg = REG_R7;
-               a->offset = n->xoffset;
-               a->sym = nil;
-               break;          
-
-       case OCFUNC:
-               naddr(n->left, a, canemitcode);
-               a->sym = linksym(n->left->sym);
-               break;
-
-       case ONAME:
-               a->etype = 0;
-               a->width = 0;
-               a->reg = 0;
-               if(n->type != T) {
-                       a->etype = simtype[n->type->etype];
-                       a->width = n->type->width;
-               }
-               a->offset = n->xoffset;
-               s = n->sym;
-               a->node = n->orig;
-               //if(a->node >= (Node*)&n)
-               //      fatal("stack node");
-               if(s == S)
-                       s = lookup(".noname");
-               if(n->method) {
-                       if(n->type != T)
-                       if(n->type->sym != S)
-                       if(n->type->sym->pkg != nil)
-                               s = pkglookup(s->name, n->type->sym->pkg);
-               }
-
-               a->type = TYPE_MEM;
-               switch(n->class) {
-               default:
-                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
-               case PEXTERN:
-                       a->name = NAME_EXTERN;
-                       break;
-               case PAUTO:
-                       a->name = NAME_AUTO;
-                       break;
-               case PPARAM:
-               case PPARAMOUT:
-                       a->name = NAME_PARAM;
-                       break;
-               case PFUNC:
-                       a->name = NAME_EXTERN;
-                       a->type = TYPE_ADDR;
-                       s = funcsym(s);
-                       break;
-               }
-               a->sym = linksym(s);
-               break;
-
-       case OLITERAL:
-               switch(n->val.ctype) {
-               default:
-                       fatal("naddr: const %lT", n->type);
-                       break;
-               case CTFLT:
-                       a->type = TYPE_FCONST;
-                       a->u.dval = mpgetflt(n->val.u.fval);
-                       break;
-               case CTINT:
-               case CTRUNE:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = mpgetfix(n->val.u.xval);
-                       break;
-               case CTSTR:
-                       datagostring(n->val.u.sval, a);
-                       break;
-               case CTBOOL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = n->val.u.bval;
-                       break;
-               case CTNIL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = 0;
-                       break;
-               }
-               break;
-
-       case OITAB:
-               // itable of interface value
-               naddr(n->left, a, canemitcode);
-               a->etype = simtype[tptr];
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->width = widthptr;
-               break;
-
-       case OSPTR:
-               // pointer in a string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // ptr(nil)
-               a->etype = simtype[tptr];
-               a->offset += Array_array;
-               a->width = widthptr;
-               break;
-
-       case OLEN:
-               // len of string or slice
-               naddr(n->left, a, canemitcode);
-               a->etype = TINT32;
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->offset += Array_nel;
-               break;
-
-       case OCAP:
-               // cap of string or slice
-               naddr(n->left, a, canemitcode);
-               a->etype = TINT32;
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // cap(nil)
-               a->offset += Array_cap;
-               break;
-
-       case OADDR:
-               naddr(n->left, a, canemitcode);
-               a->etype = tptr;
-               switch(a->type) {
-               case TYPE_MEM:
-                       a->type = TYPE_ADDR;
-                       break;
-
-               case TYPE_REG:
-               case TYPE_ADDR:
-                       break;
-               
-               default:
-                       fatal("naddr: OADDR %d\n", a->type);
-               }
-       }
-       
-       if(a->width < 0)
-               fatal("naddr: bad width for %N -> %D", n, a);
-}
-
 /*
  * return Axxx for Oxxx on type t.
  */
index 93090ebe42dc695f3a73cc7fd34a215a4dd3e8af..ec21c6abf7a8ccf5f31bf309c517f1929116f5a0 100644 (file)
@@ -725,7 +725,7 @@ mkvar(Reg *r, Adr *a)
        flag = 0;
        switch(t) {
        default:
-               print("type %d %d %D\n", t, a->name, a);
+               print("mkvar: type %d %d %D\n", t, a->name, a);
                goto none;
 
        case TYPE_NONE:
index fa1dcc34e8a73f2044cf09b2d5fe58a7710c3a7e..a266a6b87c661f80e84896742756821e10d938c5 100644 (file)
@@ -91,6 +91,7 @@ enum
        REGG = REGEXT-0,
        REGM = REGEXT-1,
 
+       REGCTXT = REG_R7,
        REGTMP = REG_R11,
        REGSP = REG_R13,
        REGLINK = REG_R14,
index 83833e189b5f24b960367074a928fb6ecf60f095..58de9ae7bc9748316af3fedd469327f062e5e559 100644 (file)
@@ -69,8 +69,9 @@ main(int argc, char **argv)
        arch.thestring = thestring;
        arch.thelinkarch = thelinkarch;
        arch.typedefs = typedefs;
+       arch.REGSP = REGSP;
+       arch.REGCTXT = REGCTXT;
        arch.MAXWIDTH = MAXWIDTH;
-       arch.afunclit = afunclit;
        arch.anyregalloc = anyregalloc;
        arch.betypeinit = betypeinit;
        arch.bgen = bgen;
@@ -80,37 +81,15 @@ main(int argc, char **argv)
        arch.cgen_callinter = cgen_callinter;
        arch.cgen_ret = cgen_ret;
        arch.clearfat = clearfat;
-       arch.clearp = clearp;
-       arch.defframe = defframe;
-       arch.dgostringptr = dgostringptr;
-       arch.dgostrlitptr = dgostrlitptr;
-       arch.dsname = dsname;
-       arch.dsymptr = dsymptr;
-       arch.dumpdata = dumpdata;
        arch.dumpit = dumpit;
        arch.excise = excise;
        arch.expandchecks = expandchecks;
-       arch.fixautoused = fixautoused;
        arch.gclean = gclean;
-       arch.gdata = gdata;
-       arch.gdatacomplex = gdatacomplex;
-       arch.gdatastring = gdatastring;
-       arch.ggloblnod = ggloblnod;
-       arch.ggloblsym = ggloblsym;
        arch.ginit = ginit;
        arch.gins = gins;
        arch.ginscall = ginscall;
-       arch.gjmp = gjmp;
-       arch.gtrack = gtrack;
-       arch.gused = gused;
        arch.igen = igen;
-       arch.isfat = isfat;
        arch.linkarchinit = linkarchinit;
-       arch.markautoused = markautoused;
-       arch.naddr = naddr;
-       arch.newplist = newplist;
-       arch.nodarg = nodarg;
-       arch.patch = patch;
        arch.proginfo = proginfo;
        arch.regalloc = regalloc;
        arch.regfree = regfree;
@@ -119,7 +98,6 @@ main(int argc, char **argv)
        arch.sameaddr = sameaddr;
        arch.smallindir = smallindir;
        arch.stackaddr = stackaddr;
-       arch.unpatch = unpatch;
        
        gcmain(argc, argv);
 }
index 7a09f673ef1e85994057637b349e03dccc8bb1a9..0167a3fa0f9c5b4a94e780c9064c813584c06e1c 100644 (file)
@@ -9,10 +9,7 @@
 #include "../gc/go.h"
 #include "../6l/6.out.h"
 
-EXTERN int32   dynloc;
 EXTERN uchar   reg[MAXREG];
-EXTERN int32   pcloc;          // instruction counter
-EXTERN Strlit  emptystring;
 EXTERN Node*   panicdiv;
 extern vlong   unmappedzero;
 extern int     addptr;
index 9f4b4d4ae391b3d8022d8ee6d669791e6585d2e1..f1d5cf2c1d3fa712e7ab6f7823d9bddd69c2c9e2 100644 (file)
@@ -115,52 +115,6 @@ appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int tre
        return q;       
 }
 
-// Sweep the prog list to mark any used nodes.
-void
-markautoused(Prog* p)
-{
-       for (; p; p = p->link) {
-               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
-                       continue;
-
-               if (p->from.node)
-                       ((Node*)(p->from.node))->used = 1;
-
-               if (p->to.node)
-                       ((Node*)(p->to.node))->used = 1;
-       }
-}
-
-// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
-void
-fixautoused(Prog *p)
-{
-       Prog **lp;
-
-       for (lp=&p; (p=*lp) != P; ) {
-               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
-                       *lp = p->link;
-                       continue;
-               }
-               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
-                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
-                       // VARDEFs are interspersed with other code, and a jump might be using the
-                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
-                       // the no-ops.
-                       nopout(p);
-                       continue;
-               }
-               if (p->from.name == NAME_AUTO && p->from.node)
-                       p->from.offset += ((Node*)(p->from.node))->stkdelta;
-
-               if (p->to.name == NAME_AUTO && p->to.node)
-                       p->to.offset += ((Node*)(p->to.node))->stkdelta;
-
-               lp = &p->link;
-       }
-}
-
-
 /*
  * generate:
  *     call f
@@ -616,20 +570,6 @@ ret:
        ;
 }
 
-int
-samereg(Node *a, Node *b)
-{
-       if(a == N || b == N)
-               return 0;
-       if(a->op != OREGISTER)
-               return 0;
-       if(b->op != OREGISTER)
-               return 0;
-       if(a->val.u.reg != b->val.u.reg)
-               return 0;
-       return 1;
-}
-
 /*
  * generate division.
  * generates one of:
diff --git a/src/cmd/6g/gobj.c b/src/cmd/6g/gobj.c
deleted file mode 100644 (file)
index 33ee4d6..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-// Derived from Inferno utils/6c/swt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-int
-dsname(Sym *s, int off, char *t, int n)
-{
-       Prog *p;
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.offset = off;
-       p->from.sym = linksym(s);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = n;
-       
-       p->to.type = TYPE_SCONST;
-       memmove(p->to.u.sval, t, n);
-       return off + n;
-}
-
-/*
- * make a refer to the data s, s+len
- * emitting DATA if needed.
- */
-void
-datastring(char *s, int len, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(s, len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-       a->offset = widthptr+widthint;  // skip header
-       a->etype = simtype[TINT];
-}
-
-/*
- * make a refer to the string sval,
- * emitting DATA if needed.
- */
-void
-datagostring(Strlit *sval, Addr *a)
-{
-       Sym *sym;
-
-       sym = stringsym(sval->s, sval->len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-       a->offset = 0;  // header
-       a->etype = TSTRING;
-}
-
-void
-gdata(Node *nam, Node *nr, int wid)
-{
-       Prog *p;
-
-       if(nr->op == OLITERAL) {
-               switch(nr->val.ctype) {
-               case CTCPLX:
-                       gdatacomplex(nam, nr->val.u.cval);
-                       return;
-               case CTSTR:
-                       gdatastring(nam, nr->val.u.sval);
-                       return;
-               }
-       }
-       p = gins(ADATA, nam, nr);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = wid;
-}
-
-void
-gdatacomplex(Node *nam, Mpcplx *cval)
-{
-       Prog *p;
-       int w;
-
-       w = cplxsubtype(nam->type->etype);
-       w = types[w]->width;
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->real);
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->from.offset += w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->imag);
-}
-
-void
-gdatastring(Node *nam, Strlit *sval)
-{
-       Prog *p;
-       Node nod1;
-
-       p = gins(ADATA, nam, N);
-       datastring(sval->s, sval->len, &p->to);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[tptr]->width;
-       p->to.type = TYPE_ADDR;
-//print("%P\n", p);
-
-       nodconst(&nod1, types[TINT], sval->len);
-       p = gins(ADATA, nam, &nod1);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthint;
-       p->from.offset += widthptr;
-}
-
-int
-dstringptr(Sym *s, int off, char *str)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-
-       datastring(str, strlen(str)+1, &p->to);
-       p->to.type = TYPE_ADDR;
-       p->to.etype = simtype[TINT];
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostrlitptr(Sym *s, int off, Strlit *lit)
-{
-       Prog *p;
-
-       if(lit == nil)
-               return duintptr(s, off, 0);
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       datagostring(lit, &p->to);
-       p->to.type = TYPE_ADDR;
-       p->to.etype = simtype[TINT];
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostringptr(Sym *s, int off, char *str)
-{
-       int n;
-       Strlit *lit;
-
-       if(str == nil)
-               return duintptr(s, off, 0);
-
-       n = strlen(str);
-       lit = mal(sizeof *lit + n);
-       strcpy(lit->s, str);
-       lit->len = n;
-       return dgostrlitptr(s, off, lit);
-}
-
-int
-dsymptr(Sym *s, int off, Sym *x, int xoff)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       p->to.type = TYPE_ADDR;
-       p->to.name = NAME_EXTERN;
-       p->to.sym = linksym(x);
-       p->to.offset = xoff;
-       off += widthptr;
-
-       return off;
-}
-
-void
-nopout(Prog *p)
-{
-       p->as = ANOP;
-       p->from = zprog.from;
-       p->to = zprog.to;
-}
-
index 51409e467b30c67bcbc6e19000ade03b0e4219e0..725ed8f819dce700867136a61cce37c8a980fb55 100644 (file)
 // the text segment up higher in 6l for all GOOS.
 // At the same time, can raise StackBig in ../../runtime/stack.h.
 vlong unmappedzero = 4096;
-
-void
-clearp(Prog *p)
-{
-       p->as = AEND;
-       p->from.type = TYPE_NONE;
-       p->from.index = TYPE_NONE;
-       p->to.type = TYPE_NONE;
-       p->to.index = TYPE_NONE;
-       p->pc = pcloc;
-       pcloc++;
-}
-
-static int ddumped;
-static Prog *dfirst;
-static Prog *dpc;
-
-/*
- * generate and return proc with p->as = as,
- * linked into program. pc is next instruction.
- */
-Prog*
-prog(int as)
-{
-       Prog *p;
-
-       if(as == ADATA || as == AGLOBL) {
-               if(ddumped)
-                       fatal("already dumped data");
-               if(dpc == nil) {
-                       dpc = mal(sizeof(*dpc));
-                       dfirst = dpc;
-               }
-               p = dpc;
-               dpc = mal(sizeof(*dpc));
-               p->link = dpc;
-       } else {
-               p = pc;
-               pc = mal(sizeof(*pc));
-               clearp(pc);
-               p->link = pc;
-       }
-
-       if(lineno == 0) {
-               if(debug['K'])
-                       warn("prog: line 0");
-       }
-
-       p->as = as;
-       p->lineno = lineno;
-       return p;
-}
-
-void
-dumpdata(void)
-{
-       ddumped = 1;
-       if(dfirst == nil)
-               return;
-       newplist();
-       *pc = *dfirst;
-       pc = dpc;
-       clearp(pc);
-}
-
-/*
- * generate a branch.
- * t is ignored.
- * likely values are for branch prediction:
- *     -1 unlikely
- *     0 no opinion
- *     +1 likely
- */
-Prog*
-gbranch(int as, Type *t, int likely)
-{
-       Prog *p;
-       
-       USED(t);
-
-       p = prog(as);
-       p->to.type = TYPE_BRANCH;
-       p->to.u.branch = P;
-       if(as != AJMP && likely != 0) {
-               p->from.type = TYPE_CONST;
-               p->from.offset = likely > 0;
-       }
-       return p;
-}
-
-/*
- * patch previous branch to jump to to.
- */
-void
-patch(Prog *p, Prog *to)
-{
-       if(p->to.type != TYPE_BRANCH)
-               fatal("patch: not a branch");
-       p->to.u.branch = to;
-       p->to.offset = to->pc;
-}
-
-Prog*
-unpatch(Prog *p)
-{
-       Prog *q;
-
-       if(p->to.type != TYPE_BRANCH)
-               fatal("unpatch: not a branch");
-       q = p->to.u.branch;
-       p->to.u.branch = P;
-       p->to.offset = 0;
-       return q;
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-newplist(void)
-{
-       Plist *pl;
-
-       pl = linknewplist(ctxt);
-
-       pc = mal(sizeof(*pc));
-       clearp(pc);
-       pl->firstpc = pc;
-
-       return pl;
-}
-
-void
-gused(Node *n)
-{
-       gins(ANOP, n, N);       // used
-}
-
-Prog*
-gjmp(Prog *to)
-{
-       Prog *p;
-
-       p = gbranch(AJMP, T, 0);
-       if(to != P)
-               patch(p, to);
-       return p;
-}
-
-void
-ggloblnod(Node *nam)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, nam, N);
-       p->lineno = nam->lineno;
-       p->from.sym->gotype = linksym(ngotype(nam));
-       p->to.sym = nil;
-       p->to.type = TYPE_CONST;
-       p->to.offset = nam->type->width;
-       if(nam->readonly)
-               p->from3.offset = RODATA;
-       if(nam->type != T && !haspointers(nam->type))
-               p->from3.offset |= NOPTR;
-}
-
-void
-gtrack(Sym *s)
-{
-       Prog *p;
-       
-       p = gins(AUSEFIELD, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int8 flags)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->to.type = TYPE_CONST;
-       p->to.offset = width;
-       p->from3.offset = flags;
-}
-
-int
-isfat(Type *t)
-{
-       if(t != T)
-       switch(t->etype) {
-       case TSTRUCT:
-       case TARRAY:
-       case TSTRING:
-       case TINTER:    // maybe remove later
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * naddr of func generates code for address of func.
- * if using opcode that can take address implicitly,
- * call afunclit to fix up the argument.
- */
-void
-afunclit(Addr *a, Node *n)
-{
-       if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
-               a->type = TYPE_MEM;
-               a->sym = linksym(n->sym);
-       }
-}
-
 static int     resvd[] =
 {
        REG_DI, // for movstring
@@ -421,105 +202,6 @@ regfree(Node *n)
                regpc[i - REG_AX] = 0;
 }
 
-/*
- * initialize n to be register r of type t.
- */
-void
-nodreg(Node *n, Type *t, int r)
-{
-       if(t == T)
-               fatal("nodreg: t nil");
-
-       memset(n, 0, sizeof(*n));
-       n->op = OREGISTER;
-       n->addable = 1;
-       ullmancalc(n);
-       n->val.u.reg = r;
-       n->type = t;
-}
-
-/*
- * initialize n to be indirect of register r; n is type t.
- */
-void
-nodindreg(Node *n, Type *t, int r)
-{
-       nodreg(n, t, r);
-       n->op = OINDREG;
-}
-
-Node*
-nodarg(Type *t, int fp)
-{
-       Node *n;
-       NodeList *l;
-       Type *first;
-       Iter savet;
-
-       // entire argument struct, not just one arg
-       if(t->etype == TSTRUCT && t->funarg) {
-               n = nod(ONAME, N, N);
-               n->sym = lookup(".args");
-               n->type = t;
-               first = structfirst(&savet, &t);
-               if(first == nil)
-                       fatal("nodarg: bad struct");
-               if(first->width == BADWIDTH)
-                       fatal("nodarg: offset not computed for %T", t);
-               n->xoffset = first->width;
-               n->addable = 1;
-               goto fp;
-       }
-
-       if(t->etype != TFIELD)
-               fatal("nodarg: not field %T", t);
-       
-       if(fp == 1) {
-               for(l=curfn->dcl; l; l=l->next) {
-                       n = l->n;
-                       if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
-                               return n;
-               }
-       }
-
-       n = nod(ONAME, N, N);
-       n->type = t->type;
-       n->sym = t->sym;
-       
-       if(t->width == BADWIDTH)
-               fatal("nodarg: offset not computed for %T", t);
-       n->xoffset = t->width;
-       n->addable = 1;
-       n->orig = t->nname;
-
-fp:
-       // Rewrite argument named _ to __,
-       // or else the assignment to _ will be
-       // discarded during code generation.
-       if(isblank(n))
-               n->sym = lookup("__");
-
-       switch(fp) {
-       case 0:         // output arg
-               n->op = OINDREG;
-               n->val.u.reg = REG_SP;
-               break;
-
-       case 1:         // input arg
-               n->class = PPARAM;
-               break;
-
-       case 2:         // offset output arg
-fatal("shouldn't be used");
-               n->op = OINDREG;
-               n->val.u.reg = REG_SP;
-               n->xoffset += types[tptr]->width;
-               break;
-       }
-       n->typecheck = 1;
-       return n;
-}
-
 /*
  * generate
  *     as $c, reg
@@ -576,27 +258,6 @@ ginscon(int as, vlong c, Node *n2)
 #define        CASE(a,b)       (((a)<<16)|((b)<<0))
 /*c2go int CASE(int, int); */
 
-/*
- * Is this node a memory operand?
- */
-int
-ismem(Node *n)
-{
-       switch(n->op) {
-       case OITAB:
-       case OSPTR:
-       case OLEN:
-       case OCAP:
-       case OINDREG:
-       case ONAME:
-       case OPARAM:
-       case OCLOSUREVAR:
-       case OADDR:
-               return 1;
-       }
-       return 0;
-}
-
 /*
  * set up nodes representing 2^63
  */
@@ -1111,213 +772,6 @@ fixlargeoffset(Node *n)
        }
 }
 
-/*
- * generate code to compute n;
- * make a refer to result.
- */
-void
-naddr(Node *n, Addr *a, int canemitcode)
-{
-       Sym *s;
-
-       a->scale = 0;
-       a->reg = REG_NONE;
-       a->index = REG_NONE;
-       a->type = TYPE_NONE;
-       a->name = NAME_NONE;
-       a->gotype = nil;
-       a->node = N;
-       a->width = 0;
-       if(n == N)
-               return;
-
-       if(n->type != T && n->type->etype != TIDEAL) {
-               dowidth(n->type);
-               a->width = n->type->width;
-       }
-
-       switch(n->op) {
-       default:
-               fatal("naddr: bad %O %D", n->op, a);
-               break;
-
-       case OREGISTER:
-               a->type = TYPE_REG;
-               a->reg = n->val.u.reg;
-               a->sym = nil;
-               break;
-
-       case OINDREG:
-               a->type = TYPE_MEM;
-               a->reg = n->val.u.reg;
-               a->sym = linksym(n->sym);
-               a->offset = n->xoffset;
-               if(a->offset != (int32)a->offset)
-                       yyerror("offset %lld too large for OINDREG", a->offset);
-               break;
-
-       case OPARAM:
-               // n->left is PHEAP ONAME for stack parameter.
-               // compute address of actual parameter on stack.
-               a->etype = simtype[n->left->type->etype];
-               a->width = n->left->type->width;
-               a->offset = n->xoffset;
-               a->sym = linksym(n->left->sym);
-               a->type = TYPE_MEM;
-               a->name = NAME_PARAM;
-               a->node = n->left->orig;
-               break;
-       
-       case OCLOSUREVAR:
-               if(!curfn->needctxt)
-                       fatal("closurevar without needctxt");
-               a->type = TYPE_MEM;
-               a->reg = REG_DX;
-               a->sym = nil;
-               a->offset = n->xoffset;
-               break;
-       
-       case OCFUNC:
-               naddr(n->left, a, canemitcode);
-               a->sym = linksym(n->left->sym);
-               break;
-
-       case ONAME:
-               a->etype = 0;
-               if(n->type != T)
-                       a->etype = simtype[n->type->etype];
-               a->offset = n->xoffset;
-               s = n->sym;
-               a->node = n->orig;
-               //if(a->node >= (Node*)&n)
-               //      fatal("stack node");
-               if(s == S)
-                       s = lookup(".noname");
-               if(n->method) {
-                       if(n->type != T)
-                       if(n->type->sym != S)
-                       if(n->type->sym->pkg != nil)
-                               s = pkglookup(s->name, n->type->sym->pkg);
-               }
-
-               a->type = TYPE_MEM;
-               switch(n->class) {
-               default:
-                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
-               case PEXTERN:
-                       a->name = NAME_EXTERN;
-                       break;
-               case PAUTO:
-                       a->name = NAME_AUTO;
-                       break;
-               case PPARAM:
-               case PPARAMOUT:
-                       a->name = NAME_PARAM;
-                       break;
-               case PFUNC:
-                       a->name = NAME_EXTERN;
-                       a->type = TYPE_ADDR;
-                       a->width = widthptr;
-                       s = funcsym(s);                 
-                       break;
-               }
-               a->sym = linksym(s);
-               break;
-
-       case OLITERAL:
-               switch(n->val.ctype) {
-               default:
-                       fatal("naddr: const %lT", n->type);
-                       break;
-               case CTFLT:
-                       a->type = TYPE_FCONST;
-                       a->u.dval = mpgetflt(n->val.u.fval);
-                       break;
-               case CTINT:
-               case CTRUNE:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = mpgetfix(n->val.u.xval);
-                       break;
-               case CTSTR:
-                       datagostring(n->val.u.sval, a);
-                       break;
-               case CTBOOL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = n->val.u.bval;
-                       break;
-               case CTNIL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = 0;
-                       break;
-               }
-               break;
-
-       case OADDR:
-               naddr(n->left, a, canemitcode);
-               a->width = widthptr;
-               if(a->type != TYPE_MEM)
-                       fatal("naddr: OADDR %D", a);
-               a->type = TYPE_ADDR;
-               break;
-       
-       case OITAB:
-               // itable of interface value
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // itab(nil)
-               a->etype = tptr;
-               a->width = widthptr;
-               break;
-
-       case OSPTR:
-               // pointer in a string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // ptr(nil)
-               a->etype = simtype[tptr];
-               a->offset += Array_array;
-               a->width = widthptr;
-               break;
-
-       case OLEN:
-               // len of string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->etype = simtype[TUINT];
-               a->offset += Array_nel;
-               a->width = widthint;
-               break;
-
-       case OCAP:
-               // cap of string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // cap(nil)
-               a->etype = simtype[TUINT];
-               a->offset += Array_cap;
-               a->width = widthint;
-               break;
-
-//     case OADD:
-//             if(n->right->op == OLITERAL) {
-//                     v = n->right->vconst;
-//                     naddr(n->left, a, canemitcode);
-//             } else
-//             if(n->left->op == OLITERAL) {
-//                     v = n->left->vconst;
-//                     naddr(n->right, a, canemitcode);
-//             } else
-//                     goto bad;
-//             a->offset += v;
-//             break;
-
-       }
-}
-
 /*
  * return Axxx for Oxxx on type t.
  */
index 01d9bb753500b40fed6bcd336655f6449ae969ac..e25c6efec8a02a349bd14b93ab276fe07a78bce1 100644 (file)
@@ -834,6 +834,7 @@ enum
        FREGRET         = REG_X0,
        REGSP           = REG_SP,
        REGTMP          = REG_DI,
+       REGCTXT         = REG_DX,
        REGEXT          = REG_R15,      /* compiler allocates external registers R15 down */
        FREGMIN         = REG_X0+5,     /* first register variable */
        FREGEXT         = REG_X0+15,    /* first external register */
index 83c323516d68942b7ec0d85eddd35bd1893ff194..c06552c02d172faeb2fd71009551260c54ed8765 100644 (file)
@@ -46,8 +46,9 @@ main(int argc, char **argv)
        arch.thestring = thestring;
        arch.thelinkarch = thelinkarch;
        arch.typedefs = typedefs;
+       arch.REGSP = REGSP;
+       arch.REGCTXT = REGCTXT;
        arch.MAXWIDTH = MAXWIDTH;
-       arch.afunclit = afunclit;
        arch.anyregalloc = anyregalloc;
        arch.betypeinit = betypeinit;
        arch.bgen = bgen;
@@ -57,37 +58,15 @@ main(int argc, char **argv)
        arch.cgen_callinter = cgen_callinter;
        arch.cgen_ret = cgen_ret;
        arch.clearfat = clearfat;
-       arch.clearp = clearp;
-       arch.defframe = defframe;
-       arch.dgostringptr = dgostringptr;
-       arch.dgostrlitptr = dgostrlitptr;
-       arch.dsname = dsname;
-       arch.dsymptr = dsymptr;
-       arch.dumpdata = dumpdata;
        arch.dumpit = dumpit;
        arch.excise = excise;
        arch.expandchecks = expandchecks;
-       arch.fixautoused = fixautoused;
        arch.gclean = gclean;
-       arch.gdata = gdata;
-       arch.gdatacomplex = gdatacomplex;
-       arch.gdatastring = gdatastring;
-       arch.ggloblnod = ggloblnod;
-       arch.ggloblsym = ggloblsym;
        arch.ginit = ginit;
        arch.gins = gins;
        arch.ginscall = ginscall;
-       arch.gjmp = gjmp;
-       arch.gtrack = gtrack;
-       arch.gused = gused;
        arch.igen = igen;
-       arch.isfat = isfat;
        arch.linkarchinit = linkarchinit;
-       arch.markautoused = markautoused;
-       arch.naddr = naddr;
-       arch.newplist = newplist;
-       arch.nodarg = nodarg;
-       arch.patch = patch;
        arch.proginfo = proginfo;
        arch.regalloc = regalloc;
        arch.regfree = regfree;
@@ -96,7 +75,6 @@ main(int argc, char **argv)
        arch.sameaddr = sameaddr;
        arch.smallindir = smallindir;
        arch.stackaddr = stackaddr;
-       arch.unpatch = unpatch;
        
        gcmain(argc, argv);
 }
index b2b1178a522c0b5d28bb96f724a1ceda0d1348fe..5217cdc2306144de7233010fe3ffeb39b5b36cb4 100644 (file)
@@ -17,10 +17,7 @@ enum
        Fpop2 = 1<<2,
 };
 
-EXTERN int32   dynloc;
 EXTERN uchar   reg[MAXREG];
-EXTERN int32   pcloc;          // instruction counter
-EXTERN Strlit  emptystring;
 EXTERN Node*   panicdiv;
 extern uint32  unmappedzero;
 
index 2fd4a601ff793450b73c3c6bfa8bcbc79fa5636a..475a5fd0e4c0859a5ae2b485d101fd47fd2bca9d 100644 (file)
@@ -106,52 +106,6 @@ appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int tre
        return q;       
 }
 
-// Sweep the prog list to mark any used nodes.
-void
-markautoused(Prog* p)
-{
-       for (; p; p = p->link) {
-               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
-                       continue;
-
-               if (p->from.node)
-                       ((Node*)(p->from.node))->used = 1;
-
-               if (p->to.node)
-                       ((Node*)(p->to.node))->used = 1;
-       }
-}
-
-// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
-void
-fixautoused(Prog* p)
-{
-       Prog **lp;
-
-       for (lp=&p; (p=*lp) != P; ) {
-               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
-                       *lp = p->link;
-                       continue;
-               }
-               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
-                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
-                       // VARDEFs are interspersed with other code, and a jump might be using the
-                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
-                       // the no-ops.
-                       nopout(p);
-                       continue;
-               }
-
-               if (p->from.type == TYPE_MEM && p->from.name == NAME_AUTO && p->from.node)
-                       p->from.offset += ((Node*)(p->from.node))->stkdelta;
-
-               if (p->to.type == TYPE_MEM && p->to.name == NAME_AUTO && p->to.node)
-                       p->to.offset += ((Node*)(p->to.node))->stkdelta;
-
-               lp = &p->link;
-       }
-}
-
 void
 clearfat(Node *nl)
 {
@@ -660,18 +614,6 @@ ret:
        ;
 }
 
-int
-samereg(Node *a, Node *b)
-{
-       if(a->op != OREGISTER)
-               return 0;
-       if(b->op != OREGISTER)
-               return 0;
-       if(a->val.u.reg != b->val.u.reg)
-               return 0;
-       return 1;
-}
-
 /*
  * generate division.
  * caller must set:
diff --git a/src/cmd/8g/gobj.c b/src/cmd/8g/gobj.c
deleted file mode 100644 (file)
index b59d226..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-// Derived from Inferno utils/8c/swt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8c/swt.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-int
-dsname(Sym *s, int off, char *t, int n)
-{
-       Prog *p;
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = n;
-       p->from.sym = linksym(s);
-       
-       p->to.type = TYPE_SCONST;
-       memmove(p->to.u.sval, t, n);
-       return off + n;
-}
-
-/*
- * make a refer to the data s, s+len
- * emitting DATA if needed.
- */
-void
-datastring(char *s, int len, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(s, len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-       a->offset = widthptr+4;  // skip header
-       a->etype = TINT32;
-}
-
-/*
- * make a refer to the string sval,
- * emitting DATA if needed.
- */
-void
-datagostring(Strlit *sval, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(sval->s, sval->len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-       a->offset = 0;  // header
-       a->etype = TSTRING;
-}
-
-void
-gdata(Node *nam, Node *nr, int wid)
-{
-       Prog *p;
-       vlong v;
-
-       if(nr->op == OLITERAL) {
-               switch(nr->val.ctype) {
-               case CTCPLX:
-                       gdatacomplex(nam, nr->val.u.cval);
-                       return;
-               case CTSTR:
-                       gdatastring(nam, nr->val.u.sval);
-                       return;
-               }
-       }
-
-       if(wid == 8 && is64(nr->type)) {
-               v = mpgetfix(nr->val.u.xval);
-               p = gins(ADATA, nam, nodintconst(v));
-               p->from3.type = TYPE_CONST;
-               p->from3.offset = 4;
-               p = gins(ADATA, nam, nodintconst(v>>32));
-               p->from3.type = TYPE_CONST;
-               p->from3.offset = 4;
-               p->from.offset += 4;
-               return;
-       }
-       p = gins(ADATA, nam, nr);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = wid;
-}
-
-void
-gdatacomplex(Node *nam, Mpcplx *cval)
-{
-       Prog *p;
-       int w;
-
-       w = cplxsubtype(nam->type->etype);
-       w = types[w]->width;
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->real);
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->from.offset += w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->imag);
-}
-
-void
-gdatastring(Node *nam, Strlit *sval)
-{
-       Prog *p;
-       Node nod1;
-
-       p = gins(ADATA, nam, N);
-       datastring(sval->s, sval->len, &p->to);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[tptr]->width;
-       p->to.type = TYPE_ADDR;
-//print("%P\n", p);
-
-       nodconst(&nod1, types[TINT32], sval->len);
-       p = gins(ADATA, nam, &nod1);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[TINT32]->width;
-       p->from.offset += types[tptr]->width;
-}
-
-int
-dstringptr(Sym *s, int off, char *str)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-
-       datastring(str, strlen(str)+1, &p->to);
-       p->to.type = TYPE_ADDR;
-       p->to.etype = TINT32;
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostrlitptr(Sym *s, int off, Strlit *lit)
-{
-       Prog *p;
-
-       if(lit == nil)
-               return duintptr(s, off, 0);
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       datagostring(lit, &p->to);
-       p->to.type = TYPE_ADDR;
-       p->to.etype = TINT32;
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostringptr(Sym *s, int off, char *str)
-{
-       int n;
-       Strlit *lit;
-
-       if(str == nil)
-               return duintptr(s, off, 0);
-
-       n = strlen(str);
-       lit = mal(sizeof *lit + n);
-       strcpy(lit->s, str);
-       lit->len = n;
-       return dgostrlitptr(s, off, lit);
-}
-
-int
-dsymptr(Sym *s, int off, Sym *x, int xoff)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       p->to.type = TYPE_ADDR;
-       p->to.name = NAME_EXTERN;
-       p->to.sym = linksym(x);
-       p->to.offset = xoff;
-       off += widthptr;
-
-       return off;
-}
-
-void
-nopout(Prog *p)
-{
-       p->as = ANOP;
-       p->from = zprog.from;
-       p->to = zprog.to;
-}
-
index af1963f9807fc313b79436b2c6f2d97a5183c059..76c8e2d14fdabf908a99ef45907bd97c80258a24 100644 (file)
@@ -41,225 +41,6 @@ uint32 unmappedzero = 4096;
 #define        CASE(a,b)       (((a)<<16)|((b)<<0))
 /*c2go int CASE(int, int);*/
 
-void
-clearp(Prog *p)
-{
-       p->as = AEND;
-       p->from.type = TYPE_NONE;
-       p->from.index = TYPE_NONE;
-       p->to.type = TYPE_NONE;
-       p->to.index = TYPE_NONE;
-       p->pc = pcloc;
-       pcloc++;
-}
-
-static int ddumped;
-static Prog *dfirst;
-static Prog *dpc;
-
-/*
- * generate and return proc with p->as = as,
- * linked into program.  pc is next instruction.
- */
-Prog*
-prog(int as)
-{
-       Prog *p;
-
-       if(as == ADATA || as == AGLOBL) {
-               if(ddumped)
-                       fatal("already dumped data");
-               if(dpc == nil) {
-                       dpc = mal(sizeof(*dpc));
-                       dfirst = dpc;
-               }
-               p = dpc;
-               dpc = mal(sizeof(*dpc));
-               p->link = dpc;
-       } else {
-               p = pc;
-               pc = mal(sizeof(*pc));
-               clearp(pc);
-               p->link = pc;
-       }
-
-       if(lineno == 0) {
-               if(debug['K'])
-                       warn("prog: line 0");
-       }
-
-       p->as = as;
-       p->lineno = lineno;
-       return p;
-}
-
-void
-dumpdata(void)
-{
-       ddumped = 1;
-       if(dfirst == nil)
-               return;
-       newplist();
-       *pc = *dfirst;
-       pc = dpc;
-       clearp(pc);
-}
-
-/*
- * generate a branch.
- * t is ignored.
- * likely values are for branch prediction:
- *     -1 unlikely
- *     0 no opinion
- *     +1 likely
- */
-Prog*
-gbranch(int as, Type *t, int likely)
-{
-       Prog *p;
-
-       USED(t);
-       p = prog(as);
-       p->to.type = TYPE_BRANCH;
-       p->to.u.branch = P;
-       if(likely != 0) {
-               p->from.type = TYPE_CONST;
-               p->from.offset = likely > 0;
-       }
-       return p;
-}
-
-/*
- * patch previous branch to jump to to.
- */
-void
-patch(Prog *p, Prog *to)
-{
-       if(p->to.type != TYPE_BRANCH)
-               fatal("patch: not a branch");
-       p->to.u.branch = to;
-       p->to.offset = to->pc;
-}
-
-Prog*
-unpatch(Prog *p)
-{
-       Prog *q;
-
-       if(p->to.type != TYPE_BRANCH)
-               fatal("unpatch: not a branch");
-       q = p->to.u.branch;
-       p->to.u.branch = P;
-       p->to.offset = 0;
-       return q;
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-newplist(void)
-{
-       Plist *pl;
-
-       pl = linknewplist(ctxt);
-       
-       pc = mal(sizeof(*pc));
-       clearp(pc);
-       pl->firstpc = pc;
-
-       return pl;
-}
-
-void
-gused(Node *n)
-{
-       gins(ANOP, n, N);       // used
-}
-
-Prog*
-gjmp(Prog *to)
-{
-       Prog *p;
-
-       p = gbranch(AJMP, T, 0);
-       if(to != P)
-               patch(p, to);
-       return p;
-}
-
-void
-ggloblnod(Node *nam)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, nam, N);
-       p->lineno = nam->lineno;
-       p->from.sym->gotype = linksym(ngotype(nam));
-       p->to.sym = nil;
-       p->to.type = TYPE_CONST;
-       p->to.offset = nam->type->width;
-       if(nam->readonly)
-               p->from3.offset = RODATA;
-       if(nam->type != T && !haspointers(nam->type))
-               p->from3.offset |= NOPTR;
-}
-
-void
-ggloblsym(Sym *s, int32 width, int8 flags)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.index = REG_NONE;
-       p->from.sym = linksym(s);
-       p->to.type = TYPE_CONST;
-       p->to.index = REG_NONE;
-       p->to.offset = width;
-       p->from3.offset = flags;
-}
-
-void
-gtrack(Sym *s)
-{
-       Prog *p;
-       
-       p = gins(AUSEFIELD, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-}
-
-int
-isfat(Type *t)
-{
-       if(t != T)
-       switch(t->etype) {
-       case TSTRUCT:
-       case TARRAY:
-       case TSTRING:
-       case TINTER:    // maybe remove later
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * naddr of func generates code for address of func.
- * if using opcode that can take address implicitly,
- * call afunclit to fix up the argument.
- */
-void
-afunclit(Addr *a, Node *n)
-{
-       if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
-               a->type = TYPE_MEM;
-               a->sym = linksym(n->sym);
-       }
-}
-
 /*
  * return Axxx for Oxxx on type t.
  */
@@ -1001,105 +782,6 @@ regfree(Node *n)
                fatal("regfree %R", i);
 }
 
-/*
- * initialize n to be register r of type t.
- */
-void
-nodreg(Node *n, Type *t, int r)
-{
-       if(t == T)
-               fatal("nodreg: t nil");
-
-       memset(n, 0, sizeof(*n));
-       n->op = OREGISTER;
-       n->addable = 1;
-       ullmancalc(n);
-       n->val.u.reg = r;
-       n->type = t;
-}
-
-/*
- * initialize n to be indirect of register r; n is type t.
- */
-void
-nodindreg(Node *n, Type *t, int r)
-{
-       nodreg(n, t, r);
-       n->op = OINDREG;
-}
-
-Node*
-nodarg(Type *t, int fp)
-{
-       Node *n;
-       NodeList *l;
-       Type *first;
-       Iter savet;
-
-       // entire argument struct, not just one arg
-       switch(t->etype) {
-       default:
-               fatal("nodarg %T", t);
-
-       case TSTRUCT:
-               if(!t->funarg)
-                       fatal("nodarg: TSTRUCT but not funarg");
-               n = nod(ONAME, N, N);
-               n->sym = lookup(".args");
-               n->type = t;
-               first = structfirst(&savet, &t);
-               if(first == nil)
-                       fatal("nodarg: bad struct");
-               if(first->width == BADWIDTH)
-                       fatal("nodarg: offset not computed for %T", t);
-               n->xoffset = first->width;
-               n->addable = 1;
-               break;
-
-       case TFIELD:
-               if(fp == 1 && t->sym != S && !isblanksym(t->sym)) {
-                       for(l=curfn->dcl; l; l=l->next) {
-                               n = l->n;
-                               if((n->class == PPARAM || n->class == PPARAMOUT) && n->sym == t->sym)
-                                       return n;
-                       }
-               }
-
-               n = nod(ONAME, N, N);
-               n->type = t->type;
-               n->sym = t->sym;
-               if(t->width == BADWIDTH)
-                       fatal("nodarg: offset not computed for %T", t);
-               n->xoffset = t->width;
-               n->addable = 1;
-               n->orig = t->nname;
-               break;
-       }
-       
-       // Rewrite argument named _ to __,
-       // or else the assignment to _ will be
-       // discarded during code generation.
-       if(isblank(n))
-               n->sym = lookup("__");
-
-       switch(fp) {
-       default:
-               fatal("nodarg %T %d", t, fp);
-
-       case 0:         // output arg
-               n->op = OINDREG;
-               n->val.u.reg = REG_SP;
-               break;
-
-       case 1:         // input arg
-               n->class = PPARAM;
-               break;
-       }
-
-       n->typecheck = 1;
-       return n;
-}
-
 /*
  * generate
  *     as $c, reg
@@ -1142,26 +824,6 @@ ncon(uint32 i)
        return &n;
 }
 
-/*
- * Is this node a memory operand?
- */
-int
-ismem(Node *n)
-{
-       switch(n->op) {
-       case OITAB:
-       case OSPTR:
-       case OLEN:
-       case OCAP:
-       case OINDREG:
-       case ONAME:
-       case OPARAM:
-       case OCLOSUREVAR:
-               return 1;
-       }
-       return 0;
-}
-
 Node sclean[10];
 int nsclean;
 
@@ -1408,8 +1070,8 @@ gmove(Node *f, Node *t)
                        gins(AMOVL, &flo, &tlo);
                        gins(AMOVL, &fhi, &thi);
                } else {
-                       nodreg(&r1, t->type, REG_AX);
-                       nodreg(&r2, t->type, REG_DX);
+                       nodreg(&r1, types[TUINT32], REG_AX);
+                       nodreg(&r2, types[TUINT32], REG_DX);
                        gins(AMOVL, &flo, &r1);
                        gins(AMOVL, &fhi, &r2);
                        gins(AMOVL, &r1, &tlo);
@@ -2165,209 +1827,6 @@ gins(int as, Node *f, Node *t)
        return p;
 }
 
-/*
- * generate code to compute n;
- * make a refer to result.
- */
-void
-naddr(Node *n, Addr *a, int canemitcode)
-{
-       Sym *s;
-
-       a->scale = 0;
-       a->reg = REG_NONE;
-       a->index = REG_NONE;
-       a->type = TYPE_NONE;
-       a->name = NAME_NONE;
-       a->gotype = nil;
-       a->node = N;
-       if(n == N)
-               return;
-
-       switch(n->op) {
-       default:
-               fatal("naddr: bad %O %D", n->op, a);
-               break;
-
-       case OREGISTER:
-               a->type = TYPE_REG;
-               a->reg = n->val.u.reg;
-               a->sym = nil;
-               break;
-
-       case OINDREG:
-               a->type = TYPE_MEM;
-               a->reg = n->val.u.reg;
-               a->sym = linksym(n->sym);
-               a->offset = n->xoffset;
-               break;
-
-       case OPARAM:
-               // n->left is PHEAP ONAME for stack parameter.
-               // compute address of actual parameter on stack.
-               a->etype = n->left->type->etype;
-               a->width = n->left->type->width;
-               a->offset = n->xoffset;
-               a->sym = linksym(n->left->sym);
-               a->type = TYPE_MEM;
-               a->name = NAME_PARAM;
-               a->node = n->left->orig;
-               break;
-
-       case OCLOSUREVAR:
-               if(!curfn->needctxt)
-                       fatal("closurevar without needctxt");
-               a->type = TYPE_MEM;
-               a->reg = REG_DX;
-               a->offset = n->xoffset;
-               a->sym = nil;
-               break;
-
-       case OCFUNC:
-               naddr(n->left, a, canemitcode);
-               a->sym = linksym(n->left->sym);
-               break;
-
-       case ONAME:
-               a->etype = 0;
-               a->width = 0;
-               if(n->type != T) {
-                       a->etype = simtype[n->type->etype];
-                       dowidth(n->type);
-                       a->width = n->type->width;
-               }
-               a->offset = n->xoffset;
-               s = n->sym;
-               a->node = n->orig;
-               //if(a->node >= (Node*)&n)
-               //      fatal("stack node");
-               if(s == S)
-                       s = lookup(".noname");
-               if(n->method) {
-                       if(n->type != T)
-                       if(n->type->sym != S)
-                       if(n->type->sym->pkg != nil)
-                               s = pkglookup(s->name, n->type->sym->pkg);
-               }
-
-               switch(n->class) {
-               default:
-                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
-               case PEXTERN:
-                       a->type = TYPE_MEM;
-                       a->name = NAME_EXTERN;
-                       break;
-               case PAUTO:
-                       a->type = TYPE_MEM;
-                       a->name = NAME_AUTO;
-                       break;
-               case PPARAM:
-               case PPARAMOUT:
-                       a->type = TYPE_MEM;
-                       a->name = NAME_PARAM;
-                       break;
-               case PFUNC:
-                       a->type = TYPE_ADDR;
-                       a->name = NAME_EXTERN;
-                       s = funcsym(s);
-                       break;
-               }
-               a->sym = linksym(s);
-               break;
-
-       case OLITERAL:
-               switch(n->val.ctype) {
-               default:
-                       fatal("naddr: const %lT", n->type);
-                       break;
-               case CTFLT:
-                       a->type = TYPE_FCONST;
-                       a->u.dval = mpgetflt(n->val.u.fval);
-                       break;
-               case CTINT:
-               case CTRUNE:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = mpgetfix(n->val.u.xval);
-                       break;
-               case CTSTR:
-                       datagostring(n->val.u.sval, a);
-                       break;
-               case CTBOOL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = n->val.u.bval;
-                       break;
-               case CTNIL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = 0;
-                       break;
-               }
-               break;
-
-       case OADDR:
-               naddr(n->left, a, canemitcode);
-               if(a->type != TYPE_MEM)
-                       fatal("naddr: OADDR %D", a);
-               a->type = TYPE_ADDR;
-               break;
-       
-       case OITAB:
-               // itable of interface value
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->etype = tptr;
-               a->width = widthptr;
-               break;
-
-       case OSPTR:
-               // pointer in a string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // ptr(nil)
-               a->etype = simtype[tptr];
-               a->offset += Array_array;
-               a->width = widthptr;
-               break;
-
-       case OLEN:
-               // len of string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->etype = TUINT32;
-               a->offset += Array_nel;
-               a->width = 4;
-               break;
-
-       case OCAP:
-               // cap of string or slice
-               naddr(n->left, a, canemitcode);
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // cap(nil)
-               a->etype = TUINT32;
-               a->offset += Array_cap;
-               a->width = 4;
-               break;
-
-//     case OADD:
-//             if(n->right->op == OLITERAL) {
-//                     v = n->right->vconst;
-//                     naddr(n->left, a, canemitcode);
-//             } else
-//             if(n->left->op == OLITERAL) {
-//                     v = n->left->vconst;
-//                     naddr(n->right, a, canemitcode);
-//             } else
-//                     goto bad;
-//             a->offset += v;
-//             break;
-
-       }
-}
-
 int
 dotaddable(Node *n, Node *n1)
 {
index 28d7dab7fb12a6a884fb23494af1a3b833e5a345..273a8ad523a4fb881fd48848252d980557e274ba 100644 (file)
@@ -634,6 +634,7 @@ enum
        FREGRET         = REG_F0,
        REGSP           = REG_SP,
        REGTMP          = REG_DI,
+       REGCTXT         = REG_DX,
 };
 
 /*
index df4291e90e6d1376070fe9fb1a9038c0758a6f26..71c869fe4e3bed5e5b4b0b98e5be9643d18f6fc2 100644 (file)
@@ -53,8 +53,9 @@ main(int argc, char **argv)
        arch.thestring = thestring;
        arch.thelinkarch = thelinkarch;
        arch.typedefs = typedefs;
+       arch.REGSP = REGSP;
+       arch.REGCTXT = REGCTXT;
        arch.MAXWIDTH = MAXWIDTH;
-       arch.afunclit = afunclit;
        arch.anyregalloc = anyregalloc;
        arch.betypeinit = betypeinit;
        arch.bgen = bgen;
@@ -64,37 +65,15 @@ main(int argc, char **argv)
        arch.cgen_callinter = cgen_callinter;
        arch.cgen_ret = cgen_ret;
        arch.clearfat = clearfat;
-       arch.clearp = clearp;
-       arch.defframe = defframe;
-       arch.dgostringptr = dgostringptr;
-       arch.dgostrlitptr = dgostrlitptr;
-       arch.dsname = dsname;
-       arch.dsymptr = dsymptr;
-       arch.dumpdata = dumpdata;
        arch.dumpit = dumpit;
        arch.excise = excise;
        arch.expandchecks = expandchecks;
-       arch.fixautoused = fixautoused;
        arch.gclean = gclean;
-       arch.gdata = gdata;
-       arch.gdatacomplex = gdatacomplex;
-       arch.gdatastring = gdatastring;
-       arch.ggloblnod = ggloblnod;
-       arch.ggloblsym = ggloblsym;
        arch.ginit = ginit;
        arch.gins = gins;
        arch.ginscall = ginscall;
-       arch.gjmp = gjmp;
-       arch.gtrack = gtrack;
-       arch.gused = gused;
        arch.igen = igen;
-       arch.isfat = isfat;
        arch.linkarchinit = linkarchinit;
-       arch.markautoused = markautoused;
-       arch.naddr = naddr;
-       arch.newplist = newplist;
-       arch.nodarg = nodarg;
-       arch.patch = patch;
        arch.proginfo = proginfo;
        arch.regalloc = regalloc;
        arch.regfree = regfree;
@@ -103,7 +82,6 @@ main(int argc, char **argv)
        arch.sameaddr = sameaddr;
        arch.smallindir = smallindir;
        arch.stackaddr = stackaddr;
-       arch.unpatch = unpatch;
        
        gcmain(argc, argv);
 }
index 367a858e860b1f8fa51b001161347b33291b289e..bf5d00299eeb703aed3d7f3706c11c4fe4cdefb2 100644 (file)
 // TODO(minux): Remove when no longer used.
 #define noimpl sysfatal("%s not implemented (%s:%d).", __func__, __FILE__, __LINE__)
 
-EXTERN int32   dynloc;
 EXTERN uchar   reg[NREG+NFREG];
-EXTERN int32   pcloc;          // instruction counter
-EXTERN Strlit  emptystring;
 EXTERN Node*   panicdiv;
 extern vlong   unmappedzero;
 
index 3865051018e0e5d7b2332adba10edd3b8fd33288..0340e1d7c2d4a065f42df6b9923228e69acec1af 100644 (file)
@@ -113,51 +113,6 @@ appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int tre
        return q;
 }
 
-// Sweep the prog list to mark any used nodes.
-void
-markautoused(Prog *p)
-{
-       for (; p; p = p->link) {
-               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
-                       continue;
-
-               if (p->from.node)
-                       ((Node*)(p->from.node))->used = 1;
-
-               if (p->to.node)
-                       ((Node*)(p->to.node))->used = 1;
-       }
-}
-
-// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
-void
-fixautoused(Prog *p)
-{
-       Prog **lp;
-
-       for (lp=&p; (p=*lp) != P; ) {
-               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
-                       *lp = p->link;
-                       continue;
-               }
-               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
-                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
-                       // VARDEFs are interspersed with other code, and a jump might be using the
-                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
-                       // the no-ops.
-                       nopout(p);
-                       continue;
-               }
-               if (p->from.name == NAME_AUTO && p->from.node)
-                       p->from.offset += ((Node*)(p->from.node))->stkdelta;
-
-               if (p->to.name == NAME_AUTO && p->to.node)
-                       p->to.offset += ((Node*)(p->to.node))->stkdelta;
-
-               lp = &p->link;
-       }
-}
-
 /*
  * generate: BL reg, f
  * where both reg and f are registers.
@@ -226,7 +181,7 @@ ginscall(Node *f, int proc)
                                gins(AUNDEF, N, N);
                        break;
                }
-               nodreg(&reg, types[tptr], REGENV);
+               nodreg(&reg, types[tptr], REGCTXT);
                nodreg(&r1, types[tptr], REG_R3);
                gmove(f, &reg);
                reg.op = OINDREG;
@@ -494,20 +449,6 @@ cgen_asop(Node *n)
        fatal("cgen_asop"); // no longer used
 }
 
-int
-samereg(Node *a, Node *b)
-{
-       if(a == N || b == N)
-               return 0;
-       if(a->op != OREGISTER)
-               return 0;
-       if(b->op != OREGISTER)
-               return 0;
-       if(a->val.u.reg != b->val.u.reg)
-               return 0;
-       return 1;
-}
-
 /*
  * generate division.
  * generates one of:
diff --git a/src/cmd/9g/gobj.c b/src/cmd/9g/gobj.c
deleted file mode 100644 (file)
index 35e4f45..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-// Derived from Inferno utils/6c/swt.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-int
-dsname(Sym *s, int off, char *t, int n)
-{
-       Prog *p;
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.offset = off;
-       p->from.sym = linksym(s);
-
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = n;
-       
-       p->to.type = TYPE_SCONST;
-       p->to.name = NAME_NONE;
-       p->to.offset = 0;
-       memmove(p->to.u.sval, t, n);
-       return off + n;
-}
-
-/*
- * make a refer to the data s, s+len
- * emitting DATA if needed.
- */
-void
-datastring(char *s, int len, Addr *a)
-{
-       Sym *sym;
-       
-       sym = stringsym(s, len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->etype = simtype[TINT];
-       a->offset = widthptr+widthint;  // skip header
-       a->reg = 0;
-       a->sym = linksym(sym);
-       a->node = sym->def;
-}
-
-/*
- * make a refer to the string sval,
- * emitting DATA if needed.
- */
-void
-datagostring(Strlit *sval, Addr *a)
-{
-       Sym *sym;
-
-       sym = stringsym(sval->s, sval->len);
-       a->type = TYPE_MEM;
-       a->name = NAME_EXTERN;
-       a->sym = linksym(sym);
-       a->reg = 0;
-       a->node = sym->def;
-       a->offset = 0;  // header
-       a->etype = TSTRING;
-}
-
-void
-gdata(Node *nam, Node *nr, int wid)
-{
-       Prog *p;
-
-       if(nr->op == OLITERAL) {
-               switch(nr->val.ctype) {
-               case CTCPLX:
-                       gdatacomplex(nam, nr->val.u.cval);
-                       return;
-               case CTSTR:
-                       gdatastring(nam, nr->val.u.sval);
-                       return;
-               }
-       }
-       p = gins(ADATA, nam, nr);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = wid;
-}
-
-void
-gdatacomplex(Node *nam, Mpcplx *cval)
-{
-       Prog *p;
-       int w;
-
-       w = cplxsubtype(nam->type->etype);
-       w = types[w]->width;
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->real);
-
-       p = gins(ADATA, nam, N);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = w;
-       p->from.offset += w;
-       p->to.type = TYPE_FCONST;
-       p->to.u.dval = mpgetflt(&cval->imag);
-}
-
-void
-gdatastring(Node *nam, Strlit *sval)
-{
-       Prog *p;
-       Node nod1;
-
-       p = gins(ADATA, nam, N);
-       datastring(sval->s, sval->len, &p->to);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = types[tptr]->width;
-       p->to.type = TYPE_ADDR;
-       p->to.etype = simtype[tptr];
-
-       nodconst(&nod1, types[TINT], sval->len);
-       p = gins(ADATA, nam, &nod1);
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthint;
-       p->from.offset += widthptr;
-}
-
-int
-dstringptr(Sym *s, int off, char *str)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-
-       datastring(str, strlen(str)+1, &p->to);
-       p->to.type = TYPE_CONST;
-       p->to.etype = simtype[TINT];
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostrlitptr(Sym *s, int off, Strlit *lit)
-{
-       Prog *p;
-
-       if(lit == nil)
-               return duintptr(s, off, 0);
-
-       off = rnd(off, widthptr);
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       datagostring(lit, &p->to);
-       p->to.type = TYPE_ADDR;
-       p->to.etype = simtype[TINT];
-       off += widthptr;
-
-       return off;
-}
-
-int
-dgostringptr(Sym *s, int off, char *str)
-{
-       int n;
-       Strlit *lit;
-
-       if(str == nil)
-               return duintptr(s, off, 0);
-
-       n = strlen(str);
-       lit = mal(sizeof *lit + n);
-       strcpy(lit->s, str);
-       lit->len = n;
-       return dgostrlitptr(s, off, lit);
-}
-
-int
-dsymptr(Sym *s, int off, Sym *x, int xoff)
-{
-       Prog *p;
-
-       off = rnd(off, widthptr);
-
-       p = gins(ADATA, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->from.offset = off;
-       p->from3.type = TYPE_CONST;
-       p->from3.offset = widthptr;
-       p->to.type = TYPE_ADDR;
-       p->to.name = NAME_EXTERN;
-       p->to.sym = linksym(x);
-       p->to.offset = xoff;
-       off += widthptr;
-
-       return off;
-}
-
-void
-nopout(Prog *p)
-{
-       p->as = ANOP;
-       p->from = zprog.from;
-       p->from3 = zprog.from3;
-       p->reg = zprog.reg;
-       p->to = zprog.to;
-}
index 073324ee12143932d85adbbe77b9012e80e2b9fa..e01b587031e65a4ce2543249b7f02f084a6f5b34 100644 (file)
 // At the same time, can raise StackBig in ../../runtime/stack.h.
 vlong unmappedzero = 4096;
 
-void
-clearp(Prog *p)
-{
-       *p = zprog;
-       p->as = AEND;
-       p->pc = pcloc;
-       pcloc++;
-}
-
-static int ddumped;
-static Prog *dfirst;
-static Prog *dpc;
-
-/*
- * generate and return proc with p->as = as,
- * linked into program. pc is next instruction.
- */
-Prog*
-prog(int as)
-{
-       Prog *p;
-
-       if(as == ADATA || as == AGLOBL) {
-               if(ddumped)
-                       fatal("already dumped data");
-               if(dpc == nil) {
-                       dpc = mal(sizeof(*dpc));
-                       dfirst = dpc;
-               }
-               p = dpc;
-               dpc = mal(sizeof(*dpc));
-               p->link = dpc;
-               p->reg = 0; // used for flags
-       } else {
-               p = pc;
-               pc = mal(sizeof(*pc));
-               clearp(pc);
-               p->link = pc;
-       }
-
-       if(lineno == 0) {
-               if(debug['K'])
-                       warn("prog: line 0");
-       }
-
-       p->as = as;
-       p->lineno = lineno;
-       return p;
-}
-
-void
-dumpdata(void)
-{
-       ddumped = 1;
-       if(dfirst == nil)
-               return;
-       newplist();
-       *pc = *dfirst;
-       pc = dpc;
-       clearp(pc);
-}
-
-/*
- * generate a branch.
- * t is ignored.
- * likely values are for branch prediction:
- *     -1 unlikely
- *     0 no opinion
- *     +1 likely
- */
-Prog*
-gbranch(int as, Type *t, int likely)
-{
-       Prog *p;
-       
-       USED(t);
-
-       p = prog(as);
-       p->to.type = TYPE_BRANCH;
-       p->to.u.branch = P;
-       // TODO(minux): Enable this code.
-       // Note: liblink used Bcc CR0, label form, so we need another way
-       // to set likely/unlikely flag. Also note the y bit is not exactly
-       // likely/unlikely bit.
-       if(0 && as != ABR && likely != 0) {
-               p->from.type = TYPE_CONST;
-               p->from.offset = likely > 0;
-       }
-       return p;
-}
-
-/*
- * patch previous branch to jump to to.
- */
-void
-patch(Prog *p, Prog *to)
-{
-       if(p->to.type != TYPE_BRANCH)
-               fatal("patch: not a branch");
-       p->to.u.branch = to;
-       p->to.offset = to->pc;
-}
-
-Prog*
-unpatch(Prog *p)
-{
-       Prog *q;
-
-       if(p->to.type != TYPE_BRANCH)
-               fatal("unpatch: not a branch");
-       q = p->to.u.branch;
-       p->to.u.branch = P;
-       p->to.offset = 0;
-       return q;
-}
-
-/*
- * start a new Prog list.
- */
-Plist*
-newplist(void)
-{
-       Plist *pl;
-
-       pl = linknewplist(ctxt);
-
-       pc = mal(sizeof(*pc));
-       clearp(pc);
-       pl->firstpc = pc;
-
-       return pl;
-}
-
-void
-gused(Node *n)
-{
-       gins(ANOP, n, N);       // used
-}
-
-Prog*
-gjmp(Prog *to)
-{
-       Prog *p;
-
-       p = gbranch(ABR, T, 0);
-       if(to != P)
-               patch(p, to);
-       return p;
-}
-
-void
-ggloblnod(Node *nam)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, nam, N);
-       p->lineno = nam->lineno;
-       p->from.sym->gotype = linksym(ngotype(nam));
-       p->to.sym = nil;
-       p->to.type = TYPE_CONST;
-       p->to.offset = nam->type->width;
-       if(nam->readonly)
-               p->from3.offset = RODATA;
-       if(nam->type != T && !haspointers(nam->type))
-               p->from3.offset |= NOPTR;
-}
-
-void
-gtrack(Sym *s)
-{
-       Prog *p;
-       
-       p = gins(AUSEFIELD, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int8 flags)
-{
-       Prog *p;
-
-       p = gins(AGLOBL, N, N);
-       p->from.type = TYPE_MEM;
-       p->from.name = NAME_EXTERN;
-       p->from.sym = linksym(s);
-       p->to.type = TYPE_CONST;
-       p->to.name = NAME_NONE;
-       p->to.offset = width;
-       p->from3.offset = flags;
-}
-
-int
-isfat(Type *t)
-{
-       if(t != T)
-       switch(t->etype) {
-       case TSTRUCT:
-       case TARRAY:
-       case TSTRING:
-       case TINTER:    // maybe remove later
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * naddr of func generates code for address of func.
- * if using opcode that can take address implicitly,
- * call afunclit to fix up the argument.
- */
-void
-afunclit(Addr *a, Node *n)
-{
-       if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
-               a->type = TYPE_MEM;
-               a->sym = linksym(n->sym);
-       }
-}
-
 static int     resvd[] =
 {
        REGZERO,
@@ -431,109 +210,6 @@ regfree(Node *n)
                regpc[i] = 0;
 }
 
-/*
- * initialize n to be register r of type t.
- */
-void
-nodreg(Node *n, Type *t, int r)
-{
-       if(t == T)
-               fatal("nodreg: t nil");
-
-       memset(n, 0, sizeof(*n));
-       n->op = OREGISTER;
-       n->addable = 1;
-       ullmancalc(n);
-       n->val.u.reg = r;
-       n->type = t;
-}
-
-/*
- * initialize n to be indirect of register r; n is type t.
- */
-void
-nodindreg(Node *n, Type *t, int r)
-{
-       nodreg(n, t, r);
-       n->op = OINDREG;
-}
-
-Node*
-nodarg(Type *t, int fp)
-{
-       Node *n;
-       NodeList *l;
-       Type *first;
-       Iter savet;
-
-       // entire argument struct, not just one arg
-       if(t->etype == TSTRUCT && t->funarg) {
-               n = nod(ONAME, N, N);
-               n->sym = lookup(".args");
-               n->type = t;
-               first = structfirst(&savet, &t);
-               if(first == nil)
-                       fatal("nodarg: bad struct");
-               if(first->width == BADWIDTH)
-                       fatal("nodarg: offset not computed for %T", t);
-               n->xoffset = first->width;
-               n->addable = 1;
-               goto fp;
-       }
-
-       if(t->etype != TFIELD)
-               fatal("nodarg: not field %T", t);
-       
-       if(fp == 1) {
-               for(l=curfn->dcl; l; l=l->next) {
-                       n = l->n;
-                       if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
-                               return n;
-               }
-       }
-
-       n = nod(ONAME, N, N);
-       n->type = t->type;
-       n->sym = t->sym;
-       
-       if(t->width == BADWIDTH)
-               fatal("nodarg: offset not computed for %T", t);
-       n->xoffset = t->width;
-       n->addable = 1;
-       n->orig = t->nname;
-
-fp:
-       // Rewrite argument named _ to __,
-       // or else the assignment to _ will be
-       // discarded during code generation.
-       if(isblank(n))
-               n->sym = lookup("__");
-
-       switch(fp) {
-       default:
-               fatal("nodarg %T %d", t, fp);
-
-       case 0:         // output arg for calling another function
-               n->op = OINDREG;
-               n->val.u.reg = REGSP;
-               n->xoffset += 8;
-               break;
-
-       case 1:         // input arg to current function
-               n->class = PPARAM;
-               break;
-
-       case 2:         // offset output arg
-fatal("shouldn't be used");
-               n->op = OINDREG;
-               n->val.u.reg = REGSP;
-               n->xoffset += types[tptr]->width;
-               break;
-       }
-       n->typecheck = 1;
-       return n;
-}
-
 /*
  * generate
  *     as $c, n
@@ -594,27 +270,6 @@ ginscon2(int as, Node *n2, vlong c)
 #define        CASE(a,b)       (((a)<<16)|((b)<<0))
 /*c2go int CASE(int, int); */
 
-/*
- * Is this node a memory operand?
- */
-int
-ismem(Node *n)
-{
-       switch(n->op) {
-       case OITAB:
-       case OSPTR:
-       case OLEN:
-       case OCAP:
-       case OINDREG:
-       case ONAME:
-       case OPARAM:
-       case OCLOSUREVAR:
-       case OADDR:
-               return 1;
-       }
-       return 0;
-}
-
 /*
  * set up nodes representing 2^63
  */
@@ -1089,208 +744,6 @@ fixlargeoffset(Node *n)
        }
 }
 
-/*
- * generate code to compute n;
- * make a refer to result.
- */
-void
-naddr(Node *n, Addr *a, int canemitcode)
-{
-       Sym *s;
-
-       a->type = TYPE_NONE;
-       a->name = NAME_NONE;
-       a->reg = 0;
-       a->gotype = nil;
-       a->node = N;
-       a->etype = 0;
-       a->width = 0;
-       if(n == N)
-               return;
-
-       if(n->type != T && n->type->etype != TIDEAL) {
-               dowidth(n->type);
-               a->width = n->type->width;
-       }
-
-       switch(n->op) {
-       default:
-               fatal("naddr: bad %O %D", n->op, a);
-               break;
-
-       case ONAME:
-               a->etype = 0;
-               a->reg = 0;
-               if(n->type != T)
-                       a->etype = simtype[n->type->etype];
-               a->offset = n->xoffset;
-               s = n->sym;
-               a->node = n->orig;
-               //if(a->node >= (Node*)&n)
-               //      fatal("stack node");
-               if(s == S)
-                       s = lookup(".noname");
-               if(n->method) {
-                       if(n->type != T)
-                       if(n->type->sym != S)
-                       if(n->type->sym->pkg != nil)
-                               s = pkglookup(s->name, n->type->sym->pkg);
-               }
-
-               a->type = TYPE_MEM;
-               switch(n->class) {
-               default:
-                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
-               case PEXTERN:
-                       a->name = NAME_EXTERN;
-                       break;
-               case PAUTO:
-                       a->name = NAME_AUTO;
-                       break;
-               case PPARAM:
-               case PPARAMOUT:
-                       a->name = NAME_PARAM;
-                       break;
-               case PFUNC:
-                       a->name = NAME_EXTERN;
-                       a->type = TYPE_ADDR;
-                       a->width = widthptr;
-                       s = funcsym(s);
-                       break;
-               }
-               a->sym = linksym(s);
-               break;
-
-       case OLITERAL:
-               switch(n->val.ctype) {
-               default:
-                       fatal("naddr: const %lT", n->type);
-                       break;
-               case CTFLT:
-                       a->type = TYPE_FCONST;
-                       a->u.dval = mpgetflt(n->val.u.fval);
-                       break;
-               case CTINT:
-               case CTRUNE:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = mpgetfix(n->val.u.xval);
-                       break;
-               case CTSTR:
-                       datagostring(n->val.u.sval, a);
-                       break;
-               case CTBOOL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = n->val.u.bval;
-                       break;
-               case CTNIL:
-                       a->sym = nil;
-                       a->type = TYPE_CONST;
-                       a->offset = 0;
-                       break;
-               }
-               break;
-
-       case OREGISTER:
-               a->type = TYPE_REG;
-               a->reg = n->val.u.reg;
-               a->sym = nil;
-               break;
-
-       case OINDREG:
-               a->type = TYPE_MEM;
-               a->reg = n->val.u.reg;
-               a->sym = linksym(n->sym);
-               a->offset = n->xoffset;
-               if(a->offset != (int32)a->offset)
-                       yyerror("offset %lld too large for OINDREG", a->offset);
-               break;
-
-       case OPARAM:
-               // n->left is PHEAP ONAME for stack parameter.
-               // compute address of actual parameter on stack.
-               a->etype = simtype[n->left->type->etype];
-               a->width = n->left->type->width;
-               a->offset = n->xoffset;
-               a->sym = linksym(n->left->sym);
-               a->type = TYPE_MEM;
-               a->name = NAME_PARAM;
-               a->node = n->left->orig;
-               break;
-
-       case OCLOSUREVAR:
-               if(!curfn->needctxt)
-                       fatal("closurevar without needctxt");
-               a->type = TYPE_MEM;
-               a->reg = REGENV;
-               a->offset = n->xoffset;
-               a->sym = nil;
-               break;
-
-       case OCFUNC:
-               naddr(n->left, a, canemitcode);
-               a->sym = linksym(n->left->sym);
-               break;
-
-       case OITAB:
-               // itable of interface value
-               naddr(n->left, a, canemitcode);
-               a->etype = simtype[tptr];
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // itab(nil)
-               a->width = widthptr;
-               break;
-
-       case OSPTR:
-               // pointer in a string or slice
-               naddr(n->left, a, canemitcode);
-               a->etype = simtype[tptr];
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // ptr(nil)
-               a->offset += Array_array;
-               a->width = widthptr;
-               break;
-
-       case OLEN:
-               // len of string or slice
-               naddr(n->left, a, canemitcode);
-               a->etype = simtype[TINT];
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // len(nil)
-               a->offset += Array_nel;
-               a->width = widthint;
-               break;
-
-       case OCAP:
-               // cap of string or slice
-               naddr(n->left, a, canemitcode);
-               a->etype = simtype[TINT];
-               if(a->type == TYPE_CONST && a->offset == 0)
-                       break;  // cap(nil)
-               a->offset += Array_cap;
-               a->width = widthint;
-               break;
-
-       case OADDR:
-               naddr(n->left, a, canemitcode);
-               a->etype = tptr;
-               switch(a->type) {
-               case TYPE_MEM:
-                       a->type = TYPE_ADDR;
-                       break;
-
-               case TYPE_REG:
-               case TYPE_CONST:
-                       break;
-
-               default:
-                       fatal("naddr: OADDR %d\n", a->type);
-               }
-               break;
-       }
-}
-
 /*
  * return Axxx for Oxxx on type t.
  */
index b99e7e6f4d5b5d852debff3c33f181784628f96d..6e95698db9dfeec4a7d9efe21f5af136d1b77a0e 100644 (file)
@@ -204,7 +204,7 @@ enum
        REGRT1          = REG_R3,       /* reserved for runtime, duffzero and duffcopy */
        REGRT2          = REG_R4,       /* reserved for runtime, duffcopy */
        REGMIN          = REG_R7,       /* register variables allocated from here to REGMAX */
-       REGENV          = REG_R11,      /* environment for closures */
+       REGCTXT         = REG_R11,      /* context for closures */
        REGTLS          = REG_R13,      /* C ABI TLS base pointer */
        REGMAX          = REG_R27,
        REGEXT          = REG_R30,      /* external registers allocated from here down */
index 20c17bd46a10bc60f0ee8cced31d21fba01c887b..f1a020152b318c0415d1507a4474a47f65546905 100644 (file)
@@ -304,8 +304,8 @@ gen(Node *n)
 
                // if there are pending gotos, resolve them all to the current pc.
                for(p1=lab->gotopc; p1; p1=p2) {
-                       p2 = arch.unpatch(p1);
-                       arch.patch(p1, pc);
+                       p2 = unpatch(p1);
+                       patch(p1, pc);
                }
                lab->gotopc = P;
                if(lab->labelpc == P)
@@ -332,9 +332,9 @@ gen(Node *n)
                // of the label in the OLABEL case above.)
                lab = newlab(n);
                if(lab->labelpc != P)
-                       arch.gjmp(lab->labelpc);
+                       gjmp(lab->labelpc);
                else
-                       lab->gotopc = arch.gjmp(lab->gotopc);
+                       lab->gotopc = gjmp(lab->gotopc);
                break;
 
        case OBREAK:
@@ -349,14 +349,14 @@ gen(Node *n)
                                yyerror("invalid break label %S", n->left->sym);
                                break;
                        }
-                       arch.gjmp(lab->breakpc);
+                       gjmp(lab->breakpc);
                        break;
                }
                if(breakpc == P) {
                        yyerror("break is not in a loop");
                        break;
                }
-               arch.gjmp(breakpc);
+               gjmp(breakpc);
                break;
 
        case OCONTINUE:
@@ -371,20 +371,20 @@ gen(Node *n)
                                yyerror("invalid continue label %S", n->left->sym);
                                break;
                        }
-                       arch.gjmp(lab->continpc);
+                       gjmp(lab->continpc);
                        break;
                }
                if(continpc == P) {
                        yyerror("continue is not in a loop");
                        break;
                }
-               arch.gjmp(continpc);
+               gjmp(continpc);
                break;
 
        case OFOR:
                sbreak = breakpc;
-               p1 = arch.gjmp(P);                      //              goto test
-               breakpc = arch.gjmp(P);         // break:       goto done
+               p1 = gjmp(P);                   //              goto test
+               breakpc = gjmp(P);              // break:       goto done
                scontin = continpc;
                continpc = pc;
 
@@ -394,11 +394,11 @@ gen(Node *n)
                        lab->continpc = continpc;
                }
                gen(n->nincr);                          // contin:      incr
-               arch.patch(p1, pc);                             // test:
+               patch(p1, pc);                          // test:
                arch.bgen(n->ntest, 0, -1, breakpc);            //              if(!test) goto break
                genlist(n->nbody);                              //              body
-               arch.gjmp(continpc);
-               arch.patch(breakpc, pc);                        // done:
+               gjmp(continpc);
+               patch(breakpc, pc);                     // done:
                continpc = scontin;
                breakpc = sbreak;
                if(lab) {
@@ -408,29 +408,29 @@ gen(Node *n)
                break;
 
        case OIF:
-               p1 = arch.gjmp(P);                      //              goto test
-               p2 = arch.gjmp(P);                      // p2:          goto else
-               arch.patch(p1, pc);                             // test:
+               p1 = gjmp(P);                   //              goto test
+               p2 = gjmp(P);                   // p2:          goto else
+               patch(p1, pc);                          // test:
                arch.bgen(n->ntest, 0, -n->likely, p2);         //              if(!test) goto p2
                genlist(n->nbody);                              //              then
-               p3 = arch.gjmp(P);                      //              goto done
-               arch.patch(p2, pc);                             // else:
+               p3 = gjmp(P);                   //              goto done
+               patch(p2, pc);                          // else:
                genlist(n->nelse);                              //              else
-               arch.patch(p3, pc);                             // done:
+               patch(p3, pc);                          // done:
                break;
 
        case OSWITCH:
                sbreak = breakpc;
-               p1 = arch.gjmp(P);                      //              goto test
-               breakpc = arch.gjmp(P);         // break:       goto done
+               p1 = gjmp(P);                   //              goto test
+               breakpc = gjmp(P);              // break:       goto done
 
                // define break label
                if((lab = stmtlabel(n)) != L)
                        lab->breakpc = breakpc;
 
-               arch.patch(p1, pc);                             // test:
+               patch(p1, pc);                          // test:
                genlist(n->nbody);                              //              switch(test) body
-               arch.patch(breakpc, pc);                        // done:
+               patch(breakpc, pc);                     // done:
                breakpc = sbreak;
                if(lab != L)
                        lab->breakpc = P;
@@ -438,16 +438,16 @@ gen(Node *n)
 
        case OSELECT:
                sbreak = breakpc;
-               p1 = arch.gjmp(P);                      //              goto test
-               breakpc = arch.gjmp(P);         // break:       goto done
+               p1 = gjmp(P);                   //              goto test
+               breakpc = gjmp(P);              // break:       goto done
 
                // define break label
                if((lab = stmtlabel(n)) != L)
                        lab->breakpc = breakpc;
 
-               arch.patch(p1, pc);                             // test:
+               patch(p1, pc);                          // test:
                genlist(n->nbody);                              //              select() body
-               arch.patch(breakpc, pc);                        // done:
+               patch(breakpc, pc);                     // done:
                breakpc = sbreak;
                if(lab != L)
                        lab->breakpc = P;
@@ -601,7 +601,7 @@ cgen_discard(Node *nr)
        switch(nr->op) {
        case ONAME:
                if(!(nr->class & PHEAP) && nr->class != PEXTERN && nr->class != PFUNC && nr->class != PPARAMREF)
-                       arch.gused(nr);
+                       gused(nr);
                break;
 
        // unary
@@ -643,7 +643,7 @@ cgen_discard(Node *nr)
        default:
                tempname(&tmp, nr->type);
                cgen_as(&tmp, nr);
-               arch.gused(&tmp);
+               gused(&tmp);
        }
 }
 
@@ -739,7 +739,7 @@ cgen_as(Node *nl, Node *nr)
                tl = nl->type;
                if(tl == T)
                        return;
-               if(arch.isfat(tl)) {
+               if(isfat(tl)) {
                        if(nl->op == ONAME)
                                gvardef(nl);
                        arch.clearfat(nl);
@@ -857,9 +857,9 @@ cgen_slice(Node *n, Node *res)
        // In essence we are replacing x[i:j:k] where i == j == k
        // or x[i:j] where i == j == cap(x) with x[0:0:0].
        if(offs != N) {
-               p1 = arch.gjmp(P);
-               p2 = arch.gjmp(P);
-               arch.patch(p1, pc);
+               p1 = gjmp(P);
+               p2 = gjmp(P);
+               patch(p1, pc);
 
                nodconst(&con, tmpcap->type, 0);
                cmp = nod(OEQ, tmpcap, &con);
@@ -870,7 +870,7 @@ cgen_slice(Node *n, Node *res)
                typecheck(&add, Erv);
                arch.cgen(add, base);
 
-               arch.patch(p2, pc);
+               patch(p2, pc);
        }
 
        // dst.array = src.array  [ + lo *width ]
index c765e063bd110fdd631d901ec68e6fe06e4900de..a89055170e43262548e96a0a473cbefbf4e78155 100644 (file)
@@ -1514,7 +1514,6 @@ void      gvarkill(Node*);
 void   movelarge(NodeList*);
 void   liveness(Node*, Prog*, Sym*, Sym*);
 void   twobitwalktype1(Type*, vlong*, Bvec*);
-void   nopout(Prog*);
 
 #pragma        varargck        type    "B"     Mpint*
 #pragma        varargck        type    "E"     int
@@ -1659,9 +1658,10 @@ struct Arch
        LinkArch *thelinkarch;
        Typedef *typedefs;
 
+       int     REGSP;
+       int     REGCTXT;
        vlong MAXWIDTH;
 
-       void (*afunclit)(Addr*, Node*);
        int (*anyregalloc)(void);
        void (*betypeinit)(void);
        void (*bgen)(Node*, int, int, Prog*);
@@ -1671,37 +1671,15 @@ struct Arch
        void (*cgen_callinter)(Node*, Node*, int);
        void (*cgen_ret)(Node*);
        void (*clearfat)(Node*);
-       void (*clearp)(Prog*);
-       void (*defframe)(Prog*);
-       int (*dgostringptr)(Sym*, int, char*);
-       int (*dgostrlitptr)(Sym*, int, Strlit*);
-       int (*dsname)(Sym*, int, char*, int);
-       int (*dsymptr)(Sym*, int, Sym*, int);
-       void (*dumpdata)(void);
        void (*dumpit)(char*, Flow*, int);
        void (*excise)(Flow*);
        void (*expandchecks)(Prog*);
-       void (*fixautoused)(Prog*);
        void (*gclean)(void);
-       void    (*gdata)(Node*, Node*, int);
-       void    (*gdatacomplex)(Node*, Mpcplx*);
-       void    (*gdatastring)(Node*, Strlit*);
-       void    (*ggloblnod)(Node*);
-       void    (*ggloblsym)(Sym*, int32, int8);
        void (*ginit)(void);
        Prog*   (*gins)(int, Node*, Node*);
        void    (*ginscall)(Node*, int);
-       Prog*   (*gjmp)(Prog*);
-       void (*gtrack)(Sym*);
-       void    (*gused)(Node*);
        void    (*igen)(Node*, Node*, Node*);
-       int (*isfat)(Type*);
        void (*linkarchinit)(void);
-       void (*markautoused)(Prog*);
-       void (*naddr)(Node*, Addr*, int);
-       Plist* (*newplist)(void);
-       Node* (*nodarg)(Type*, int);
-       void (*patch)(Prog*, Prog*);
        void (*proginfo)(ProgInfo*, Prog*);
        void (*regalloc)(Node*, Type*, Node*);
        void (*regfree)(Node*);
@@ -1710,9 +1688,38 @@ struct Arch
        int (*sameaddr)(Addr*, Addr*);
        int (*smallindir)(Addr*, Addr*);
        int (*stackaddr)(Addr*);
-       Prog* (*unpatch)(Prog*);
 };
 
+void afunclit(Addr*, Node*);
+void clearp(Prog*);
+void defframe(Prog*);
+int dgostringptr(Sym*, int, char*);
+int dgostrlitptr(Sym*, int, Strlit*);
+int dsname(Sym*, int, char*, int);
+int dsymptr(Sym*, int, Sym*, int);
+void dumpdata(void);
+void fixautoused(Prog*);
+void   gdata(Node*, Node*, int);
+void   gdatacomplex(Node*, Mpcplx*);
+void   gdatastring(Node*, Strlit*);
+void   ggloblnod(Node*);
+void   ggloblsym(Sym*, int32, int8);
+Prog*  gjmp(Prog*);
+void gtrack(Sym*);
+void   gused(Node*);
+int isfat(Type*);
+void markautoused(Prog*);
+void naddr(Node*, Addr*, int);
+Plist* newplist(void);
+Node* nodarg(Type*, int);
+void patch(Prog*, Prog*);
+Prog* unpatch(Prog*);
+void datagostring(Strlit *sval, Addr *a);
+int ismem(Node*);
+int samereg(Node*, Node*);
+
+EXTERN int32   pcloc;
+
 EXTERN Arch arch;
 
 EXTERN Node *newproc;
diff --git a/src/cmd/gc/gsubr.c b/src/cmd/gc/gsubr.c
new file mode 100644 (file)
index 0000000..c972402
--- /dev/null
@@ -0,0 +1,654 @@
+// Derived from Inferno utils/6c/txt.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.c
+//
+//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+//     Portions Copyright © 1997-1999 Vita Nuova Limited
+//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+//     Portions Copyright © 2004,2006 Bruce Ellis
+//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+#include "../../runtime/funcdata.h"
+#include "../ld/textflag.h"
+
+void
+ggloblnod(Node *nam)
+{
+       Prog *p;
+
+       p = arch.gins(AGLOBL, nam, N);
+       p->lineno = nam->lineno;
+       p->from.sym->gotype = linksym(ngotype(nam));
+       p->to.sym = nil;
+       p->to.type = TYPE_CONST;
+       p->to.offset = nam->type->width;
+       if(nam->readonly)
+               p->from3.offset = RODATA;
+       if(nam->type != T && !haspointers(nam->type))
+               p->from3.offset |= NOPTR;
+}
+
+void
+gtrack(Sym *s)
+{
+       Prog *p;
+       
+       p = arch.gins(AUSEFIELD, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.sym = linksym(s);
+}
+
+void
+ggloblsym(Sym *s, int32 width, int8 flags)
+{
+       Prog *p;
+
+       p = arch.gins(AGLOBL, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.sym = linksym(s);
+       p->to.type = TYPE_CONST;
+       p->to.offset = width;
+       p->from3.offset = flags;
+}
+
+void
+clearp(Prog *p)
+{
+       nopout(p);
+       p->as = AEND;
+       p->pc = pcloc;
+       pcloc++;
+}
+
+static int ddumped;
+static Prog *dfirst;
+static Prog *dpc;
+
+/*
+ * generate and return proc with p->as = as,
+ * linked into program. pc is next instruction.
+ */
+Prog*
+prog(int as)
+{
+       Prog *p;
+
+       if(as == ADATA || as == AGLOBL) {
+               if(ddumped)
+                       fatal("already dumped data");
+               if(dpc == nil) {
+                       dpc = mal(sizeof(*dpc));
+                       dfirst = dpc;
+               }
+               p = dpc;
+               dpc = mal(sizeof(*dpc));
+               p->link = dpc;
+       } else {
+               p = pc;
+               pc = mal(sizeof(*pc));
+               clearp(pc);
+               p->link = pc;
+       }
+
+       if(lineno == 0) {
+               if(debug['K'])
+                       warn("prog: line 0");
+       }
+
+       p->as = as;
+       p->lineno = lineno;
+       return p;
+}
+
+void
+dumpdata(void)
+{
+       ddumped = 1;
+       if(dfirst == nil)
+               return;
+       newplist();
+       *pc = *dfirst;
+       pc = dpc;
+       clearp(pc);
+}
+
+/*
+ * generate a branch.
+ * t is ignored.
+ * likely values are for branch prediction:
+ *     -1 unlikely
+ *     0 no opinion
+ *     +1 likely
+ */
+Prog*
+gbranch(int as, Type *t, int likely)
+{
+       Prog *p;
+       
+       USED(t);
+
+       p = prog(as);
+       p->to.type = TYPE_BRANCH;
+       p->to.u.branch = P;
+       if(as != AJMP && likely != 0 && arch.thechar != '9') {
+               p->from.type = TYPE_CONST;
+               p->from.offset = likely > 0;
+       }
+       return p;
+}
+
+/*
+ * patch previous branch to jump to to.
+ */
+void
+patch(Prog *p, Prog *to)
+{
+       if(p->to.type != TYPE_BRANCH)
+               fatal("patch: not a branch");
+       p->to.u.branch = to;
+       p->to.offset = to->pc;
+}
+
+Prog*
+unpatch(Prog *p)
+{
+       Prog *q;
+
+       if(p->to.type != TYPE_BRANCH)
+               fatal("unpatch: not a branch");
+       q = p->to.u.branch;
+       p->to.u.branch = P;
+       p->to.offset = 0;
+       return q;
+}
+
+/*
+ * start a new Prog list.
+ */
+Plist*
+newplist(void)
+{
+       Plist *pl;
+
+       pl = linknewplist(ctxt);
+
+       pc = mal(sizeof(*pc));
+       clearp(pc);
+       pl->firstpc = pc;
+
+       return pl;
+}
+
+void
+gused(Node *n)
+{
+       arch.gins(ANOP, n, N);  // used
+}
+
+Prog*
+gjmp(Prog *to)
+{
+       Prog *p;
+
+       p = gbranch(AJMP, T, 0);
+       if(to != P)
+               patch(p, to);
+       return p;
+}
+
+int
+isfat(Type *t)
+{
+       if(t != T)
+       switch(t->etype) {
+       case TSTRUCT:
+       case TARRAY:
+       case TSTRING:
+       case TINTER:    // maybe remove later
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * naddr of func generates code for address of func.
+ * if using opcode that can take address implicitly,
+ * call afunclit to fix up the argument.
+ */
+void
+afunclit(Addr *a, Node *n)
+{
+       if(a->type == TYPE_ADDR && a->name == NAME_EXTERN) {
+               a->type = TYPE_MEM;
+               a->sym = linksym(n->sym);
+       }
+}
+
+/*
+ * initialize n to be register r of type t.
+ */
+void
+nodreg(Node *n, Type *t, int r)
+{
+       if(t == T)
+               fatal("nodreg: t nil");
+
+       memset(n, 0, sizeof(*n));
+       n->op = OREGISTER;
+       n->addable = 1;
+       ullmancalc(n);
+       n->val.u.reg = r;
+       n->type = t;
+}
+
+/*
+ * initialize n to be indirect of register r; n is type t.
+ */
+void
+nodindreg(Node *n, Type *t, int r)
+{
+       nodreg(n, t, r);
+       n->op = OINDREG;
+}
+
+/*
+ * Is this node a memory operand?
+ */
+int
+ismem(Node *n)
+{
+       switch(n->op) {
+       case OITAB:
+       case OSPTR:
+       case OLEN:
+       case OCAP:
+       case OINDREG:
+       case ONAME:
+       case OPARAM:
+       case OCLOSUREVAR:
+               return 1;
+       case OADDR:
+               return arch.thechar == '6' || arch.thechar == '9'; // because 6g uses PC-relative addressing; TODO(rsc): not sure why 9g too
+       }
+       return 0;
+}
+
+// Sweep the prog list to mark any used nodes.
+void
+markautoused(Prog* p)
+{
+       for (; p; p = p->link) {
+               if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
+                       continue;
+
+               if (p->from.node)
+                       ((Node*)(p->from.node))->used = 1;
+
+               if (p->to.node)
+                       ((Node*)(p->to.node))->used = 1;
+       }
+}
+
+// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
+void
+fixautoused(Prog *p)
+{
+       Prog **lp;
+
+       for (lp=&p; (p=*lp) != P; ) {
+               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
+                       *lp = p->link;
+                       continue;
+               }
+               if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
+                       // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
+                       // VARDEFs are interspersed with other code, and a jump might be using the
+                       // VARDEF as a target. Replace with a no-op instead. A later pass will remove
+                       // the no-ops.
+                       nopout(p);
+                       continue;
+               }
+               if (p->from.name == NAME_AUTO && p->from.node)
+                       p->from.offset += ((Node*)(p->from.node))->stkdelta;
+
+               if (p->to.name == NAME_AUTO && p->to.node)
+                       p->to.offset += ((Node*)(p->to.node))->stkdelta;
+
+               lp = &p->link;
+       }
+}
+
+int
+samereg(Node *a, Node *b)
+{
+       if(a == N || b == N)
+               return 0;
+       if(a->op != OREGISTER)
+               return 0;
+       if(b->op != OREGISTER)
+               return 0;
+       if(a->val.u.reg != b->val.u.reg)
+               return 0;
+       return 1;
+}
+
+Node*
+nodarg(Type *t, int fp)
+{
+       Node *n;
+       NodeList *l;
+       Type *first;
+       Iter savet;
+
+       // entire argument struct, not just one arg
+       if(t->etype == TSTRUCT && t->funarg) {
+               n = nod(ONAME, N, N);
+               n->sym = lookup(".args");
+               n->type = t;
+               first = structfirst(&savet, &t);
+               if(first == nil)
+                       fatal("nodarg: bad struct");
+               if(first->width == BADWIDTH)
+                       fatal("nodarg: offset not computed for %T", t);
+               n->xoffset = first->width;
+               n->addable = 1;
+               goto fp;
+       }
+
+       if(t->etype != TFIELD)
+               fatal("nodarg: not field %T", t);
+       
+       if(fp == 1) {
+               for(l=curfn->dcl; l; l=l->next) {
+                       n = l->n;
+                       if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
+                               return n;
+               }
+       }
+
+       n = nod(ONAME, N, N);
+       n->type = t->type;
+       n->sym = t->sym;
+       
+       if(t->width == BADWIDTH)
+               fatal("nodarg: offset not computed for %T", t);
+       n->xoffset = t->width;
+       n->addable = 1;
+       n->orig = t->nname;
+
+fp:
+       // Rewrite argument named _ to __,
+       // or else the assignment to _ will be
+       // discarded during code generation.
+       if(isblank(n))
+               n->sym = lookup("__");
+
+       switch(fp) {
+       case 0:         // output arg
+               n->op = OINDREG;
+               n->val.u.reg = arch.REGSP;
+               if(arch.thechar == '5')
+                       n->xoffset += 4;
+               if(arch.thechar == '9')
+                       n->xoffset += 8;
+               break;
+
+       case 1:         // input arg
+               n->class = PPARAM;
+               break;
+
+       case 2:         // offset output arg
+fatal("shouldn't be used");
+               n->op = OINDREG;
+               n->val.u.reg = arch.REGSP;
+               n->xoffset += types[tptr]->width;
+               break;
+       }
+       n->typecheck = 1;
+       return n;
+}
+
+/*
+ * generate code to compute n;
+ * make a refer to result.
+ */
+void
+naddr(Node *n, Addr *a, int canemitcode)
+{
+       Sym *s;
+
+       *a = zprog.from;
+       if(n == N)
+               return;
+
+       if(n->type != T && n->type->etype != TIDEAL) {
+               // TODO(rsc): This is undone by the selective clearing of width below,
+               // to match architectures that were not as aggressive in setting width
+               // during naddr. Those widths must be cleared to avoid triggering
+               // failures in gins when it detects real but heretofore latent (and one
+               // hopes innocuous) type mismatches.
+               // The type mismatches should be fixed and the clearing below removed.
+               dowidth(n->type);
+               a->width = n->type->width;
+       }
+
+       switch(n->op) {
+       default:
+               fatal("naddr: bad %O %D", n->op, a);
+               break;
+
+       case OREGISTER:
+               a->type = TYPE_REG;
+               a->reg = n->val.u.reg;
+               a->sym = nil;
+               if(arch.thechar == '8') // TODO(rsc): Never clear a->width.
+                       a->width = 0;
+               break;
+
+       case OINDREG:
+               a->type = TYPE_MEM;
+               a->reg = n->val.u.reg;
+               a->sym = linksym(n->sym);
+               a->offset = n->xoffset;
+               if(a->offset != (int32)a->offset)
+                       yyerror("offset %lld too large for OINDREG", a->offset);
+               if(arch.thechar == '8') // TODO(rsc): Never clear a->width.
+                       a->width = 0;
+               break;
+
+       case OPARAM:
+               // n->left is PHEAP ONAME for stack parameter.
+               // compute address of actual parameter on stack.
+               a->etype = simtype[n->left->type->etype];
+               a->width = n->left->type->width;
+               a->offset = n->xoffset;
+               a->sym = linksym(n->left->sym);
+               a->type = TYPE_MEM;
+               a->name = NAME_PARAM;
+               a->node = n->left->orig;
+               break;
+       
+       case OCLOSUREVAR:
+               if(!curfn->needctxt)
+                       fatal("closurevar without needctxt");
+               a->type = TYPE_MEM;
+               a->reg = arch.REGCTXT;
+               a->sym = nil;
+               a->offset = n->xoffset;
+               break;
+       
+       case OCFUNC:
+               naddr(n->left, a, canemitcode);
+               a->sym = linksym(n->left->sym);
+               break;
+
+       case ONAME:
+               a->etype = 0;
+               if(n->type != T)
+                       a->etype = simtype[n->type->etype];
+               a->offset = n->xoffset;
+               s = n->sym;
+               a->node = n->orig;
+               //if(a->node >= (Node*)&n)
+               //      fatal("stack node");
+               if(s == S)
+                       s = lookup(".noname");
+               if(n->method) {
+                       if(n->type != T)
+                       if(n->type->sym != S)
+                       if(n->type->sym->pkg != nil)
+                               s = pkglookup(s->name, n->type->sym->pkg);
+               }
+
+               a->type = TYPE_MEM;
+               switch(n->class) {
+               default:
+                       fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
+               case PEXTERN:
+                       a->name = NAME_EXTERN;
+                       break;
+               case PAUTO:
+                       a->name = NAME_AUTO;
+                       break;
+               case PPARAM:
+               case PPARAMOUT:
+                       a->name = NAME_PARAM;
+                       break;
+               case PFUNC:
+                       a->name = NAME_EXTERN;
+                       a->type = TYPE_ADDR;
+                       a->width = widthptr;
+                       s = funcsym(s);                 
+                       break;
+               }
+               a->sym = linksym(s);
+               break;
+
+       case OLITERAL:
+               if(arch.thechar == '8')
+                       a->width = 0;
+               switch(n->val.ctype) {
+               default:
+                       fatal("naddr: const %lT", n->type);
+                       break;
+               case CTFLT:
+                       a->type = TYPE_FCONST;
+                       a->u.dval = mpgetflt(n->val.u.fval);
+                       break;
+               case CTINT:
+               case CTRUNE:
+                       a->sym = nil;
+                       a->type = TYPE_CONST;
+                       a->offset = mpgetfix(n->val.u.xval);
+                       break;
+               case CTSTR:
+                       datagostring(n->val.u.sval, a);
+                       break;
+               case CTBOOL:
+                       a->sym = nil;
+                       a->type = TYPE_CONST;
+                       a->offset = n->val.u.bval;
+                       break;
+               case CTNIL:
+                       a->sym = nil;
+                       a->type = TYPE_CONST;
+                       a->offset = 0;
+                       break;
+               }
+               break;
+
+       case OADDR:
+               naddr(n->left, a, canemitcode);
+               a->etype = tptr;
+               if(arch.thechar != '5' && arch.thechar != '9') // TODO(rsc): Do this even for arm, ppc64.
+                       a->width = widthptr;
+               if(a->type != TYPE_MEM)
+                       fatal("naddr: OADDR %D (from %O)", a, n->left->op);
+               a->type = TYPE_ADDR;
+               break;
+       
+       case OITAB:
+               // itable of interface value
+               naddr(n->left, a, canemitcode);
+               if(a->type == TYPE_CONST && a->offset == 0)
+                       break;  // itab(nil)
+               a->etype = tptr;
+               a->width = widthptr;
+               break;
+
+       case OSPTR:
+               // pointer in a string or slice
+               naddr(n->left, a, canemitcode);
+               if(a->type == TYPE_CONST && a->offset == 0)
+                       break;  // ptr(nil)
+               a->etype = simtype[tptr];
+               a->offset += Array_array;
+               a->width = widthptr;
+               break;
+
+       case OLEN:
+               // len of string or slice
+               naddr(n->left, a, canemitcode);
+               if(a->type == TYPE_CONST && a->offset == 0)
+                       break;  // len(nil)
+               a->etype = simtype[TUINT];
+               if(arch.thechar == '9')
+                       a->etype = simtype[TINT];
+               a->offset += Array_nel;
+               if(arch.thechar != '5') // TODO(rsc): Do this even on arm.
+                       a->width = widthint;
+               break;
+
+       case OCAP:
+               // cap of string or slice
+               naddr(n->left, a, canemitcode);
+               if(a->type == TYPE_CONST && a->offset == 0)
+                       break;  // cap(nil)
+               a->etype = simtype[TUINT];
+               if(arch.thechar == '9')
+                       a->etype = simtype[TINT];
+               a->offset += Array_cap;
+               if(arch.thechar != '5') // TODO(rsc): Do this even on arm.
+                       a->width = widthint;
+               break;
+
+//     case OADD:
+//             if(n->right->op == OLITERAL) {
+//                     v = n->right->vconst;
+//                     naddr(n->left, a, canemitcode);
+//             } else
+//             if(n->left->op == OLITERAL) {
+//                     v = n->left->vconst;
+//                     naddr(n->right, a, canemitcode);
+//             } else
+//                     goto bad;
+//             a->offset += v;
+//             break;
+
+       }
+}
index a4d470615a67d87fc1f0dfe859e86ad927648aa0..fdabf40069baa86f7c61f3a8459e5ac41ebeeba0 100644 (file)
@@ -95,9 +95,9 @@ dumpobj(void)
        externdcl = tmp;
 
        zero = pkglookup("zerovalue", runtimepkg);
-       arch.ggloblsym(zero, zerosize, DUPOK|RODATA);
+       ggloblsym(zero, zerosize, DUPOK|RODATA);
 
-       arch.dumpdata();
+       dumpdata();
        writeobj(ctxt, bout);
 
        if(writearchive) {
@@ -133,13 +133,13 @@ dumpglobls(void)
                        continue;
                dowidth(n->type);
 
-               arch.ggloblnod(n);
+               ggloblnod(n);
        }
        
        for(l=funcsyms; l; l=l->next) {
                n = l->n;
-               arch.dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
-               arch.ggloblsym(n->sym, widthptr, DUPOK|RODATA);
+               dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
+               ggloblsym(n->sym, widthptr, DUPOK|RODATA);
        }
        
        // Do not reprocess funcsyms on next dumpglobls call.
@@ -250,7 +250,7 @@ stringsym(char *s, int len)
        off = 0;
        
        // string header
-       off = arch.dsymptr(sym, off, sym, widthptr+widthint);
+       off = dsymptr(sym, off, sym, widthptr+widthint);
        off = duintxx(sym, off, len, widthint);
        
        // string data
@@ -258,11 +258,11 @@ stringsym(char *s, int len)
                m = 8;
                if(m > len-n)
                        m = len-n;
-               off = arch.dsname(sym, off, s+n, m);
+               off = dsname(sym, off, s+n, m);
        }
        off = duint8(sym, off, 0);  // terminating NUL for runtime
        off = (off+widthptr-1)&~(widthptr-1);  // round to pointer alignment
-       arch.ggloblsym(sym, off, DUPOK|RODATA);
+       ggloblsym(sym, off, DUPOK|RODATA);
 
        return sym;     
 }
@@ -283,14 +283,216 @@ slicebytes(Node *nam, char *s, int len)
                m = 8;
                if(m > len-n)
                        m = len-n;
-               off = arch.dsname(sym, off, s+n, m);
+               off = dsname(sym, off, s+n, m);
        }
-       arch.ggloblsym(sym, off, NOPTR);
+       ggloblsym(sym, off, NOPTR);
        
        if(nam->op != ONAME)
                fatal("slicebytes %N", nam);
        off = nam->xoffset;
-       off = arch.dsymptr(nam->sym, off, sym, 0);
+       off = dsymptr(nam->sym, off, sym, 0);
        off = duintxx(nam->sym, off, len, widthint);
        duintxx(nam->sym, off, len, widthint);
 }
+
+int
+dsname(Sym *s, int off, char *t, int n)
+{
+       Prog *p;
+
+       p = arch.gins(ADATA, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.offset = off;
+       p->from.sym = linksym(s);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = n;
+       
+       p->to.type = TYPE_SCONST;
+       memmove(p->to.u.sval, t, n);
+       return off + n;
+}
+
+/*
+ * make a refer to the data s, s+len
+ * emitting DATA if needed.
+ */
+void
+datastring(char *s, int len, Addr *a)
+{
+       Sym *sym;
+       
+       sym = stringsym(s, len);
+       a->type = TYPE_MEM;
+       a->name = NAME_EXTERN;
+       a->sym = linksym(sym);
+       a->node = sym->def;
+       a->offset = widthptr+widthint;  // skip header
+       a->etype = simtype[TINT];
+}
+
+/*
+ * make a refer to the string sval,
+ * emitting DATA if needed.
+ */
+void
+datagostring(Strlit *sval, Addr *a)
+{
+       Sym *sym;
+
+       sym = stringsym(sval->s, sval->len);
+       a->type = TYPE_MEM;
+       a->name = NAME_EXTERN;
+       a->sym = linksym(sym);
+       a->node = sym->def;
+       a->offset = 0;  // header
+       a->etype = TSTRING;
+}
+
+void
+gdata(Node *nam, Node *nr, int wid)
+{
+       Prog *p;
+
+       if(nr->op == OLITERAL) {
+               switch(nr->val.ctype) {
+               case CTCPLX:
+                       gdatacomplex(nam, nr->val.u.cval);
+                       return;
+               case CTSTR:
+                       gdatastring(nam, nr->val.u.sval);
+                       return;
+               }
+       }
+       p = arch.gins(ADATA, nam, nr);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = wid;
+}
+
+void
+gdatacomplex(Node *nam, Mpcplx *cval)
+{
+       Prog *p;
+       int w;
+
+       w = cplxsubtype(nam->type->etype);
+       w = types[w]->width;
+
+       p = arch.gins(ADATA, nam, N);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = w;
+       p->to.type = TYPE_FCONST;
+       p->to.u.dval = mpgetflt(&cval->real);
+
+       p = arch.gins(ADATA, nam, N);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = w;
+       p->from.offset += w;
+       p->to.type = TYPE_FCONST;
+       p->to.u.dval = mpgetflt(&cval->imag);
+}
+
+void
+gdatastring(Node *nam, Strlit *sval)
+{
+       Prog *p;
+       Node nod1;
+
+       p = arch.gins(ADATA, nam, N);
+       datastring(sval->s, sval->len, &p->to);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = types[tptr]->width;
+       p->to.type = TYPE_ADDR;
+//print("%P\n", p);
+
+       nodconst(&nod1, types[TINT], sval->len);
+       p = arch.gins(ADATA, nam, &nod1);
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = widthint;
+       p->from.offset += widthptr;
+}
+
+int
+dstringptr(Sym *s, int off, char *str)
+{
+       Prog *p;
+
+       off = rnd(off, widthptr);
+       p = arch.gins(ADATA, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = widthptr;
+
+       datastring(str, strlen(str)+1, &p->to);
+       p->to.type = TYPE_ADDR;
+       p->to.etype = simtype[TINT];
+       off += widthptr;
+
+       return off;
+}
+
+int
+dgostrlitptr(Sym *s, int off, Strlit *lit)
+{
+       Prog *p;
+
+       if(lit == nil)
+               return duintptr(s, off, 0);
+
+       off = rnd(off, widthptr);
+       p = arch.gins(ADATA, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = widthptr;
+       datagostring(lit, &p->to);
+       p->to.type = TYPE_ADDR;
+       p->to.etype = simtype[TINT];
+       off += widthptr;
+
+       return off;
+}
+
+int
+dgostringptr(Sym *s, int off, char *str)
+{
+       int n;
+       Strlit *lit;
+
+       if(str == nil)
+               return duintptr(s, off, 0);
+
+       n = strlen(str);
+       lit = mal(sizeof *lit + n);
+       strcpy(lit->s, str);
+       lit->len = n;
+       return dgostrlitptr(s, off, lit);
+}
+
+int
+dsymptr(Sym *s, int off, Sym *x, int xoff)
+{
+       Prog *p;
+
+       off = rnd(off, widthptr);
+
+       p = arch.gins(ADATA, N, N);
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
+       p->from.sym = linksym(s);
+       p->from.offset = off;
+       p->from3.type = TYPE_CONST;
+       p->from3.offset = widthptr;
+       p->to.type = TYPE_ADDR;
+       p->to.name = NAME_EXTERN;
+       p->to.sym = linksym(x);
+       p->to.offset = xoff;
+       off += widthptr;
+
+       return off;
+}
index ec1628651e501c085c60296b0f9fb714c7a8e74c..0b37bd0856249dabdcec4492732fce26bdadd23f 100644 (file)
@@ -39,7 +39,7 @@ makefuncdatasym(char *namefmt, int64 funcdatakind)
 // where a complete initialization (definition) of a variable begins.
 // Since the liveness analysis can see initialization of single-word
 // variables quite easy, gvardef is usually only called for multi-word
-// or 'fat' variables, those satisfying arch.isfat(n->type).
+// or 'fat' variables, those satisfying isfat(n->type).
 // However, gvardef is also called when a non-fat variable is initialized
 // via a block move; the only time this happens is when you have
 //     return f()
@@ -223,7 +223,7 @@ compile(Node *fn)
        continpc = P;
        breakpc = P;
 
-       pl = arch.newplist();
+       pl = newplist();
        pl->name = linksym(curfn->nname->sym);
 
        setlineno(curfn);
@@ -247,7 +247,7 @@ compile(Node *fn)
                        ptxt->from3.offset |= WRAPPER;
        }       
        
-       arch.afunclit(&ptxt->from, curfn->nname);
+       afunclit(&ptxt->from, curfn->nname);
 
        arch.ginit();
 
@@ -255,7 +255,7 @@ compile(Node *fn)
        gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
 
        for(t=curfn->paramfld; t; t=t->down)
-               arch.gtrack(tracksym(t->type));
+               gtrack(tracksym(t->type));
 
        for(l=fn->dcl; l; l=l->next) {
                n = l->n;
@@ -325,7 +325,7 @@ compile(Node *fn)
        gcsymdup(gcargs);
        gcsymdup(gclocals);
 
-       arch.defframe(ptxt);
+       defframe(ptxt);
 
        if(0)
                frame(0);
@@ -369,7 +369,7 @@ emitptrargsmap(void)
                for(j = 0; j < bv->n; j += 32)
                        off = duint32(sym, off, bv->b[j/32]);
        }
-       arch.ggloblsym(sym, off, RODATA);
+       ggloblsym(sym, off, RODATA);
        free(bv);
 }
 
@@ -438,7 +438,7 @@ allocauto(Prog* ptxt)
                if (ll->n->class == PAUTO)
                        ll->n->used = 0;
 
-       arch.markautoused(ptxt);
+       markautoused(ptxt);
 
        listsort(&curfn->dcl, cmpstackvar);
 
@@ -448,7 +448,7 @@ allocauto(Prog* ptxt)
        if (n->class == PAUTO && n->op == ONAME && !n->used) {
                // No locals used at all
                curfn->dcl = nil;
-               arch.fixautoused(ptxt);
+               fixautoused(ptxt);
                return;
        }
 
@@ -486,7 +486,7 @@ allocauto(Prog* ptxt)
        stksize = rnd(stksize, widthreg);
        stkptrsize = rnd(stkptrsize, widthreg);
 
-       arch.fixautoused(ptxt);
+       fixautoused(ptxt);
 
        // The debug information needs accurate offsets on the symbols.
        for(ll = curfn->dcl; ll != nil; ll=ll->next) {
index 0461085b5b6bc14a25577284f344a1591ecd9d04..05722e0f8e3ef6dd986d71ad19b146f3d9de3110 100644 (file)
@@ -744,7 +744,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
                                        if(info.flags & (LeftRead | LeftAddr))
                                                bvset(uevar, pos);
                                        if(info.flags & LeftWrite)
-                                               if(from->node != nil && !arch.isfat(((Node*)(from->node))->type))
+                                               if(from->node != nil && !isfat(((Node*)(from->node))->type))
                                                        bvset(varkill, pos);
                                }
                        }
@@ -780,7 +780,7 @@ Next:
                                        if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
                                                bvset(uevar, pos);
                                        if(info.flags & RightWrite)
-                                               if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == AVARDEF))
+                                               if(to->node != nil && (!isfat(((Node*)(to->node))->type) || prog->as == AVARDEF))
                                                        bvset(varkill, pos);
                                }
                        }
@@ -1218,7 +1218,7 @@ unlinkedprog(int as)
        Prog *p;
 
        p = mal(sizeof(*p));
-       arch.clearp(p);
+       clearp(p);
        p->as = as;
        return p;
 }
@@ -1235,8 +1235,8 @@ newpcdataprog(Prog *prog, int32 index)
        nodconst(&to, types[TINT32], index);
        pcdata = unlinkedprog(APCDATA);
        pcdata->lineno = prog->lineno;
-       arch.naddr(&from, &pcdata->from, 0);
-       arch.naddr(&to, &pcdata->to, 0);
+       naddr(&from, &pcdata->from, 0);
+       naddr(&to, &pcdata->to, 0);
        return pcdata;
 }
 
@@ -1932,7 +1932,7 @@ twobitwritesymbol(Array *arr, Sym *sym)
                }
        }
        duint32(sym, 0, i); // number of bitmaps
-       arch.ggloblsym(sym, off, RODATA);
+       ggloblsym(sym, off, RODATA);
 }
 
 static void
index 61a63c0528bd2b95d2a9cd44faeb038e99852afe..ec102dbeb520640ed5c980ec2dadeb3597190f97 100644 (file)
@@ -547,15 +547,15 @@ dimportpath(Pkg *p)
        n->xoffset = 0;
        p->pathsym = n->sym;
 
-       arch.gdatastring(n, p->path);
-       arch.ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
+       gdatastring(n, p->path);
+       ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
 }
 
 static int
 dgopkgpath(Sym *s, int ot, Pkg *pkg)
 {
        if(pkg == nil)
-               return arch.dgostringptr(s, ot, nil);
+               return dgostringptr(s, ot, nil);
 
        // Emit reference to go.importpath.""., which 6l will
        // rewrite using the correct import path.  Every package
@@ -565,11 +565,11 @@ dgopkgpath(Sym *s, int ot, Pkg *pkg)
 
                if(ns == nil)
                        ns = pkglookup("importpath.\"\".", mkpkg(newstrlit("go")));
-               return arch.dsymptr(s, ot, ns, 0);
+               return dsymptr(s, ot, ns, 0);
        }
 
        dimportpath(pkg);
-       return arch.dsymptr(s, ot, pkg->pathsym, 0);
+       return dsymptr(s, ot, pkg->pathsym, 0);
 }
 
 /*
@@ -589,7 +589,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
 
        // fill in *extraType pointer in header
        off = rnd(off, widthptr);
-       arch.dsymptr(sym, ptroff, sym, off);
+       dsymptr(sym, ptroff, sym, off);
 
        n = 0;
        for(a=m; a; a=a->link) {
@@ -600,18 +600,18 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
        ot = off;
        s = sym;
        if(t->sym) {
-               ot = arch.dgostringptr(s, ot, t->sym->name);
+               ot = dgostringptr(s, ot, t->sym->name);
                if(t != types[t->etype] && t != errortype)
                        ot = dgopkgpath(s, ot, t->sym->pkg);
                else
-                       ot = arch.dgostringptr(s, ot, nil);
+                       ot = dgostringptr(s, ot, nil);
        } else {
-               ot = arch.dgostringptr(s, ot, nil);
-               ot = arch.dgostringptr(s, ot, nil);
+               ot = dgostringptr(s, ot, nil);
+               ot = dgostringptr(s, ot, nil);
        }
 
        // slice header
-       ot = arch.dsymptr(s, ot, s, ot + widthptr + 2*widthint);
+       ot = dsymptr(s, ot, s, ot + widthptr + 2*widthint);
        ot = duintxx(s, ot, n, widthint);
        ot = duintxx(s, ot, n, widthint);
 
@@ -619,16 +619,16 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
        for(a=m; a; a=a->link) {
                // method
                // ../../runtime/type.go:/method
-               ot = arch.dgostringptr(s, ot, a->name);
+               ot = dgostringptr(s, ot, a->name);
                ot = dgopkgpath(s, ot, a->pkg);
-               ot = arch.dsymptr(s, ot, dtypesym(a->mtype), 0);
-               ot = arch.dsymptr(s, ot, dtypesym(a->type), 0);
+               ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
+               ot = dsymptr(s, ot, dtypesym(a->type), 0);
                if(a->isym)
-                       ot = arch.dsymptr(s, ot, a->isym, 0);
+                       ot = dsymptr(s, ot, a->isym, 0);
                else
                        ot = duintptr(s, ot, 0);
                if(a->tsym)
-                       ot = arch.dsymptr(s, ot, a->tsym, 0);
+                       ot = dsymptr(s, ot, a->tsym, 0);
                else
                        ot = duintptr(s, ot, 0);
        }
@@ -816,17 +816,17 @@ dcommontype(Sym *s, int ot, Type *t)
                i |= KindGCProg;
        ot = duint8(s, ot, i);  // kind
        if(algsym == S)
-               ot = arch.dsymptr(s, ot, algarray, alg*sizeofAlg);
+               ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
        else
-               ot = arch.dsymptr(s, ot, algsym, 0);
+               ot = dsymptr(s, ot, algsym, 0);
        // gc
        if(gcprog) {
                gengcprog(t, &gcprog0, &gcprog1);
                if(gcprog0 != S)
-                       ot = arch.dsymptr(s, ot, gcprog0, 0);
+                       ot = dsymptr(s, ot, gcprog0, 0);
                else
                        ot = duintptr(s, ot, 0);
-               ot = arch.dsymptr(s, ot, gcprog1, 0);
+               ot = dsymptr(s, ot, gcprog1, 0);
        } else {
                gengcmask(t, gcmask);
                x1 = 0;
@@ -845,14 +845,14 @@ dcommontype(Sym *s, int ot, Type *t)
                        sbits->flags |= SymUniq;
                        for(i = 0; i < 2*widthptr; i++)
                                duint8(sbits, i, gcmask[i]);
-                       arch.ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
+                       ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
                }
-               ot = arch.dsymptr(s, ot, sbits, 0);
+               ot = dsymptr(s, ot, sbits, 0);
                ot = duintptr(s, ot, 0);
        }
        p = smprint("%-uT", t);
        //print("dcommontype: %s\n", p);
-       ot = arch.dgostringptr(s, ot, p);       // string
+       ot = dgostringptr(s, ot, p);    // string
        free(p);
 
        // skip pointer to extraType,
@@ -861,8 +861,8 @@ dcommontype(Sym *s, int ot, Type *t)
        // otherwise linker will assume 0.
        ot += widthptr;
 
-       ot = arch.dsymptr(s, ot, sptr, 0);  // ptrto type
-       ot = arch.dsymptr(s, ot, zero, 0);  // ptr to zero value
+       ot = dsymptr(s, ot, sptr, 0);  // ptrto type
+       ot = dsymptr(s, ot, zero, 0);  // ptr to zero value
        return ot;
 }
 
@@ -1092,15 +1092,15 @@ ok:
                        s2 = dtypesym(t2);
                        ot = dcommontype(s, ot, t);
                        xt = ot - 3*widthptr;
-                       ot = arch.dsymptr(s, ot, s1, 0);
-                       ot = arch.dsymptr(s, ot, s2, 0);
+                       ot = dsymptr(s, ot, s1, 0);
+                       ot = dsymptr(s, ot, s2, 0);
                        ot = duintptr(s, ot, t->bound);
                } else {
                        // ../../runtime/type.go:/SliceType
                        s1 = dtypesym(t->type);
                        ot = dcommontype(s, ot, t);
                        xt = ot - 3*widthptr;
-                       ot = arch.dsymptr(s, ot, s1, 0);
+                       ot = dsymptr(s, ot, s1, 0);
                }
                break;
 
@@ -1109,7 +1109,7 @@ ok:
                s1 = dtypesym(t->type);
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = arch.dsymptr(s, ot, s1, 0);
+               ot = dsymptr(s, ot, s1, 0);
                ot = duintptr(s, ot, t->chan);
                break;
 
@@ -1130,21 +1130,21 @@ ok:
 
                // two slice headers: in and out.
                ot = rnd(ot, widthptr);
-               ot = arch.dsymptr(s, ot, s, ot+2*(widthptr+2*widthint));
+               ot = dsymptr(s, ot, s, ot+2*(widthptr+2*widthint));
                n = t->thistuple + t->intuple;
                ot = duintxx(s, ot, n, widthint);
                ot = duintxx(s, ot, n, widthint);
-               ot = arch.dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr);
+               ot = dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr);
                ot = duintxx(s, ot, t->outtuple, widthint);
                ot = duintxx(s, ot, t->outtuple, widthint);
 
                // slice data
                for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
-                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
                for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
-                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
                for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
-                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
                break;
 
        case TINTER:
@@ -1158,14 +1158,14 @@ ok:
                // ../../runtime/type.go:/InterfaceType
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = arch.dsymptr(s, ot, s, ot+widthptr+2*widthint);
+               ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
                ot = duintxx(s, ot, n, widthint);
                ot = duintxx(s, ot, n, widthint);
                for(a=m; a; a=a->link) {
                        // ../../runtime/type.go:/imethod
-                       ot = arch.dgostringptr(s, ot, a->name);
+                       ot = dgostringptr(s, ot, a->name);
                        ot = dgopkgpath(s, ot, a->pkg);
-                       ot = arch.dsymptr(s, ot, dtypesym(a->type), 0);
+                       ot = dsymptr(s, ot, dtypesym(a->type), 0);
                }
                break;
 
@@ -1177,10 +1177,10 @@ ok:
                s4 = dtypesym(hmap(t));
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = arch.dsymptr(s, ot, s1, 0);
-               ot = arch.dsymptr(s, ot, s2, 0);
-               ot = arch.dsymptr(s, ot, s3, 0);
-               ot = arch.dsymptr(s, ot, s4, 0);
+               ot = dsymptr(s, ot, s1, 0);
+               ot = dsymptr(s, ot, s2, 0);
+               ot = dsymptr(s, ot, s3, 0);
+               ot = dsymptr(s, ot, s4, 0);
                if(t->down->width > MAXKEYSIZE) {
                        ot = duint8(s, ot, widthptr);
                        ot = duint8(s, ot, 1); // indirect
@@ -1210,7 +1210,7 @@ ok:
                s1 = dtypesym(t->type);
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = arch.dsymptr(s, ot, s1, 0);
+               ot = dsymptr(s, ot, s1, 0);
                break;
 
        case TSTRUCT:
@@ -1223,32 +1223,32 @@ ok:
                }
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = arch.dsymptr(s, ot, s, ot+widthptr+2*widthint);
+               ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
                ot = duintxx(s, ot, n, widthint);
                ot = duintxx(s, ot, n, widthint);
                for(t1=t->type; t1!=T; t1=t1->down) {
                        // ../../runtime/type.go:/structField
                        if(t1->sym && !t1->embedded) {
-                               ot = arch.dgostringptr(s, ot, t1->sym->name);
+                               ot = dgostringptr(s, ot, t1->sym->name);
                                if(exportname(t1->sym->name))
-                                       ot = arch.dgostringptr(s, ot, nil);
+                                       ot = dgostringptr(s, ot, nil);
                                else
                                        ot = dgopkgpath(s, ot, t1->sym->pkg);
                        } else {
-                               ot = arch.dgostringptr(s, ot, nil);
+                               ot = dgostringptr(s, ot, nil);
                                if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg)
                                        ot = dgopkgpath(s, ot, localpkg);
                                else
-                                       ot = arch.dgostringptr(s, ot, nil);
+                                       ot = dgostringptr(s, ot, nil);
                        }
-                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
-                       ot = arch.dgostrlitptr(s, ot, t1->note);
+                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = dgostrlitptr(s, ot, t1->note);
                        ot = duintptr(s, ot, t1->width);        // field offset
                }
                break;
        }
        ot = dextratype(s, ot, t, xt);
-       arch.ggloblsym(s, ot, dupok|RODATA);
+       ggloblsym(s, ot, dupok|RODATA);
 
        // generate typelink.foo pointing at s = type.foo.
        // The linker will leave a table of all the typelinks for
@@ -1261,8 +1261,8 @@ ok:
                case TCHAN:
                case TMAP:
                        slink = typelinksym(t);
-                       arch.dsymptr(slink, 0, s, 0);
-                       arch.ggloblsym(slink, widthptr, dupok|RODATA);
+                       dsymptr(slink, 0, s, 0);
+                       ggloblsym(slink, widthptr, dupok|RODATA);
                }
        }
 
@@ -1354,18 +1354,18 @@ dalgsym(Type *t)
                hashfunc = pkglookup(p, typepkg);
                free(p);
                ot = 0;
-               ot = arch.dsymptr(hashfunc, ot, pkglookup("memhash_varlen", runtimepkg), 0);
+               ot = dsymptr(hashfunc, ot, pkglookup("memhash_varlen", runtimepkg), 0);
                ot = duintxx(hashfunc, ot, t->width, widthptr); // size encoded in closure
-               arch.ggloblsym(hashfunc, ot, DUPOK|RODATA);
+               ggloblsym(hashfunc, ot, DUPOK|RODATA);
 
                // make equality closure
                p = smprint(".eqfunc%lld", t->width);
                eqfunc = pkglookup(p, typepkg);
                free(p);
                ot = 0;
-               ot = arch.dsymptr(eqfunc, ot, pkglookup("memequal_varlen", runtimepkg), 0);
+               ot = dsymptr(eqfunc, ot, pkglookup("memequal_varlen", runtimepkg), 0);
                ot = duintxx(eqfunc, ot, t->width, widthptr);
-               arch.ggloblsym(eqfunc, ot, DUPOK|RODATA);
+               ggloblsym(eqfunc, ot, DUPOK|RODATA);
        } else {
                // generate an alg table specific to this type
                s = typesymprefix(".alg", t);
@@ -1378,16 +1378,16 @@ dalgsym(Type *t)
                geneq(eq, t);
 
                // make Go funcs (closures) for calling hash and equal from Go
-               arch.dsymptr(hashfunc, 0, hash, 0);
-               arch.ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
-               arch.dsymptr(eqfunc, 0, eq, 0);
-               arch.ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
+               dsymptr(hashfunc, 0, hash, 0);
+               ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
+               dsymptr(eqfunc, 0, eq, 0);
+               ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
        }
        // ../../runtime/alg.go:/typeAlg
        ot = 0;
-       ot = arch.dsymptr(s, ot, hashfunc, 0);
-       ot = arch.dsymptr(s, ot, eqfunc, 0);
-       arch.ggloblsym(s, ot, DUPOK|RODATA);
+       ot = dsymptr(s, ot, hashfunc, 0);
+       ot = dsymptr(s, ot, eqfunc, 0);
+       ggloblsym(s, ot, DUPOK|RODATA);
        return s;
 }
 
@@ -1570,7 +1570,7 @@ gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
        // Don't generate it if it's too large, runtime will unroll directly into GC bitmap.
        if(size <= MaxGCMask) {
                gc0 = typesymprefix(".gc", t);
-               arch.ggloblsym(gc0, size, DUPOK|NOPTR);
+               ggloblsym(gc0, size, DUPOK|NOPTR);
                *pgc0 = gc0;
        }
 
@@ -1580,7 +1580,7 @@ gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
        xoffset = 0;
        gengcprog1(&g, t, &xoffset);
        ot = proggenfini(&g);
-       arch.ggloblsym(gc1, ot, DUPOK|RODATA);
+       ggloblsym(gc1, ot, DUPOK|RODATA);
        *pgc1 = gc1;
 }
 
index 3d303eda09583493b7dfb20f7c7df5bc8a29cac3..7dfa1e42fd41988555fb64a3822cba936d468477 100644 (file)
@@ -302,13 +302,13 @@ staticcopy(Node *l, Node *r, NodeList **out)
        case OLITERAL:
                if(iszero(r))
                        return 1;
-               arch.gdata(l, r, l->type->width);
+               gdata(l, r, l->type->width);
                return 1;
 
        case OADDR:
                switch(r->left->op) {
                case ONAME:
-                       arch.gdata(l, r, l->type->width);
+                       gdata(l, r, l->type->width);
                        return 1;
                }
                break;
@@ -322,7 +322,7 @@ staticcopy(Node *l, Node *r, NodeList **out)
                case OSTRUCTLIT:
                case OMAPLIT:
                        // copy pointer
-                       arch.gdata(l, nod(OADDR, r->nname, N), l->type->width);
+                       gdata(l, nod(OADDR, r->nname, N), l->type->width);
                        return 1;
                }
                break;
@@ -333,11 +333,11 @@ staticcopy(Node *l, Node *r, NodeList **out)
                        a = r->nname;
                        n1 = *l;
                        n1.xoffset = l->xoffset + Array_array;
-                       arch.gdata(&n1, nod(OADDR, a, N), widthptr);
+                       gdata(&n1, nod(OADDR, a, N), widthptr);
                        n1.xoffset = l->xoffset + Array_nel;
-                       arch.gdata(&n1, r->right, widthint);
+                       gdata(&n1, r->right, widthint);
                        n1.xoffset = l->xoffset + Array_cap;
-                       arch.gdata(&n1, r->right, widthint);
+                       gdata(&n1, r->right, widthint);
                        return 1;
                }
                // fall through
@@ -349,7 +349,7 @@ staticcopy(Node *l, Node *r, NodeList **out)
                        n1.xoffset = l->xoffset + e->xoffset;
                        n1.type = e->expr->type;
                        if(e->expr->op == OLITERAL)
-                               arch.gdata(&n1, e->expr, n1.type->width);
+                               gdata(&n1, e->expr, n1.type->width);
                        else {
                                ll = nod(OXXX, N, N);
                                *ll = n1;
@@ -394,14 +394,14 @@ staticassign(Node *l, Node *r, NodeList **out)
        case OLITERAL:
                if(iszero(r))
                        return 1;
-               arch.gdata(l, r, l->type->width);
+               gdata(l, r, l->type->width);
                return 1;
 
        case OADDR:
                if(stataddr(&nam, r->left)) {
                        n1 = *r;
                        n1.left = &nam;
-                       arch.gdata(l, &n1, l->type->width);
+                       gdata(l, &n1, l->type->width);
                        return 1;
                }
        
@@ -417,7 +417,7 @@ staticassign(Node *l, Node *r, NodeList **out)
                        // Init pointer.
                        a = staticname(r->left->type, 1);
                        r->nname = a;
-                       arch.gdata(l, nod(OADDR, a, N), l->type->width);
+                       gdata(l, nod(OADDR, a, N), l->type->width);
                        // Init underlying literal.
                        if(!staticassign(a, r->left, out))
                                *out = list(*out, nod(OAS, a, r->left));
@@ -444,11 +444,11 @@ staticassign(Node *l, Node *r, NodeList **out)
                        r->nname = a;
                        n1 = *l;
                        n1.xoffset = l->xoffset + Array_array;
-                       arch.gdata(&n1, nod(OADDR, a, N), widthptr);
+                       gdata(&n1, nod(OADDR, a, N), widthptr);
                        n1.xoffset = l->xoffset + Array_nel;
-                       arch.gdata(&n1, r->right, widthint);
+                       gdata(&n1, r->right, widthint);
                        n1.xoffset = l->xoffset + Array_cap;
-                       arch.gdata(&n1, r->right, widthint);
+                       gdata(&n1, r->right, widthint);
                        // Fall through to init underlying array.
                        l = a;
                }
@@ -462,7 +462,7 @@ staticassign(Node *l, Node *r, NodeList **out)
                        n1.xoffset = l->xoffset + e->xoffset;
                        n1.type = e->expr->type;
                        if(e->expr->op == OLITERAL)
-                               arch.gdata(&n1, e->expr, n1.type->width);
+                               gdata(&n1, e->expr, n1.type->width);
                        else {
                                a = nod(OXXX, N, N);
                                *a = n1;
@@ -1303,16 +1303,16 @@ gen_as_init(Node *n)
        case TPTR64:
        case TFLOAT32:
        case TFLOAT64:
-               arch.gdata(&nam, nr, nr->type->width);
+               gdata(&nam, nr, nr->type->width);
                break;
 
        case TCOMPLEX64:
        case TCOMPLEX128:
-               arch.gdatacomplex(&nam, nr->val.u.cval);
+               gdatacomplex(&nam, nr->val.u.cval);
                break;
 
        case TSTRING:
-               arch.gdatastring(&nam, nr->val.u.sval);
+               gdatastring(&nam, nr->val.u.sval);
                break;
        }
 
@@ -1320,7 +1320,7 @@ yes:
        return 1;
 
 slice:
-       arch.gused(N); // in case the data is the dest of a goto
+       gused(N); // in case the data is the dest of a goto
        nl = nr;
        if(nr == N || nr->op != OADDR)
                goto no;
@@ -1333,14 +1333,14 @@ slice:
                goto no;
 
        nam.xoffset += Array_array;
-       arch.gdata(&nam, nl, types[tptr]->width);
+       gdata(&nam, nl, types[tptr]->width);
 
        nam.xoffset += Array_nel-Array_array;
        nodconst(&nod1, types[TINT], nr->type->bound);
-       arch.gdata(&nam, &nod1, widthint);
+       gdata(&nam, &nod1, widthint);
 
        nam.xoffset += Array_cap-Array_nel;
-       arch.gdata(&nam, &nod1, widthint);
+       gdata(&nam, &nod1, widthint);
 
        goto yes;
 
index 89c465869160b9cf30331e8ce9811d89cdef22c8..07df5a1adc9bb0ffd2254f63baa8a3c22c89da6b 100644 (file)
@@ -927,7 +927,7 @@ walkexpr(Node **np, NodeList **init)
                                l->class = PEXTERN;
                                l->xoffset = 0;
                                sym->def = l;
-                               arch.ggloblsym(sym, widthptr, DUPOK|NOPTR);
+                               ggloblsym(sym, widthptr, DUPOK|NOPTR);
                        }
                        l = nod(OADDR, sym->def, N);
                        l->addable = 1;
@@ -1602,7 +1602,7 @@ ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
                        l = tmp;
                }
 
-               a = nod(OAS, l, arch.nodarg(r, fp));
+               a = nod(OAS, l, nodarg(r, fp));
                a = convas(a, init);
                ullmancalc(a);
                if(a->ullman >= UINF) {
@@ -1655,7 +1655,7 @@ mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Nod
                walkexpr(&n, init);
        }
 
-       a = nod(OAS, arch.nodarg(l, fp), n);
+       a = nod(OAS, nodarg(l, fp), n);
        nn = list(nn, convas(a, init));
        return nn;
 }
@@ -1735,7 +1735,7 @@ ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeL
        if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) {
                // optimization - can do block copy
                if(eqtypenoname(r->type, *nl)) {
-                       a = arch.nodarg(*nl, fp);
+                       a = nodarg(*nl, fp);
                        r = nod(OCONVNOP, r, N);
                        r->type = a->type;
                        nn = list1(convas(nod(OAS, a, r), init));
@@ -1772,7 +1772,7 @@ loop:
                // argument to a ddd parameter then it is
                // passed thru unencapsulated
                if(r != N && lr->next == nil && isddd && eqtype(l->type, r->type)) {
-                       a = nod(OAS, arch.nodarg(l, fp), r);
+                       a = nod(OAS, nodarg(l, fp), r);
                        a = convas(a, init);
                        nn = list(nn, a);
                        goto ret;
@@ -1797,7 +1797,7 @@ loop:
                goto ret;
        }
 
-       a = nod(OAS, arch.nodarg(l, fp), r);
+       a = nod(OAS, nodarg(l, fp), r);
        a = convas(a, init);
        nn = list(nn, a);
 
@@ -2560,7 +2560,7 @@ paramstoheap(Type **argin, int out)
                        // Defer might stop a panic and show the
                        // return values as they exist at the time of panic.
                        // Make sure to zero them on entry to the function.
-                       nn = list(nn, nod(OAS, arch.nodarg(t, 1), N));
+                       nn = list(nn, nod(OAS, nodarg(t, 1), N));
                }
                if(v == N || !(v->class & PHEAP))
                        continue;
index 3947a571e5c7c07e7e126a31931649b9e69181fd..398b7841c2dc0d3abe4f3289acbbb918dfdb9435 100644 (file)
@@ -96,6 +96,7 @@ static Optab  optab[] =
        { ABL,          C_NONE, C_NONE, C_SBRA,          5, 4, 0 },
        { ABX,          C_NONE, C_NONE, C_SBRA,          74, 20, 0 },
        { ABEQ,         C_NONE, C_NONE, C_SBRA,          5, 4, 0 },
+       { ABEQ,         C_RCON, C_NONE, C_SBRA,          5, 4, 0 }, // prediction hinted form, hint ignored
 
        { AB,           C_NONE, C_NONE, C_ROREG,         6, 4, 0,       LPOOL },
        { ABL,          C_NONE, C_NONE, C_ROREG,         7, 4, 0 },
@@ -353,14 +354,6 @@ static     uchar   xcmp[C_GOK+1][C_GOK+1];
 
 static LSym *deferreturn;
 
-static void
-nocache(Prog *p)
-{
-       p->optab = 0;
-       p->from.class = 0;
-       p->to.class = 0;
-}
-
 /* size of a case statement including jump table */
 static int32
 casesz(Link *ctxt, Prog *p)
index 754a7cc15e43cfc2a8ffa9b207b35217f85116a8..08ce82b30cc78fd05c97db2dc67e6c97766e1494 100644 (file)
@@ -133,3 +133,24 @@ double2ieee(uint64 *ieee, float64 f)
 {
        memmove(ieee, &f, 8);
 }
+
+void
+nopout(Prog *p)
+{
+       p->as = ANOP;
+       p->scond = zprog.scond;
+       p->from = zprog.from;
+       p->from3 = zprog.from3;
+       p->reg = zprog.reg;
+       p->to = zprog.to;
+}
+
+void
+nocache(Prog *p)
+{
+       p->optab = 0;
+       p->from.class = 0;
+       p->from3.class = 0;
+       p->to.class = 0;
+}
+
index 805d7a59c230e9a9b7eaa25d3e2e6ca5ca9f19b5..abddbc3c4fea5251b26f19cb4af725b5461f72f3 100644 (file)
@@ -184,14 +184,6 @@ linkcase(Prog *casep)
        }
 }
 
-static void
-nocache5(Prog *p)
-{
-       p->optab = 0;
-       p->from.class = 0;
-       p->to.class = 0;
-}
-
 static void
 preprocess(Link *ctxt, LSym *cursym)
 {
@@ -478,7 +470,7 @@ preprocess(Link *ctxt, LSym *cursym)
                        break;
 
                case ARET:
-                       nocache5(p);
+                       nocache(p);
                        if(cursym->text->mark & LEAF) {
                                if(!autosize) {
                                        p->as = AB;
index cddc723bf2d23b1437c717de3a890bf19d787783..546c89d53c1b0c16f4f3864871e7647baa6e8cb0 100644 (file)
 #include "../cmd/6l/6.out.h"
 #include "../runtime/stack.h"
 
-static void
-nopout(Prog *p)
-{
-       p->as = ANOP;
-       p->from.type = TYPE_NONE;
-       p->from.reg = 0;
-       p->from.name = 0;
-       p->to.type = TYPE_NONE;
-       p->to.reg = 0;
-       p->to.name = 0;
-}
-
 static void nacladdr(Link*, Prog*, Addr*);
 
 static int