]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: make cmd/gc a real library
authorRuss Cox <rsc@golang.org>
Thu, 22 Jan 2015 05:52:01 +0000 (00:52 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 26 Jan 2015 20:00:38 +0000 (20:00 +0000)
cmd/gc contains symbol references into the back end dirs like 6g.
It also contains a few files that include the back end header files and
are compiled separately for each back end, despite being in cmd/gc.
cmd/gc also defines main, which makes at least one reverse symbol
reference unavoidable. (Otherwise you can't get into back-end code.)

This was all expedient, but it's too tightly coupled, especially for a
program written Go.

Make cmd/gc into a true library, letting the back end define main and
call into cmd/gc after making the necessary references available.
cmd/gc being a real library will ease the transition to Go.

Change-Id: I4fb9a0e2b11a32f1d024b3c56fc3bd9ee458842c
Reviewed-on: https://go-review.googlesource.com/3277
Reviewed-by: Rob Pike <r@golang.org>
28 files changed:
src/cmd/5g/galign.c
src/cmd/5g/gg.h
src/cmd/5g/opt.h
src/cmd/6g/galign.c
src/cmd/6g/gg.h
src/cmd/6g/opt.h
src/cmd/8g/galign.c
src/cmd/8g/gg.h
src/cmd/8g/opt.h
src/cmd/9g/galign.c
src/cmd/9g/gg.h
src/cmd/9g/opt.h
src/cmd/dist/build.go
src/cmd/gc/align.c
src/cmd/gc/cplx.c
src/cmd/gc/export.c
src/cmd/gc/gen.c
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/obj.c
src/cmd/gc/pgen.c
src/cmd/gc/plive.c
src/cmd/gc/popt.c
src/cmd/gc/popt.h [deleted file]
src/cmd/gc/reflect.c
src/cmd/gc/sinit.c
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index b4c45da6907403e2ae5b387b19f900e64ca14e29..812ce5c7fc9230649b274b8a20e1a97ef68e1ed4 100644 (file)
@@ -44,6 +44,90 @@ betypeinit(void)
        zprog.from.name = D_NONE;
        zprog.from.reg = NREG;
        zprog.to = zprog.from;
+       arch.zprog = zprog;
 
        listinit5();
 }
+
+void
+main(int argc, char **argv)
+{
+       arch.thechar = thechar;
+       arch.thestring = thestring;
+       arch.thelinkarch = thelinkarch;
+       arch.typedefs = typedefs;
+       arch.zprog = zprog;
+       arch.ACALL = ABL;
+       arch.ACHECKNIL = ACHECKNIL;
+       arch.ADATA = ADATA;
+       arch.AFUNCDATA = AFUNCDATA;
+       arch.AGLOBL = AGLOBL;
+       arch.AJMP = AB;
+       arch.ANAME = ANAME;
+       arch.ANOP = ANOP;
+       arch.APCDATA = APCDATA;
+       arch.ARET = ARET;
+       arch.ASIGNAME = ASIGNAME;
+       arch.ATEXT = ATEXT;
+       arch.ATYPE = ATYPE;
+       arch.AUNDEF = AUNDEF;
+       arch.AVARDEF = AVARDEF;
+       arch.AVARKILL = AVARKILL;
+       arch.D_AUTO = D_AUTO;
+       arch.D_BRANCH = D_BRANCH;
+       arch.D_NONE = D_NONE;
+       arch.D_PARAM = D_PARAM;
+       arch.MAXWIDTH = MAXWIDTH;
+       arch.afunclit = afunclit;
+       arch.anyregalloc = anyregalloc;
+       arch.betypeinit = betypeinit;
+       arch.bgen = bgen;
+       arch.cgen = cgen;
+       arch.cgen_asop = cgen_asop;
+       arch.cgen_call = cgen_call;
+       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;
+       arch.regopt = regopt;
+       arch.regtyp = regtyp;
+       arch.sameaddr = sameaddr;
+       arch.smallindir = smallindir;
+       arch.stackaddr = stackaddr;
+       arch.unpatch = unpatch;
+       
+       gcmain(argc, argv);
+}
index 00914bfa34cafb5d3c317edb542a4e01c2356d41..f5c795a63ddee0c5b5bb5471fd56ce8f3d809a00 100644 (file)
@@ -24,12 +24,6 @@ EXTERN       uchar   reg[REGALLOC_FMAX+1];
 EXTERN int32   pcloc;          // instruction counter
 EXTERN Strlit  emptystring;
 EXTERN Prog    zprog;
-EXTERN Node*   newproc;
-EXTERN Node*   deferproc;
-EXTERN Node*   deferreturn;
-EXTERN Node*   panicindex;
-EXTERN Node*   panicslice;
-EXTERN Node*   throwreturn;
 extern long    unmappedzero;
 
 /*
@@ -121,3 +115,54 @@ void       datastring(char*, int, Addr*);
 void   listinit(void);
 
 void   zaddr(Biobuf*, Addr*, int, int);
+
+void afunclit(Addr*, Node*);
+int anyregalloc(void);
+void betypeinit(void);
+void bgen(Node*, int, int, Prog*);
+void cgen(Node*, Node*);
+void cgen_asop(Node*);
+void cgen_call(Node*, int);
+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 *nam);
+void   ggloblsym(Sym *s, int32 width, int8 flags);
+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*);
+void regopt(Prog*);
+int regtyp(Addr*);
+int sameaddr(Addr*, Addr*);
+int smallindir(Addr*, Addr*);
+int stackaddr(Addr*);
+Prog* unpatch(Prog*);
index a606f1d3105e969afc034d7cafe42f2fa09653c0..64c83f1b5ac43e5f3a70def43f986a324efac99d 100644 (file)
@@ -28,7 +28,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include       "../gc/popt.h"
 
 #define        Z       N
 #define        Adr     Addr
@@ -180,53 +179,6 @@ int        BtoF(uint32);
 /*
  * prog.c
  */
-typedef struct ProgInfo ProgInfo;
-struct ProgInfo
-{
-       uint32 flags; // the bits below
-};
-
-enum
-{
-       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
-       Pseudo = 1<<1,
-       
-       // There's nothing to say about the instruction,
-       // but it's still okay to see.
-       OK = 1<<2,
-
-       // Size of right-side write, or right-side read if no write.
-       SizeB = 1<<3,
-       SizeW = 1<<4,
-       SizeL = 1<<5,
-       SizeQ = 1<<6,
-       SizeF = 1<<7, // float aka float32
-       SizeD = 1<<8, // double aka float64
-
-       // Left side (Prog.from): address taken, read, write.
-       LeftAddr = 1<<9,
-       LeftRead = 1<<10,
-       LeftWrite = 1<<11,
-       
-       // Register in middle (Prog.reg); only ever read.
-       RegRead = 1<<12,
-       CanRegRead = 1<<13,
-       
-       // Right side (Prog.to): address taken, read, write.
-       RightAddr = 1<<14,
-       RightRead = 1<<15,
-       RightWrite = 1<<16,
-
-       // Instruction kinds
-       Move = 1<<17, // straight move
-       Conv = 1<<18, // size conversion
-       Cjmp = 1<<19, // conditional jump
-       Break = 1<<20, // breaks control flow (no fallthrough)
-       Call = 1<<21, // function call
-       Jump = 1<<22, // jump
-       Skip = 1<<23, // data instruction
-};
-
 void proginfo(ProgInfo*, Prog*);
 
 // To allow use of AJMP and ACALL in ../gc/popt.c.
index 5670e6fac87bc2195899acfc04e8d41c1514c73f..a3c97a79a6920d823eac352ef681acec97051123 100644 (file)
@@ -13,8 +13,12 @@ LinkArch*    thelinkarch = &linkamd64;
 void
 linkarchinit(void)
 {
-       if(strcmp(getgoarch(), "amd64p32") == 0)
+       if(strcmp(getgoarch(), "amd64p32") == 0) {
                thelinkarch = &linkamd64p32;
+               arch.thelinkarch = thelinkarch;
+               thestring = "amd64p32";
+               arch.thestring = "amd64p32";
+       }
 }
 
 vlong MAXWIDTH = 1LL<<50;
@@ -61,6 +65,90 @@ betypeinit(void)
        zprog.from.index = D_NONE;
        zprog.from.scale = 0;
        zprog.to = zprog.from;
+       arch.zprog = zprog;
 
        listinit6();
 }
+
+void
+main(int argc, char **argv)
+{
+       arch.thechar = thechar;
+       arch.thestring = thestring;
+       arch.thelinkarch = thelinkarch;
+       arch.typedefs = typedefs;
+       arch.zprog = zprog;
+       arch.ACALL = ACALL;
+       arch.ACHECKNIL = ACHECKNIL;
+       arch.ADATA = ADATA;
+       arch.AFUNCDATA = AFUNCDATA;
+       arch.AGLOBL = AGLOBL;
+       arch.AJMP = AJMP;
+       arch.ANAME = ANAME;
+       arch.ANOP = ANOP;
+       arch.APCDATA = APCDATA;
+       arch.ARET = ARET;
+       arch.ASIGNAME = ASIGNAME;
+       arch.ATEXT = ATEXT;
+       arch.ATYPE = ATYPE;
+       arch.AUNDEF = AUNDEF;
+       arch.AVARDEF = AVARDEF;
+       arch.AVARKILL = AVARKILL;
+       arch.D_AUTO = D_AUTO;
+       arch.D_BRANCH = D_BRANCH;
+       arch.D_NONE = D_NONE;
+       arch.D_PARAM = D_PARAM;
+       arch.MAXWIDTH = MAXWIDTH;
+       arch.afunclit = afunclit;
+       arch.anyregalloc = anyregalloc;
+       arch.betypeinit = betypeinit;
+       arch.bgen = bgen;
+       arch.cgen = cgen;
+       arch.cgen_asop = cgen_asop;
+       arch.cgen_call = cgen_call;
+       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;
+       arch.regopt = regopt;
+       arch.regtyp = regtyp;
+       arch.sameaddr = sameaddr;
+       arch.smallindir = smallindir;
+       arch.stackaddr = stackaddr;
+       arch.unpatch = unpatch;
+       
+       gcmain(argc, argv);
+}
index fe69d5c968d0cd27d951ee0ca31e1a41b9ed305e..97fd8818cf21383f24b2eba6306b674ffed0642e 100644 (file)
@@ -16,13 +16,7 @@ EXTERN       uchar   reg[D_NONE];
 EXTERN int32   pcloc;          // instruction counter
 EXTERN Strlit  emptystring;
 EXTERN Prog    zprog;
-EXTERN Node*   newproc;
-EXTERN Node*   deferproc;
-EXTERN Node*   deferreturn;
-EXTERN Node*   panicindex;
-EXTERN Node*   panicslice;
 EXTERN Node*   panicdiv;
-EXTERN Node*   throwreturn;
 extern vlong   unmappedzero;
 extern int     addptr;
 extern int     cmpptr;
@@ -120,3 +114,55 @@ void       datagostring(Strlit*, Addr*);
 void   listinit(void);
 
 void   zaddr(Biobuf*, Addr*, int, int);
+
+void afunclit(Addr*, Node*);
+int anyregalloc(void);
+void betypeinit(void);
+void bgen(Node*, int, int, Prog*);
+void cgen(Node*, Node*);
+void cgen_asop(Node*);
+void cgen_call(Node*, int);
+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 *nam);
+void   ggloblsym(Sym *s, int32 width, int8 flags);
+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*);
+void regopt(Prog*);
+int regtyp(Addr*);
+int sameaddr(Addr*, Addr*);
+int smallindir(Addr*, Addr*);
+int stackaddr(Addr*);
+Prog* unpatch(Prog*);
+
index 493171ef82db80ff7b6ba1bb8a9662ee06dce717..fd8b5c30e53b881f4708c551fc1fb5c20c6b588c 100644 (file)
@@ -28,7 +28,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include       "../gc/popt.h"
 
 #define        Z       N
 #define        Adr     Addr
@@ -177,60 +176,5 @@ int        BtoF(uint32);
 /*
  * prog.c
  */
-typedef struct ProgInfo ProgInfo;
-struct ProgInfo
-{
-       uint32 flags; // the bits below
-       uint32 reguse; // registers implicitly used by this instruction
-       uint32 regset; // registers implicitly set by this instruction
-       uint32 regindex; // registers used by addressing mode
-};
-
-enum
-{
-       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
-       Pseudo = 1<<1,
-       
-       // There's nothing to say about the instruction,
-       // but it's still okay to see.
-       OK = 1<<2,
-
-       // Size of right-side write, or right-side read if no write.
-       SizeB = 1<<3,
-       SizeW = 1<<4,
-       SizeL = 1<<5,
-       SizeQ = 1<<6,
-       SizeF = 1<<7, // float aka float32
-       SizeD = 1<<8, // double aka float64
-
-       // Left side (Prog.from): address taken, read, write.
-       LeftAddr = 1<<9,
-       LeftRead = 1<<10,
-       LeftWrite = 1<<11,
-       
-       // Right side (Prog.to): address taken, read, write.
-       RightAddr = 1<<12,
-       RightRead = 1<<13,
-       RightWrite = 1<<14,
-
-       // Set, use, or kill of carry bit.
-       // Kill means we never look at the carry bit after this kind of instruction.
-       SetCarry = 1<<15,
-       UseCarry = 1<<16,
-       KillCarry = 1<<17,
-
-       // Instruction kinds
-       Move = 1<<18, // straight move
-       Conv = 1<<19, // size conversion
-       Cjmp = 1<<20, // conditional jump
-       Break = 1<<21, // breaks control flow (no fallthrough)
-       Call = 1<<22, // function call
-       Jump = 1<<23, // jump
-       Skip = 1<<24, // data instruction
-
-       // Special cases for register use.
-       ShiftCX = 1<<25, // possible shift by CX
-       ImulAXDX = 1<<26, // possible multiply into DX:AX
-};
 
 void proginfo(ProgInfo*, Prog*);
index a0eb3493759605391d578226d870db0c4421beb8..3c15f96c08df544ff9e7f1e0028df43d2ae753f3 100644 (file)
@@ -42,6 +42,90 @@ betypeinit(void)
        zprog.from.index = D_NONE;
        zprog.from.scale = 0;
        zprog.to = zprog.from;
+       arch.zprog = zprog;
 
        listinit8();
 }
+
+void
+main(int argc, char **argv)
+{
+       arch.thechar = thechar;
+       arch.thestring = thestring;
+       arch.thelinkarch = thelinkarch;
+       arch.typedefs = typedefs;
+       arch.zprog = zprog;
+       arch.ACALL = ACALL;
+       arch.ACHECKNIL = ACHECKNIL;
+       arch.ADATA = ADATA;
+       arch.AFUNCDATA = AFUNCDATA;
+       arch.AGLOBL = AGLOBL;
+       arch.AJMP = AJMP;
+       arch.ANAME = ANAME;
+       arch.ANOP = ANOP;
+       arch.APCDATA = APCDATA;
+       arch.ARET = ARET;
+       arch.ASIGNAME = ASIGNAME;
+       arch.ATEXT = ATEXT;
+       arch.ATYPE = ATYPE;
+       arch.AUNDEF = AUNDEF;
+       arch.AVARDEF = AVARDEF;
+       arch.AVARKILL = AVARKILL;
+       arch.D_AUTO = D_AUTO;
+       arch.D_BRANCH = D_BRANCH;
+       arch.D_NONE = D_NONE;
+       arch.D_PARAM = D_PARAM;
+       arch.MAXWIDTH = MAXWIDTH;
+       arch.afunclit = afunclit;
+       arch.anyregalloc = anyregalloc;
+       arch.betypeinit = betypeinit;
+       arch.bgen = bgen;
+       arch.cgen = cgen;
+       arch.cgen_asop = cgen_asop;
+       arch.cgen_call = cgen_call;
+       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;
+       arch.regopt = regopt;
+       arch.regtyp = regtyp;
+       arch.sameaddr = sameaddr;
+       arch.smallindir = smallindir;
+       arch.stackaddr = stackaddr;
+       arch.unpatch = unpatch;
+       
+       gcmain(argc, argv);
+}
index 238f9276567d85c3f3c93c51a1acbb798b163dcd..d3535f5ff9ea8025d07295371167a84c61ffdd3c 100644 (file)
@@ -24,13 +24,7 @@ EXTERN       uchar   reg[D_NONE];
 EXTERN int32   pcloc;          // instruction counter
 EXTERN Strlit  emptystring;
 EXTERN Prog    zprog;
-EXTERN Node*   newproc;
-EXTERN Node*   deferproc;
-EXTERN Node*   deferreturn;
-EXTERN Node*   panicindex;
-EXTERN Node*   panicslice;
 EXTERN Node*   panicdiv;
-EXTERN Node*   throwreturn;
 extern uint32  unmappedzero;
 
 
@@ -133,3 +127,54 @@ void       datagostring(Strlit*, Addr*);
 void   listinit(void);
 
 void   zaddr(Biobuf*, Addr*, int, int);
+
+void afunclit(Addr*, Node*);
+int anyregalloc(void);
+void betypeinit(void);
+void bgen(Node*, int, int, Prog*);
+void cgen(Node*, Node*);
+void cgen_asop(Node*);
+void cgen_call(Node*, int);
+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 *nam);
+void   ggloblsym(Sym *s, int32 width, int8 flags);
+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*);
+void regopt(Prog*);
+int regtyp(Addr*);
+int sameaddr(Addr*, Addr*);
+int smallindir(Addr*, Addr*);
+int stackaddr(Addr*);
+Prog* unpatch(Prog*);
index 5445f91275e792fa8c76534a57e743e017053ded..d31cd26007f52388baf75b9423151fa8ac7ba716 100644 (file)
@@ -28,7 +28,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include       "../gc/popt.h"
 
 #define        Z       N
 #define        Adr     Addr
@@ -195,60 +194,4 @@ int        BtoF(uint32);
 /*
  * prog.c
  */
-typedef struct ProgInfo ProgInfo;
-struct ProgInfo
-{
-       uint32 flags; // the bits below
-       uint32 reguse; // registers implicitly used by this instruction
-       uint32 regset; // registers implicitly set by this instruction
-       uint32 regindex; // registers used by addressing mode
-};
-
-enum
-{
-       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
-       Pseudo = 1<<1,
-       
-       // There's nothing to say about the instruction,
-       // but it's still okay to see.
-       OK = 1<<2,
-
-       // Size of right-side write, or right-side read if no write.
-       SizeB = 1<<3,
-       SizeW = 1<<4,
-       SizeL = 1<<5,
-       SizeQ = 1<<6,
-       SizeF = 1<<7, // float aka float32
-       SizeD = 1<<8, // double aka float64
-
-       // Left side (Prog.from): address taken, read, write.
-       LeftAddr = 1<<9,
-       LeftRead = 1<<10,
-       LeftWrite = 1<<11,
-       
-       // Right side (Prog.to): address taken, read, write.
-       RightAddr = 1<<12,
-       RightRead = 1<<13,
-       RightWrite = 1<<14,
-
-       // Set, use, or kill of carry bit.
-       // Kill means we never look at the carry bit after this kind of instruction.
-       SetCarry = 1<<15,
-       UseCarry = 1<<16,
-       KillCarry = 1<<17,
-
-       // Instruction kinds
-       Move = 1<<18, // straight move
-       Conv = 1<<19, // size conversion
-       Cjmp = 1<<20, // conditional jump
-       Break = 1<<21, // breaks control flow (no fallthrough)
-       Call = 1<<22, // function call
-       Jump = 1<<23, // jump
-       Skip = 1<<24, // data instruction
-
-       // Special cases for register use.
-       ShiftCX = 1<<25, // possible shift by CX
-       ImulAXDX = 1<<26, // possible multiply into DX:AX
-};
-
 void proginfo(ProgInfo*, Prog*);
index 67514faa47ecd746d10ee0bfa1339d0b9b8d8ce8..a4aa332282214d2b3cbea89906f56482c7bbd3f5 100644 (file)
@@ -14,10 +14,12 @@ void
 linkarchinit(void)
 {
        thestring = getgoarch();
+       arch.thestring = thestring;
        if(strcmp(thestring, "ppc64le") == 0)
                thelinkarch = &linkppc64le;
        else
                thelinkarch = &linkppc64;
+       arch.thelinkarch = thelinkarch;
 }
 
 vlong MAXWIDTH = 1LL<<50;
@@ -49,6 +51,90 @@ betypeinit(void)
        zprog.from.reg = NREG;
        zprog.to = zprog.from;
        zprog.from3 = zprog.from;
+       arch.zprog = zprog;
 
        listinit9();
 }
+
+void
+main(int argc, char **argv)
+{
+       arch.thechar = thechar;
+       arch.thestring = thestring;
+       arch.thelinkarch = thelinkarch;
+       arch.typedefs = typedefs;
+       arch.zprog = zprog;
+       arch.ACALL = ABL;
+       arch.ACHECKNIL = ACHECKNIL;
+       arch.ADATA = ADATA;
+       arch.AFUNCDATA = AFUNCDATA;
+       arch.AGLOBL = AGLOBL;
+       arch.AJMP = ABR;
+       arch.ANAME = ANAME;
+       arch.ANOP = ANOP;
+       arch.APCDATA = APCDATA;
+       arch.ARET = ARETURN;
+       arch.ASIGNAME = ASIGNAME;
+       arch.ATEXT = ATEXT;
+       arch.ATYPE = ATYPE;
+       arch.AUNDEF = AUNDEF;
+       arch.AVARDEF = AVARDEF;
+       arch.AVARKILL = AVARKILL;
+       arch.D_AUTO = D_AUTO;
+       arch.D_BRANCH = D_BRANCH;
+       arch.D_NONE = D_NONE;
+       arch.D_PARAM = D_PARAM;
+       arch.MAXWIDTH = MAXWIDTH;
+       arch.afunclit = afunclit;
+       arch.anyregalloc = anyregalloc;
+       arch.betypeinit = betypeinit;
+       arch.bgen = bgen;
+       arch.cgen = cgen;
+       arch.cgen_asop = cgen_asop;
+       arch.cgen_call = cgen_call;
+       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;
+       arch.regopt = regopt;
+       arch.regtyp = regtyp;
+       arch.sameaddr = sameaddr;
+       arch.smallindir = smallindir;
+       arch.stackaddr = stackaddr;
+       arch.unpatch = unpatch;
+       
+       gcmain(argc, argv);
+}
index 703fbd0a8715d99e50d0ee7f52e83680469c6f32..ea9d52db8ebd7117d5ebc074cae8cdc6d8ec0e90 100644 (file)
@@ -19,13 +19,7 @@ EXTERN       uchar   reg[NREG+NFREG];
 EXTERN int32   pcloc;          // instruction counter
 EXTERN Strlit  emptystring;
 EXTERN Prog    zprog;
-EXTERN Node*   newproc;
-EXTERN Node*   deferproc;
-EXTERN Node*   deferreturn;
-EXTERN Node*   panicindex;
-EXTERN Node*   panicslice;
 EXTERN Node*   panicdiv;
-EXTERN Node*   throwreturn;
 extern vlong   unmappedzero;
 
 /*
@@ -115,3 +109,55 @@ void       datagostring(Strlit*, Addr*);
 void   listinit(void);
 
 void   zaddr(Biobuf*, Addr*, int, int);
+
+void afunclit(Addr*, Node*);
+int anyregalloc(void);
+void betypeinit(void);
+void bgen(Node*, int, int, Prog*);
+void cgen(Node*, Node*);
+void cgen_asop(Node*);
+void cgen_call(Node*, int);
+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 *nam);
+void   ggloblsym(Sym *s, int32 width, int8 flags);
+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*);
+void regopt(Prog*);
+int regtyp(Addr*);
+int sameaddr(Addr*, Addr*);
+int smallindir(Addr*, Addr*);
+int stackaddr(Addr*);
+Prog* unpatch(Prog*);
+
index 6a07b268f212d7866ec81f03fe68ad9acc4b17e2..ab586434cc1cae4fd0dcb2fb7d7a3e4d51f3b587 100644 (file)
@@ -28,7 +28,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#include       "../gc/popt.h"
 
 #define        Z       N
 #define        Adr     Addr
@@ -170,59 +169,6 @@ int        BtoF(uint64);
 /*
  * prog.c
  */
-typedef struct ProgInfo ProgInfo;
-struct ProgInfo
-{
-       uint32 flags; // the bits below
-       uint64 reguse; // registers implicitly used by this instruction
-       uint64 regset; // registers implicitly set by this instruction
-       uint64 regindex; // registers used by addressing mode
-};
-
-enum
-{
-       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
-       Pseudo = 1<<1,
-       
-       // There's nothing to say about the instruction,
-       // but it's still okay to see.
-       OK = 1<<2,
-
-       // Size of right-side write, or right-side read if no write.
-       SizeB = 1<<3,
-       SizeW = 1<<4,
-       SizeL = 1<<5,
-       SizeQ = 1<<6,
-       SizeF = 1<<7, // float aka float32
-       SizeD = 1<<8, // double aka float64
-
-       // Left side (Prog.from): address taken, read, write.
-       LeftAddr = 1<<9,
-       LeftRead = 1<<10,
-       LeftWrite = 1<<11,
-
-       // Register in middle (Prog.reg); only ever read.
-       RegRead = 1<<12,
-       CanRegRead = 1<<13,
-
-       // Right side (Prog.to): address taken, read, write.
-       RightAddr = 1<<14,
-       RightRead = 1<<15,
-       RightWrite = 1<<16,
-
-       // Instruction updates whichever of from/to is type D_OREG
-       PostInc = 1<<17,
-
-       // Instruction kinds
-       Move = 1<<18, // straight move
-       Conv = 1<<19, // size conversion
-       Cjmp = 1<<20, // conditional jump
-       Break = 1<<21, // breaks control flow (no fallthrough)
-       Call = 1<<22, // function call
-       Jump = 1<<23, // jump
-       Skip = 1<<24, // data instruction
-};
-
 void proginfo(ProgInfo*, Prog*);
 
 // Many Power ISA arithmetic and logical instructions come in four
index 82c2273b234a715305de812da3c6d587e9cbf57d..e36df51f5dce1afcddebc0c3f652c82c55ea2f82 100644 (file)
@@ -516,43 +516,18 @@ var deptab = []struct {
                "anames9.c",
        }},
        {"cmd/gc", []string{
-               "-cplx.c",
-               "-pgen.c",
-               "-plive.c",
-               "-popt.c",
-               "-y1.tab.c", // makefile dreg
                "opnames.h",
        }},
        {"cmd/5g", []string{
-               "../gc/cplx.c",
-               "../gc/pgen.c",
-               "../gc/plive.c",
-               "../gc/popt.c",
-               "../gc/popt.h",
                "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
        }},
        {"cmd/6g", []string{
-               "../gc/cplx.c",
-               "../gc/pgen.c",
-               "../gc/plive.c",
-               "../gc/popt.c",
-               "../gc/popt.h",
                "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
        }},
        {"cmd/8g", []string{
-               "../gc/cplx.c",
-               "../gc/pgen.c",
-               "../gc/plive.c",
-               "../gc/popt.c",
-               "../gc/popt.h",
                "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
        }},
        {"cmd/9g", []string{
-               "../gc/cplx.c",
-               "../gc/pgen.c",
-               "../gc/plive.c",
-               "../gc/popt.c",
-               "../gc/popt.h",
                "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
        }},
        {"cmd/5l", []string{
index 57daaa974558d6a4a7e57a47a1e278bdceef11e2..cf03994184170bc0ff9f9b4bce17d61d14f26c1c 100644 (file)
@@ -35,7 +35,7 @@ offmod(Type *t)
                        fatal("offmod: not TFIELD: %lT", f);
                f->width = o;
                o += widthptr;
-               if(o >= MAXWIDTH) {
+               if(o >= arch.MAXWIDTH) {
                        yyerror("interface too large");
                        o = widthptr;
                }
@@ -86,7 +86,7 @@ widstruct(Type *errtype, Type *t, vlong o, int flag)
                if(w == 0)
                        lastzero = o;
                o += w;
-               if(o >= MAXWIDTH) {
+               if(o >= arch.MAXWIDTH) {
                        yyerror("type %lT too large", errtype);
                        o = 8;  // small but nonzero
                }
@@ -260,7 +260,7 @@ dowidth(Type *t)
 
                        dowidth(t->type);
                        if(t->type->width != 0) {
-                               cap = (MAXWIDTH-1) / t->type->width;
+                               cap = (arch.MAXWIDTH-1) / t->type->width;
                                if(t->bound > cap)
                                        yyerror("type %lT larger than address space", t);
                        }
@@ -613,15 +613,15 @@ typeinit(void)
        simtype[TFUNC] = tptr;
        simtype[TUNSAFEPTR] = tptr;
 
-       /* pick up the backend typedefs */
-       for(i=0; typedefs[i].name; i++) {
-               s = lookup(typedefs[i].name);
-               s1 = pkglookup(typedefs[i].name, builtinpkg);
+       /* pick up the backend arch.typedefs */
+       for(i=0; arch.typedefs[i].name; i++) {
+               s = lookup(arch.typedefs[i].name);
+               s1 = pkglookup(arch.typedefs[i].name, builtinpkg);
 
-               etype = typedefs[i].etype;
+               etype = arch.typedefs[i].etype;
                if(etype < 0 || etype >= nelem(types))
                        fatal("typeinit: %s bad etype", s->name);
-               sameas = typedefs[i].sameas;
+               sameas = arch.typedefs[i].sameas;
                if(sameas < 0 || sameas >= nelem(types))
                        fatal("typeinit: %s bad sameas", s->name);
                simtype[etype] = sameas;
index 6f3dc93572e2ec50b7303628f39c49a9ac34d237..d3fb9525584da00f299c4616fda80ffed92d1352 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <u.h>
 #include <libc.h>
-#include "gg.h"
+#include "go.h"
 
 static void    subnode(Node *nr, Node *ni, Node *nc);
 static void    minus(Node *nl, Node *res);
@@ -78,8 +78,8 @@ complexmove(Node *f, Node *t)
                subnode(&n1, &n2, f);
                subnode(&n3, &n4, t);
 
-               cgen(&n1, &n3);
-               cgen(&n2, &n4);
+               arch.cgen(&n1, &n3);
+               arch.cgen(&n2, &n4);
                break;
        }
 }
@@ -151,9 +151,9 @@ complexgen(Node *n, Node *res)
                if(res->addable) {
                        subnode(&n1, &n2, res);
                        tempname(&tmp, n1.type);
-                       cgen(n->left, &tmp);
-                       cgen(n->right, &n2);
-                       cgen(&tmp, &n1);
+                       arch.cgen(n->left, &tmp);
+                       arch.cgen(n->right, &n2);
+                       arch.cgen(&tmp, &n1);
                        return;
                }
                break;
@@ -168,10 +168,10 @@ complexgen(Node *n, Node *res)
                }
                subnode(&n1, &n2, nl);
                if(n->op == OREAL) {
-                       cgen(&n1, res);
+                       arch.cgen(&n1, res);
                        return;
                }
-               cgen(&n2, res);
+               arch.cgen(&n2, res);
                return;
        }
 
@@ -191,9 +191,9 @@ complexgen(Node *n, Node *res)
        }
 
        if(!res->addable) {
-               igen(res, &n1, N);
-               cgen(n, &n1);
-               regfree(&n1);
+               arch.igen(res, &n1, N);
+               arch.cgen(n, &n1);
+               arch.regfree(&n1);
                return;
        }
        if(n->addable) {
@@ -214,9 +214,9 @@ complexgen(Node *n, Node *res)
        case OCALLFUNC:
        case OCALLMETH:
        case OCALLINTER:
-               igen(n, &n1, res);
+               arch.igen(n, &n1, res);
                complexmove(&n1, res);
-               regfree(&n1);
+               arch.regfree(&n1);
                return;
 
        case OCONV:
@@ -239,18 +239,18 @@ complexgen(Node *n, Node *res)
        if(nr != N) {
                if(nl->ullman > nr->ullman && !nl->addable) {
                        tempname(&tnl, nl->type);
-                       cgen(nl, &tnl);
+                       arch.cgen(nl, &tnl);
                        nl = &tnl;
                }
                if(!nr->addable) {
                        tempname(&tnr, nr->type);
-                       cgen(nr, &tnr);
+                       arch.cgen(nr, &tnr);
                        nr = &tnr;
                }
        }
        if(!nl->addable) {
                tempname(&tnl, nl->type);
-               cgen(nl, &tnl);
+               arch.cgen(nl, &tnl);
                nl = &tnl;
        }
 
@@ -289,18 +289,18 @@ complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to)
        if(nr != N) {
                if(nl->ullman > nr->ullman && !nl->addable) {
                        tempname(&tnl, nl->type);
-                       cgen(nl, &tnl);
+                       arch.cgen(nl, &tnl);
                        nl = &tnl;
                }
                if(!nr->addable) {
                        tempname(&tnr, nr->type);
-                       cgen(nr, &tnr);
+                       arch.cgen(nr, &tnr);
                        nr = &tnr;
                }
        }
        if(!nl->addable) {
                tempname(&tnl, nl->type);
-               cgen(nl, &tnl);
+               arch.cgen(nl, &tnl);
                nl = &tnl;
        }
 
@@ -331,7 +331,7 @@ complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to)
        if(op == ONE)
                true = !true;
 
-       bgen(&na, true, likely, to);
+       arch.bgen(&na, true, likely, to);
 }
 
 void
@@ -387,7 +387,7 @@ minus(Node *nl, Node *res)
        ra.op = OMINUS;
        ra.left = nl;
        ra.type = nl->type;
-       cgen(&ra, res);
+       arch.cgen(&ra, res);
 }
 
 // build and execute tree
@@ -424,14 +424,14 @@ complexadd(int op, Node *nl, Node *nr, Node *res)
        ra.left = &n1;
        ra.right = &n3;
        ra.type = n1.type;
-       cgen(&ra, &n5);
+       arch.cgen(&ra, &n5);
 
        memset(&ra, 0, sizeof(ra));
        ra.op = op;
        ra.left = &n2;
        ra.right = &n4;
        ra.type = n2.type;
-       cgen(&ra, &n6);
+       arch.cgen(&ra, &n6);
 }
 
 // build and execute tree
@@ -467,7 +467,7 @@ complexmul(Node *nl, Node *nr, Node *res)
        ra.left = &rm1;
        ra.right = &rm2;
        ra.type = rm1.type;
-       cgen(&ra, &tmp);
+       arch.cgen(&ra, &tmp);
 
        // imag part
        memset(&rm1, 0, sizeof(rm1));
@@ -487,8 +487,8 @@ complexmul(Node *nl, Node *nr, Node *res)
        ra.left = &rm1;
        ra.right = &rm2;
        ra.type = rm1.type;
-       cgen(&ra, &n6);
+       arch.cgen(&ra, &n6);
 
        // tmp ->real part
-       cgen(&tmp, &n5);
+       arch.cgen(&tmp, &n5);
 }
index 241912c9092055d760a7b06c2a8812a0b9906117..8685aa0def47d727fc39fa61282249b379a7c8fe 100644 (file)
@@ -538,7 +538,7 @@ dumpasmhdr(void)
        b = Bopen(asmhdr, OWRITE);
        if(b == nil)
                fatal("open %s: %r", asmhdr);
-       Bprint(b, "// generated by %cg -asmhdr from package %s\n\n", thechar, localpkg->name);
+       Bprint(b, "// generated by %cg -asmhdr from package %s\n\n", arch.thechar, localpkg->name);
        for(l=asmlist; l; l=l->next) {
                n = l->n;
                if(isblanksym(n->sym))
index c7c9fcdaff8763fc347cd7219f6b9024859c0444..20c17bd46a10bc60f0ee8cced31d21fba01c887b 100644 (file)
@@ -265,7 +265,7 @@ gen(Node *n)
 //dump("gen", n);
 
        lno = setlineno(n);
-       wasregalloc = anyregalloc();
+       wasregalloc = arch.anyregalloc();
 
        if(n == N)
                goto ret;
@@ -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 = unpatch(p1);
-                       patch(p1, pc);
+                       p2 = arch.unpatch(p1);
+                       arch.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)
-                       gjmp(lab->labelpc);
+                       arch.gjmp(lab->labelpc);
                else
-                       lab->gotopc = gjmp(lab->gotopc);
+                       lab->gotopc = arch.gjmp(lab->gotopc);
                break;
 
        case OBREAK:
@@ -349,14 +349,14 @@ gen(Node *n)
                                yyerror("invalid break label %S", n->left->sym);
                                break;
                        }
-                       gjmp(lab->breakpc);
+                       arch.gjmp(lab->breakpc);
                        break;
                }
                if(breakpc == P) {
                        yyerror("break is not in a loop");
                        break;
                }
-               gjmp(breakpc);
+               arch.gjmp(breakpc);
                break;
 
        case OCONTINUE:
@@ -371,20 +371,20 @@ gen(Node *n)
                                yyerror("invalid continue label %S", n->left->sym);
                                break;
                        }
-                       gjmp(lab->continpc);
+                       arch.gjmp(lab->continpc);
                        break;
                }
                if(continpc == P) {
                        yyerror("continue is not in a loop");
                        break;
                }
-               gjmp(continpc);
+               arch.gjmp(continpc);
                break;
 
        case OFOR:
                sbreak = breakpc;
-               p1 = gjmp(P);                   //              goto test
-               breakpc = gjmp(P);              // break:       goto done
+               p1 = arch.gjmp(P);                      //              goto test
+               breakpc = arch.gjmp(P);         // break:       goto done
                scontin = continpc;
                continpc = pc;
 
@@ -394,11 +394,11 @@ gen(Node *n)
                        lab->continpc = continpc;
                }
                gen(n->nincr);                          // contin:      incr
-               patch(p1, pc);                          // test:
-               bgen(n->ntest, 0, -1, breakpc);         //              if(!test) goto break
+               arch.patch(p1, pc);                             // test:
+               arch.bgen(n->ntest, 0, -1, breakpc);            //              if(!test) goto break
                genlist(n->nbody);                              //              body
-               gjmp(continpc);
-               patch(breakpc, pc);                     // done:
+               arch.gjmp(continpc);
+               arch.patch(breakpc, pc);                        // done:
                continpc = scontin;
                breakpc = sbreak;
                if(lab) {
@@ -408,29 +408,29 @@ gen(Node *n)
                break;
 
        case OIF:
-               p1 = gjmp(P);                   //              goto test
-               p2 = gjmp(P);                   // p2:          goto else
-               patch(p1, pc);                          // test:
-               bgen(n->ntest, 0, -n->likely, p2);              //              if(!test) goto p2
+               p1 = arch.gjmp(P);                      //              goto test
+               p2 = arch.gjmp(P);                      // p2:          goto else
+               arch.patch(p1, pc);                             // test:
+               arch.bgen(n->ntest, 0, -n->likely, p2);         //              if(!test) goto p2
                genlist(n->nbody);                              //              then
-               p3 = gjmp(P);                   //              goto done
-               patch(p2, pc);                          // else:
+               p3 = arch.gjmp(P);                      //              goto done
+               arch.patch(p2, pc);                             // else:
                genlist(n->nelse);                              //              else
-               patch(p3, pc);                          // done:
+               arch.patch(p3, pc);                             // done:
                break;
 
        case OSWITCH:
                sbreak = breakpc;
-               p1 = gjmp(P);                   //              goto test
-               breakpc = gjmp(P);              // break:       goto done
+               p1 = arch.gjmp(P);                      //              goto test
+               breakpc = arch.gjmp(P);         // break:       goto done
 
                // define break label
                if((lab = stmtlabel(n)) != L)
                        lab->breakpc = breakpc;
 
-               patch(p1, pc);                          // test:
+               arch.patch(p1, pc);                             // test:
                genlist(n->nbody);                              //              switch(test) body
-               patch(breakpc, pc);                     // done:
+               arch.patch(breakpc, pc);                        // done:
                breakpc = sbreak;
                if(lab != L)
                        lab->breakpc = P;
@@ -438,23 +438,23 @@ gen(Node *n)
 
        case OSELECT:
                sbreak = breakpc;
-               p1 = gjmp(P);                   //              goto test
-               breakpc = gjmp(P);              // break:       goto done
+               p1 = arch.gjmp(P);                      //              goto test
+               breakpc = arch.gjmp(P);         // break:       goto done
 
                // define break label
                if((lab = stmtlabel(n)) != L)
                        lab->breakpc = breakpc;
 
-               patch(p1, pc);                          // test:
+               arch.patch(p1, pc);                             // test:
                genlist(n->nbody);                              //              select() body
-               patch(breakpc, pc);                     // done:
+               arch.patch(breakpc, pc);                        // done:
                breakpc = sbreak;
                if(lab != L)
                        lab->breakpc = P;
                break;
 
        case OASOP:
-               cgen_asop(n);
+               arch.cgen_asop(n);
                break;
 
        case ODCL:
@@ -472,11 +472,11 @@ gen(Node *n)
                break;
 
        case OCALLINTER:
-               cgen_callinter(n, N, 0);
+               arch.cgen_callinter(n, N, 0);
                break;
 
        case OCALLFUNC:
-               cgen_call(n, 0);
+               arch.cgen_call(n, 0);
                break;
 
        case OPROC:
@@ -489,7 +489,7 @@ gen(Node *n)
 
        case ORETURN:
        case ORETJMP:
-               cgen_ret(n);
+               arch.cgen_ret(n);
                break;
        
        case OCHECKNIL:
@@ -502,7 +502,7 @@ gen(Node *n)
        }
 
 ret:
-       if(anyregalloc() != wasregalloc) {
+       if(arch.anyregalloc() != wasregalloc) {
                dump("node", n);
                fatal("registers left allocated");
        }
@@ -536,7 +536,7 @@ cgen_callmeth(Node *n, int proc)
 
        if(n2.left->op == ONAME)
                n2.left->class = PFUNC;
-       cgen_call(&n2, proc);
+       arch.cgen_call(&n2, proc);
 }
 
 /*
@@ -554,11 +554,11 @@ cgen_proc(Node *n, int proc)
                break;
 
        case OCALLINTER:
-               cgen_callinter(n->left, N, proc);
+               arch.cgen_callinter(n->left, N, proc);
                break;
 
        case OCALLFUNC:
-               cgen_call(n->left, proc);
+               arch.cgen_call(n->left, proc);
                break;
        }
 
@@ -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)
-                       gused(nr);
+                       arch.gused(nr);
                break;
 
        // unary
@@ -643,7 +643,7 @@ cgen_discard(Node *nr)
        default:
                tempname(&tmp, nr->type);
                cgen_as(&tmp, nr);
-               gused(&tmp);
+               arch.gused(&tmp);
        }
 }
 
@@ -705,7 +705,7 @@ clearslim(Node *n)
        }
 
        ullmancalc(&z);
-       cgen(&z, n);
+       arch.cgen(&z, n);
 }
 
 /*
@@ -739,10 +739,10 @@ cgen_as(Node *nl, Node *nr)
                tl = nl->type;
                if(tl == T)
                        return;
-               if(isfat(tl)) {
+               if(arch.isfat(tl)) {
                        if(nl->op == ONAME)
                                gvardef(nl);
-                       clearfat(nl);
+                       arch.clearfat(nl);
                        return;
                }
                clearslim(nl);
@@ -753,7 +753,7 @@ cgen_as(Node *nl, Node *nr)
        if(tl == T)
                return;
 
-       cgen(nr, nl);
+       arch.cgen(nr, nl);
 }
 
 /*
@@ -773,17 +773,17 @@ cgen_eface(Node *n, Node *res)
        Node *tmp;
 
        tmp = temp(types[tptr]);
-       cgen(n->right, tmp);
+       arch.cgen(n->right, tmp);
 
        gvardef(res);
 
        dst = *res;
        dst.type = types[tptr];
        dst.xoffset += widthptr;
-       cgen(tmp, &dst);
+       arch.cgen(tmp, &dst);
 
        dst.xoffset -= widthptr;
-       cgen(n->left, &dst);
+       arch.cgen(n->left, &dst);
 }
 
 /*
@@ -824,7 +824,7 @@ cgen_slice(Node *n, Node *res)
 
        if(isnil(n->left)) {
                tempname(&src, n->left->type);
-               cgen(n->left, &src);
+               arch.cgen(n->left, &src);
        } else
                src = *n->left;
        if(n->op == OSLICE || n->op == OSLICE3 || n->op == OSLICESTR)
@@ -833,11 +833,11 @@ cgen_slice(Node *n, Node *res)
        if(n->op == OSLICEARR || n->op == OSLICE3ARR) {
                if(!isptr[n->left->type->etype])
                        fatal("slicearr is supposed to work on pointer: %+N\n", n);
-               cgen(&src, base);
+               arch.cgen(&src, base);
                cgen_checknil(base);
        } else {
                src.type = types[tptr];
-               cgen(&src, base);
+               arch.cgen(&src, base);
        }
        
        // committed to the update
@@ -846,9 +846,9 @@ cgen_slice(Node *n, Node *res)
        // compute len and cap.
        // len = n-i, cap = m-i, and offs = i*width.
        // computing offs last lets the multiply overwrite i.
-       cgen(len, tmplen);
+       arch.cgen(len, tmplen);
        if(n->op != OSLICESTR)
-               cgen(cap, tmpcap);
+               arch.cgen(cap, tmpcap);
 
        // if new cap != 0 { base += add }
        // This avoids advancing base past the end of the underlying array/string,
@@ -857,40 +857,40 @@ 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 = gjmp(P);
-               p2 = gjmp(P);
-               patch(p1, pc);
+               p1 = arch.gjmp(P);
+               p2 = arch.gjmp(P);
+               arch.patch(p1, pc);
 
                nodconst(&con, tmpcap->type, 0);
                cmp = nod(OEQ, tmpcap, &con);
                typecheck(&cmp, Erv);
-               bgen(cmp, 1, -1, p2);
+               arch.bgen(cmp, 1, -1, p2);
 
                add = nod(OADD, base, offs);
                typecheck(&add, Erv);
-               cgen(add, base);
+               arch.cgen(add, base);
 
-               patch(p2, pc);
+               arch.patch(p2, pc);
        }
 
        // dst.array = src.array  [ + lo *width ]
        dst = *res;
        dst.xoffset += Array_array;
        dst.type = types[tptr];
-       cgen(base, &dst);
+       arch.cgen(base, &dst);
 
        // dst.len = hi [ - lo ]
        dst = *res;
        dst.xoffset += Array_nel;
        dst.type = types[simtype[TUINT]];
-       cgen(tmplen, &dst);
+       arch.cgen(tmplen, &dst);
 
        if(n->op != OSLICESTR) {
                // dst.cap = cap [ - lo ]
                dst = *res;
                dst.xoffset += Array_cap;
                dst.type = types[simtype[TUINT]];
-               cgen(tmpcap, &dst);
+               arch.cgen(tmpcap, &dst);
        }
 }
 
index 3a1fdde82a73da5075acb2df6ec4381d6f176c78..9f3f1b582ce59d293d18b5668c5b31a410535ae8 100644 (file)
@@ -67,8 +67,6 @@ enum
        MaxStackVarSize = 10*1024*1024,
 };
 
-extern vlong   MAXWIDTH;
-
 /*
  * note this is the representation
  * of the compilers string literals,
@@ -753,8 +751,6 @@ struct      Typedef
        int     sameas;
 };
 
-extern Typedef typedefs[];
-
 typedef        struct  Sig     Sig;
 struct Sig
 {
@@ -975,9 +971,6 @@ EXTERN      int     widthreg;
 EXTERN Node*   typesw;
 EXTERN Node*   nblank;
 
-extern int     thechar;
-extern char*   thestring;
-extern LinkArch*       thelinkarch;
 EXTERN int     use_sse;
 
 EXTERN char*   hunk;
@@ -1293,7 +1286,6 @@ int       duint32(Sym *s, int off, uint32 v);
 int    duint64(Sym *s, int off, uint64 v);
 int    duint8(Sym *s, int off, uint8 v);
 int    duintptr(Sym *s, int off, uint64 v);
-int    dsname(Sym *s, int off, char *dat, int ndat);
 void   dumpobj(void);
 Sym*   stringsym(char*, int);
 void   slicebytes(Node*, char*, int);
@@ -1505,47 +1497,16 @@ EXTERN  Node*   nodfp;
 EXTERN int     disable_checknil;
 EXTERN vlong   zerosize;
 
-int    anyregalloc(void);
-void   betypeinit(void);
-void   bgen(Node *n, int true, int likely, Prog *to);
 void   checknil(Node*, NodeList**);
-void   expandchecks(Prog*);
-void   cgen(Node*, Node*);
-void   cgen_asop(Node *n);
-void   cgen_call(Node *n, int proc);
-void   cgen_callinter(Node *n, Node *res, int proc);
 void   cgen_checknil(Node*);
-void   cgen_ret(Node *n);
-void   clearfat(Node *n);
 void   compile(Node*);
-void   defframe(Prog*);
-int    dgostringptr(Sym*, int off, char *str);
-int    dgostrlitptr(Sym*, int off, Strlit*);
-int    dstringptr(Sym *s, int off, char *str);
-int    dsymptr(Sym *s, int off, Sym *x, int xoff);
 int    duintxx(Sym *s, int off, uint64 v, int wid);
-void   dumpdata(void);
-void   fixautoused(Prog*);
-void   gdata(Node*, Node*, int);
-void   gdatacomplex(Node*, Mpcplx*);
-void   gdatastring(Node*, Strlit*);
-void   ggloblnod(Node *nam);
-void   ggloblsym(Sym *s, int32 width, int8 flags);
 void   gvardef(Node*);
 void   gvarkill(Node*);
-Prog*  gjmp(Prog*);
-void   gused(Node*);
 void   movelarge(NodeList*);
-int    isfat(Type*);
-void   linkarchinit(void);
 void   liveness(Node*, Prog*, Sym*, Sym*);
 void   twobitwalktype1(Type*, vlong*, Bvec*);
-void   markautoused(Prog*);
-Plist* newplist(void);
-Node*  nodarg(Type*, int);
 void   nopout(Prog*);
-void   patch(Prog*, Prog*);
-Prog*  unpatch(Prog*);
 
 #pragma        varargck        type    "B"     Mpint*
 #pragma        varargck        type    "E"     int
@@ -1571,3 +1532,207 @@ Prog*   unpatch(Prog*);
  *     racewalk.c
  */
 void   racewalk(Node *fn);
+
+/*
+ *     flow.c
+ */
+typedef struct Flow Flow;
+typedef struct Graph Graph;
+
+struct Flow {
+       Prog*   prog;           // actual instruction
+       Flow*   p1;             // predecessors of this instruction: p1,
+       Flow*   p2;             // and then p2 linked though p2link.
+       Flow*   p2link;
+       Flow*   s1;             // successors of this instruction (at most two: s1 and s2).
+       Flow*   s2;
+       Flow*   link;           // next instruction in function code
+       
+       int32   active; // usable by client
+
+       int32   rpo;            // reverse post ordering
+       uint16  loop;           // x5 for every loop
+       uchar   refset;         // diagnostic generated
+};
+
+struct Graph
+{
+       Flow*   start;
+       int     num;
+       
+       // After calling flowrpo, rpo lists the flow nodes in reverse postorder,
+       // and each non-dead Flow node f has g->rpo[f->rpo] == f.
+       Flow**  rpo;
+};
+
+void   fixjmp(Prog*);
+Graph* flowstart(Prog*, int);
+void   flowrpo(Graph*);
+void   flowend(Graph*);
+void   mergetemp(Prog*);
+void   nilopt(Prog*);
+int    noreturn(Prog*);
+Flow*  uniqp(Flow*);
+Flow*  uniqs(Flow*);
+
+/*
+ *     interface to back end
+ */
+
+typedef struct ProgInfo ProgInfo;
+struct ProgInfo
+{
+       uint32 flags; // the bits below
+       uint64 reguse; // registers implicitly used by this instruction
+       uint64 regset; // registers implicitly set by this instruction
+       uint64 regindex; // registers used by addressing mode
+};
+
+enum
+{
+       // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
+       Pseudo = 1<<1,
+       
+       // There's nothing to say about the instruction,
+       // but it's still okay to see.
+       OK = 1<<2,
+
+       // Size of right-side write, or right-side read if no write.
+       SizeB = 1<<3,
+       SizeW = 1<<4,
+       SizeL = 1<<5,
+       SizeQ = 1<<6,
+       SizeF = 1<<7, // float aka float32
+       SizeD = 1<<8, // double aka float64
+
+       // Left side (Prog.from): address taken, read, write.
+       LeftAddr = 1<<9,
+       LeftRead = 1<<10,
+       LeftWrite = 1<<11,
+       
+       // Register in middle (Prog.reg); only ever read. (arm, ppc64)
+       RegRead = 1<<12,
+       CanRegRead = 1<<13,
+       
+       // Right side (Prog.to): address taken, read, write.
+       RightAddr = 1<<14,
+       RightRead = 1<<15,
+       RightWrite = 1<<16,
+
+       // Instruction kinds
+       Move = 1<<17, // straight move
+       Conv = 1<<18, // size conversion
+       Cjmp = 1<<19, // conditional jump
+       Break = 1<<20, // breaks control flow (no fallthrough)
+       Call = 1<<21, // function call
+       Jump = 1<<22, // jump
+       Skip = 1<<23, // data instruction
+
+       // Set, use, or kill of carry bit.
+       // Kill means we never look at the carry bit after this kind of instruction.
+       SetCarry = 1<<24,
+       UseCarry = 1<<25,
+       KillCarry = 1<<26,
+
+       // Special cases for register use. (amd64, 386)
+       ShiftCX = 1<<27, // possible shift by CX
+       ImulAXDX = 1<<28, // possible multiply into DX:AX
+
+       // Instruction updates whichever of from/to is type D_OREG. (ppc64)
+       PostInc = 1<<29,
+};
+
+typedef struct Arch Arch;
+
+struct Arch
+{
+       int thechar;
+       char *thestring;
+       LinkArch *thelinkarch;
+       Typedef *typedefs;
+       Prog zprog;
+       
+       int ACALL;
+       int ACHECKNIL;
+       int ADATA;
+       int AFUNCDATA;
+       int AGLOBL;
+       int AJMP;
+       int ANAME;
+       int ANOP;
+       int APCDATA;
+       int ARET;
+       int ASIGNAME;
+       int ATEXT;
+       int ATYPE;
+       int AUNDEF;
+       int AVARDEF;
+       int AVARKILL;
+       int D_AUTO;
+       int D_BRANCH;
+       int D_NONE;
+       int D_PARAM;
+       vlong MAXWIDTH;
+
+       void (*afunclit)(Addr*, Node*);
+       int (*anyregalloc)(void);
+       void (*betypeinit)(void);
+       void (*bgen)(Node*, int, int, Prog*);
+       void (*cgen)(Node*, Node*);
+       void (*cgen_asop)(Node*);
+       void (*cgen_call)(Node*, int);
+       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*);
+       void (*regopt)(Prog*);
+       int (*regtyp)(Addr*);
+       int (*sameaddr)(Addr*, Addr*);
+       int (*smallindir)(Addr*, Addr*);
+       int (*stackaddr)(Addr*);
+       Prog* (*unpatch)(Prog*);
+};
+
+EXTERN Arch arch;
+
+EXTERN Node *newproc;
+EXTERN Node *deferproc;
+EXTERN Node *deferreturn;
+EXTERN Node *panicindex;
+EXTERN Node *panicslice;
+EXTERN Node *throwreturn;
+
+int    gcmain(int, char**);
index 29fb2e1603ac11f5d49b79773801bc8f4525aa66..968eb174a487419881db82000847dd3575e9c4ee 100644 (file)
@@ -91,7 +91,7 @@ enum
 void
 usage(void)
 {
-       print("usage: %cg [options] file.go...\n", thechar);
+       print("usage: %cg [options] file.go...\n", arch.thechar);
        flagprint(1);
        exits("usage");
 }
@@ -133,17 +133,17 @@ doversion(void)
        p = expstring();
        if(strcmp(p, "X:none") == 0)
                p = "";
-       print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p);
+       print("%cg version %s%s%s\n", arch.thechar, getgoversion(), *p ? " " : "", p);
        exits(0);
 }
 
 int
-main(int argc, char *argv[])
+gcmain(int argc, char *argv[])
 {
        int i;
        NodeList *l;
        char *p;
-
+       
 #ifdef SIGBUS  
        signal(SIGBUS, fault);
        signal(SIGSEGV, fault);
@@ -154,15 +154,15 @@ main(int argc, char *argv[])
        // Tell the FPU to handle all exceptions.
        setfcr(FPPDBL|FPRNR);
 #endif
-       // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+       // Allow GOARCH=arch.thestring or GOARCH=arch.thestringsuffix,
        // but not other values.        
        p = getgoarch();
-       if(strncmp(p, thestring, strlen(thestring)) != 0)
-               sysfatal("cannot use %cg with GOARCH=%s", thechar, p);
+       if(strncmp(p, arch.thestring, strlen(arch.thestring)) != 0)
+               sysfatal("cannot use %cg with GOARCH=%s", arch.thechar, p);
        goarch = p;
 
-       linkarchinit();
-       ctxt = linknew(thelinkarch);
+       arch.linkarchinit();
+       ctxt = linknew(arch.thelinkarch);
        ctxt->diag = yyerror;
        ctxt->bso = &bstdout;
        Binit(&bstdout, 1, OWRITE);
@@ -260,7 +260,7 @@ main(int argc, char *argv[])
        flagcount("wb", "enable write barrier", &use_writebarrier);
        flagcount("x", "debug lexer", &debug['x']);
        flagcount("y", "debug declarations in canned imports (with -d)", &debug['y']);
-       if(thechar == '6')
+       if(arch.thechar == '6')
                flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
 
        flagparse(&argc, &argv, usage);
@@ -301,7 +301,7 @@ main(int argc, char *argv[])
        if(debug['l'] <= 1)
                debug['l'] = 1 - debug['l'];
 
-       if(thechar == '8') {
+       if(arch.thechar == '8') {
                p = getgo386();
                if(strcmp(p, "387") == 0)
                        use_sse = 0;
@@ -312,7 +312,7 @@ main(int argc, char *argv[])
        }
 
        fmtinstallgo();
-       betypeinit();
+       arch.betypeinit();
        if(widthptr == 0)
                fatal("betypeinit failed");
 
@@ -571,7 +571,7 @@ findpkg(Strlit *name)
                snprint(namebuf, sizeof(namebuf), "%Z.a", name);
                if(access(namebuf, 0) >= 0)
                        return 1;
-               snprint(namebuf, sizeof(namebuf), "%Z.%c", name, thechar);
+               snprint(namebuf, sizeof(namebuf), "%Z.%c", name, arch.thechar);
                if(access(namebuf, 0) >= 0)
                        return 1;
                return 0;
@@ -593,7 +593,7 @@ findpkg(Strlit *name)
                snprint(namebuf, sizeof(namebuf), "%s/%Z.a", p->dir, name);
                if(access(namebuf, 0) >= 0)
                        return 1;
-               snprint(namebuf, sizeof(namebuf), "%s/%Z.%c", p->dir, name, thechar);
+               snprint(namebuf, sizeof(namebuf), "%s/%Z.%c", p->dir, name, arch.thechar);
                if(access(namebuf, 0) >= 0)
                        return 1;
        }
@@ -610,7 +610,7 @@ findpkg(Strlit *name)
                snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.a", goroot, goos, goarch, suffixsep, suffix, name);
                if(access(namebuf, 0) >= 0)
                        return 1;
-               snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.%c", goroot, goos, goarch, suffixsep, suffix, name, thechar);
+               snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.%c", goroot, goos, goarch, suffixsep, suffix, name, arch.thechar);
                if(access(namebuf, 0) >= 0)
                        return 1;
        }
@@ -2253,10 +2253,10 @@ lexfini(void)
        }
 
        // backend-specific builtin types (e.g. int).
-       for(i=0; typedefs[i].name; i++) {
-               s = lookup(typedefs[i].name);
+       for(i=0; arch.typedefs[i].name; i++) {
+               s = lookup(arch.typedefs[i].name);
                if(s->def == N) {
-                       s->def = typenod(types[typedefs[i].etype]);
+                       s->def = typenod(types[arch.typedefs[i].etype]);
                        s->origpkg = builtinpkg;
                }
        }
@@ -2554,6 +2554,6 @@ mkpackage(char* pkgname)
                p = strrchr(namebuf, '.');
                if(p != nil)
                        *p = 0;
-               outfile = smprint("%s.%c", namebuf, thechar);
+               outfile = smprint("%s.%c", namebuf, arch.thechar);
        }
 }
index 7e4e97854a8748e8c40c56daed1f9abffb42bd97..a4d470615a67d87fc1f0dfe859e86ad927648aa0 100644 (file)
@@ -95,9 +95,9 @@ dumpobj(void)
        externdcl = tmp;
 
        zero = pkglookup("zerovalue", runtimepkg);
-       ggloblsym(zero, zerosize, DUPOK|RODATA);
+       arch.ggloblsym(zero, zerosize, DUPOK|RODATA);
 
-       dumpdata();
+       arch.dumpdata();
        writeobj(ctxt, bout);
 
        if(writearchive) {
@@ -106,7 +106,7 @@ dumpobj(void)
                if(size&1)
                        Bputc(bout, 0);
                Bseek(bout, startobj - ArhdrSize, 0);
-               snprint(namebuf, sizeof namebuf, "_go_.%c", thechar);
+               snprint(namebuf, sizeof namebuf, "_go_.%c", arch.thechar);
                formathdr(arhdr, namebuf, size);
                Bwrite(bout, arhdr, ArhdrSize);
        }
@@ -133,13 +133,13 @@ dumpglobls(void)
                        continue;
                dowidth(n->type);
 
-               ggloblnod(n);
+               arch.ggloblnod(n);
        }
        
        for(l=funcsyms; l; l=l->next) {
                n = l->n;
-               dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
-               ggloblsym(n->sym, widthptr, DUPOK|RODATA);
+               arch.dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
+               arch.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 = dsymptr(sym, off, sym, widthptr+widthint);
+       off = arch.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 = dsname(sym, off, s+n, m);
+               off = arch.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
-       ggloblsym(sym, off, DUPOK|RODATA);
+       arch.ggloblsym(sym, off, DUPOK|RODATA);
 
        return sym;     
 }
@@ -283,14 +283,14 @@ slicebytes(Node *nam, char *s, int len)
                m = 8;
                if(m > len-n)
                        m = len-n;
-               off = dsname(sym, off, s+n, m);
+               off = arch.dsname(sym, off, s+n, m);
        }
-       ggloblsym(sym, off, NOPTR);
+       arch.ggloblsym(sym, off, NOPTR);
        
        if(nam->op != ONAME)
                fatal("slicebytes %N", nam);
        off = nam->xoffset;
-       off = dsymptr(nam->sym, off, sym, 0);
+       off = arch.dsymptr(nam->sym, off, sym, 0);
        off = duintxx(nam->sym, off, len, widthint);
        duintxx(nam->sym, off, len, widthint);
 }
index 259cec85a31531b6bafb04b1348466113b0bb67f..9e38da670978141a5547d054f05604a3d454ff85 100644 (file)
@@ -9,9 +9,10 @@
 #include       <u.h>
 #include       <libc.h>
 #include       "md5.h"
-#include       "gg.h"
-#include       "opt.h"
+#include       "go.h"
+//#include     "opt.h"
 #include       "../../runtime/funcdata.h"
+#include       "../ld/textflag.h"
 
 static void allocauto(Prog* p);
 static void emitptrargsmap(void);
@@ -29,7 +30,7 @@ makefuncdatasym(char *namefmt, int64 funcdatakind)
        pnod = newname(sym);
        pnod->class = PEXTERN;
        nodconst(&nod, types[TINT32], funcdatakind);
-       gins(AFUNCDATA, &nod, pnod);
+       arch.gins(arch.AFUNCDATA, &nod, pnod);
        return sym;
 }
 
@@ -38,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 isfat(n->type).
+// or 'fat' variables, those satisfying arch.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()
@@ -102,20 +103,20 @@ gvardefx(Node *n, int as)
        case PAUTO:
        case PPARAM:
        case PPARAMOUT:
-               gins(as, N, n);
+               arch.gins(as, N, n);
        }
 }
 
 void
 gvardef(Node *n)
 {
-       gvardefx(n, AVARDEF);
+       gvardefx(n, arch.AVARDEF);
 }
 
 void
 gvarkill(Node *n)
 {
-       gvardefx(n, AVARKILL);
+       gvardefx(n, arch.AVARKILL);
 }
 
 static void
@@ -124,10 +125,10 @@ removevardef(Prog *firstp)
        Prog *p;
 
        for(p = firstp; p != P; p = p->link) {
-               while(p->link != P && (p->link->as == AVARDEF || p->link->as == AVARKILL))
+               while(p->link != P && (p->link->as == arch.AVARDEF || p->link->as == arch.AVARKILL))
                        p->link = p->link->link;
-               if(p->to.type == D_BRANCH)
-                       while(p->to.u.branch != P && (p->to.u.branch->as == AVARDEF || p->to.u.branch->as == AVARKILL))
+               if(p->to.type == arch.D_BRANCH)
+                       while(p->to.u.branch != P && (p->to.u.branch->as == arch.AVARDEF || p->to.u.branch->as == arch.AVARKILL))
                                p->to.u.branch = p->to.u.branch->link;
        }
 }
@@ -222,39 +223,39 @@ compile(Node *fn)
        continpc = P;
        breakpc = P;
 
-       pl = newplist();
+       pl = arch.newplist();
        pl->name = linksym(curfn->nname->sym);
 
        setlineno(curfn);
 
        nodconst(&nod1, types[TINT32], 0);
-       ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
+       ptxt = arch.gins(arch.ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1);
        if(fn->dupok)
-               ptxt->TEXTFLAG |= DUPOK;
+               arch.thelinkarch->settextflag(ptxt, arch.thelinkarch->textflag(ptxt) | DUPOK);
        if(fn->wrapper)
-               ptxt->TEXTFLAG |= WRAPPER;
+               arch.thelinkarch->settextflag(ptxt, arch.thelinkarch->textflag(ptxt) | WRAPPER);
        if(fn->needctxt)
-               ptxt->TEXTFLAG |= NEEDCTXT;
+               arch.thelinkarch->settextflag(ptxt, arch.thelinkarch->textflag(ptxt) | NEEDCTXT);
        if(fn->nosplit)
-               ptxt->TEXTFLAG |= NOSPLIT;
+               arch.thelinkarch->settextflag(ptxt, arch.thelinkarch->textflag(ptxt) | NOSPLIT);
 
        // Clumsy but important.
        // See test/recover.go for test cases and src/reflect/value.go
        // for the actual functions being considered.
        if(myimportpath != nil && strcmp(myimportpath, "reflect") == 0) {
                if(strcmp(curfn->nname->sym->name, "callReflect") == 0 || strcmp(curfn->nname->sym->name, "callMethod") == 0)
-                       ptxt->TEXTFLAG |= WRAPPER;
+                       arch.thelinkarch->settextflag(ptxt, arch.thelinkarch->textflag(ptxt) | WRAPPER);
        }       
        
-       afunclit(&ptxt->from, curfn->nname);
+       arch.afunclit(&ptxt->from, curfn->nname);
 
-       ginit();
+       arch.ginit();
 
        gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
        gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
 
        for(t=curfn->paramfld; t; t=t->down)
-               gtrack(tracksym(t->type));
+               arch.gtrack(tracksym(t->type));
 
        for(l=fn->dcl; l; l=l->next) {
                n = l->n;
@@ -265,7 +266,7 @@ compile(Node *fn)
                case PPARAM:
                case PPARAMOUT:
                        nodconst(&nod1, types[TUINTPTR], l->n->type->width);
-                       p = gins(ATYPE, l->n, &nod1);
+                       p = arch.gins(arch.ATYPE, l->n, &nod1);
                        p->from.gotype = linksym(ngotype(l->n));
                        break;
                }
@@ -273,7 +274,7 @@ compile(Node *fn)
 
        genlist(curfn->enter);
        genlist(curfn->nbody);
-       gclean();
+       arch.gclean();
        checklabels();
        if(nerrors != 0)
                goto ret;
@@ -281,30 +282,30 @@ compile(Node *fn)
                lineno = curfn->endlineno;
 
        if(curfn->type->outtuple != 0)
-               ginscall(throwreturn, 0);
+               arch.ginscall(throwreturn, 0);
 
-       ginit();
+       arch.ginit();
        // TODO: Determine when the final cgen_ret can be omitted. Perhaps always?
-       cgen_ret(nil);
+       arch.cgen_ret(nil);
        if(hasdefer) {
                // deferreturn pretends to have one uintptr argument.
                // Reserve space for it so stack scanner is happy.
                if(maxarg < widthptr)
                        maxarg = widthptr;
        }
-       gclean();
+       arch.gclean();
        if(nerrors != 0)
                goto ret;
 
-       pc->as = ARET;  // overwrite AEND
+       pc->as = arch.ARET;     // overwrite AEND
        pc->lineno = lineno;
 
        fixjmp(ptxt);
        if(!debug['N'] || debug['R'] || debug['P']) {
-               regopt(ptxt);
+               arch.regopt(ptxt);
                nilopt(ptxt);
        }
-       expandchecks(ptxt);
+       arch.expandchecks(ptxt);
 
        oldstksize = stksize;
        allocauto(ptxt);
@@ -324,7 +325,7 @@ compile(Node *fn)
        gcsymdup(gcargs);
        gcsymdup(gclocals);
 
-       defframe(ptxt);
+       arch.defframe(ptxt);
 
        if(0)
                frame(0);
@@ -368,7 +369,7 @@ emitptrargsmap(void)
                for(j = 0; j < bv->n; j += 32)
                        off = duint32(sym, off, bv->b[j/32]);
        }
-       ggloblsym(sym, off, RODATA);
+       arch.ggloblsym(sym, off, RODATA);
        free(bv);
 }
 
@@ -434,7 +435,7 @@ allocauto(Prog* ptxt)
                if (ll->n->class == PAUTO)
                        ll->n->used = 0;
 
-       markautoused(ptxt);
+       arch.markautoused(ptxt);
 
        listsort(&curfn->dcl, cmpstackvar);
 
@@ -444,7 +445,7 @@ allocauto(Prog* ptxt)
        if (n->class == PAUTO && n->op == ONAME && !n->used) {
                // No locals used at all
                curfn->dcl = nil;
-               fixautoused(ptxt);
+               arch.fixautoused(ptxt);
                return;
        }
 
@@ -465,13 +466,13 @@ allocauto(Prog* ptxt)
 
                dowidth(n->type);
                w = n->type->width;
-               if(w >= MAXWIDTH || w < 0)
+               if(w >= arch.MAXWIDTH || w < 0)
                        fatal("bad width");
                stksize += w;
                stksize = rnd(stksize, n->type->align);
                if(haspointers(n->type))
                        stkptrsize = stksize;
-               if(thechar == '5' || thechar == '9')
+               if(arch.thechar == '5' || arch.thechar == '9')
                        stksize = rnd(stksize, widthptr);
                if(stksize >= (1ULL<<31)) {
                        setlineno(curfn);
@@ -482,7 +483,7 @@ allocauto(Prog* ptxt)
        stksize = rnd(stksize, widthreg);
        stkptrsize = rnd(stkptrsize, widthreg);
 
-       fixautoused(ptxt);
+       arch.fixautoused(ptxt);
 
        // The debug information needs accurate offsets on the symbols.
        for(ll = curfn->dcl; ll != nil; ll=ll->next) {
@@ -528,12 +529,12 @@ cgen_checknil(Node *n)
                dump("checknil", n);
                fatal("bad checknil");
        }
-       if(((thechar == '5' || thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
-               regalloc(&reg, types[tptr], n);
-               cgen(n, &reg);
-               gins(ACHECKNIL, &reg, N);
-               regfree(&reg);
+       if(((arch.thechar == '5' || arch.thechar == '9') && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
+               arch.regalloc(&reg, types[tptr], n);
+               arch.cgen(n, &reg);
+               arch.gins(arch.ACHECKNIL, &reg, N);
+               arch.regfree(&reg);
                return;
        }
-       gins(ACHECKNIL, n, N);
+       arch.gins(arch.ACHECKNIL, n, N);
 }
index 480f398711d1d6009b4dc63e5bdddc7ed7d37720..3c8f66245fa3a36bace5d0bebae0dd3fb193a840 100644 (file)
@@ -15,8 +15,7 @@
 
 #include <u.h>
 #include <libc.h>
-#include "gg.h"
-#include "opt.h"
+#include "go.h"
 #include "../ld/textflag.h"
 #include "../../runtime/funcdata.h"
 #include "../../runtime/mgc0.h"
@@ -372,7 +371,7 @@ iscall(Prog *prog, LSym *name)
                fatal("iscall: prog is nil");
        if(name == nil)
                fatal("iscall: function name is nil");
-       if(prog->as != ACALL)
+       if(prog->as != arch.ACALL)
                return 0;
        return name == prog->to.sym;
 }
@@ -513,14 +512,14 @@ newcfg(Prog *firstp)
        bb = newblock(firstp);
        arrayadd(cfg, &bb);
        for(p = firstp; p != P; p = p->link) {
-               if(p->to.type == D_BRANCH) {
+               if(p->to.type == arch.D_BRANCH) {
                        if(p->to.u.branch == nil)
                                fatal("prog branch to nil");
                        if(p->to.u.branch->opt == nil) {
                                p->to.u.branch->opt = newblock(p->to.u.branch);
                                arrayadd(cfg, &p->to.u.branch->opt);
                        }
-                       if(p->as != AJMP && p->link != nil && p->link->opt == nil) {
+                       if(p->as != arch.AJMP && p->link != nil && p->link->opt == nil) {
                                p->link->opt = newblock(p->link);
                                arrayadd(cfg, &p->link->opt);
                        }
@@ -545,26 +544,20 @@ newcfg(Prog *firstp)
 
                        // Stop before an unreachable RET, to avoid creating
                        // unreachable control flow nodes.
-                       if(p->link != nil && p->link->as == ARET && p->link->mode == 1)
+                       if(p->link != nil && p->link->as == arch.ARET && p->link->mode == 1)
                                break;
 
                        // Collect basic blocks with selectgo calls.
                        if(isselectgocall(p))
                                arrayadd(selectgo, &bb);
                }
-               if(bb->last->to.type == D_BRANCH)
+               if(bb->last->to.type == arch.D_BRANCH)
                        addedge(bb, bb->last->to.u.branch->opt);
                if(bb->last->link != nil) {
                        // Add a fall-through when the instruction is
                        // not an unconditional control transfer.
-                       switch(bb->last->as) {
-                       case AJMP:
-                       case ARET:
-                       case AUNDEF:
-                               break;
-                       default:
+                       if(bb->last->as != arch.AJMP && bb->last->as != arch.ARET && bb->last->as != arch.AUNDEF)
                                addedge(bb, bb->last->link->opt);
-                       }
                }
        }
 
@@ -684,8 +677,8 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
        bvresetall(varkill);
        bvresetall(avarinit);
 
-       proginfo(&info, prog);
-       if(prog->as == ARET) {
+       arch.proginfo(&info, prog);
+       if(prog->as == arch.ARET) {
                // Return instructions implicitly read all the arguments.  For
                // the sake of correctness, out arguments must be read.  For the
                // sake of backtrace quality, we read in arguments as well.
@@ -708,17 +701,17 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
                                // If we added it to uevar too, we'd not see any kill
                                // and decide that the varible was live entry, which it is not.
                                // So only use uevar in the non-addrtaken case.
-                               // The p->to.type == D_NONE limits the bvset to
+                               // The p->to.type == arch.D_NONE limits the bvset to
                                // non-tail-call return instructions; see note above
                                // the for loop for details.
-                               if(!node->addrtaken && prog->to.type == D_NONE)
+                               if(!node->addrtaken && prog->to.type == arch.D_NONE)
                                        bvset(uevar, i);
                                break;
                        }
                }
                return;
        }
-       if(prog->as == ATEXT) {
+       if(prog->as == arch.ATEXT) {
                // A text instruction marks the entry point to a function and
                // the definition point of all in arguments.
                for(i = 0; i < arraylength(vars); i++) {
@@ -751,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 && !isfat(((Node*)(from->node))->type))
+                                               if(from->node != nil && !arch.isfat(((Node*)(from->node))->type))
                                                        bvset(varkill, pos);
                                }
                        }
@@ -771,9 +764,9 @@ Next:
                                if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node)
                                        fatal("bad bookkeeping in liveness %N %d", to->node, pos);
                                if(((Node*)(to->node))->addrtaken) {
-                                       if(prog->as != AVARKILL)
+                                       if(prog->as != arch.AVARKILL)
                                                bvset(avarinit, pos);
-                                       if(prog->as == AVARDEF || prog->as == AVARKILL)
+                                       if(prog->as == arch.AVARDEF || prog->as == arch.AVARKILL)
                                                bvset(varkill, pos);
                                } else {
                                        // RightRead is a read, obviously.
@@ -787,7 +780,7 @@ Next:
                                        if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
                                                bvset(uevar, pos);
                                        if(info.flags & RightWrite)
-                                               if(to->node != nil && (!isfat(((Node*)(to->node))->type) || prog->as == AVARDEF))
+                                               if(to->node != nil && (!arch.isfat(((Node*)(to->node))->type) || prog->as == arch.AVARDEF))
                                                        bvset(varkill, pos);
                                }
                        }
@@ -959,7 +952,7 @@ livenessprintblock(Liveness *lv, BasicBlock *bb)
        print("\tprog:\n");
        for(prog = bb->first;; prog = prog->link) {
                print("\t\t%P", prog);
-               if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
+               if(prog->as == arch.APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
                        pos = prog->to.offset;
                        live = *(Bvec**)arrayget(lv->livepointers, pos);
                        print(" ");
@@ -1025,13 +1018,13 @@ checkparam(Node *fn, Prog *p, Node *n)
 static void
 checkprog(Node *fn, Prog *p)
 {
-       if(p->from.type == D_AUTO)
+       if(p->from.type == arch.D_AUTO)
                checkauto(fn, p, p->from.node);
-       if(p->from.type == D_PARAM)
+       if(p->from.type == arch.D_PARAM)
                checkparam(fn, p, p->from.node);
-       if(p->to.type == D_AUTO)
+       if(p->to.type == arch.D_AUTO)
                checkauto(fn, p, p->to.node);
-       if(p->to.type == D_PARAM)
+       if(p->to.type == arch.D_PARAM)
                checkparam(fn, p, p->to.node);
 }
 
@@ -1051,15 +1044,8 @@ checkptxt(Node *fn, Prog *firstp)
        for(p = firstp; p != P; p = p->link) {
                if(0)
                        print("analyzing '%P'\n", p);
-               switch(p->as) {
-               case ADATA:
-               case AGLOBL:
-               case ANAME:
-               case ASIGNAME:
-               case ATYPE:
-                       continue;
-               }
-               checkprog(fn, p);
+               if(p->as != arch.ADATA && p->as != arch.AGLOBL && p->as != arch.ANAME && p->as != arch.ASIGNAME && p->as != arch.ATYPE)
+                       checkprog(fn, p);
        }
 }
 
@@ -1228,7 +1214,7 @@ unlinkedprog(int as)
        Prog *p;
 
        p = mal(sizeof(*p));
-       clearp(p);
+       arch.clearp(p);
        p->as = as;
        return p;
 }
@@ -1243,10 +1229,10 @@ newpcdataprog(Prog *prog, int32 index)
 
        nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
        nodconst(&to, types[TINT32], index);
-       pcdata = unlinkedprog(APCDATA);
+       pcdata = unlinkedprog(arch.APCDATA);
        pcdata->lineno = prog->lineno;
-       naddr(&from, &pcdata->from, 0);
-       naddr(&to, &pcdata->to, 0);
+       arch.naddr(&from, &pcdata->from, 0);
+       arch.naddr(&to, &pcdata->to, 0);
        return pcdata;
 }
 
@@ -1255,7 +1241,7 @@ newpcdataprog(Prog *prog, int32 index)
 static int
 issafepoint(Prog *prog)
 {
-       return prog->as == ATEXT || prog->as == ACALL;
+       return prog->as == arch.ATEXT || prog->as == arch.ACALL;
 }
 
 // Initializes the sets for solving the live variables.  Visits all the
@@ -1552,7 +1538,7 @@ livenessepilogue(Liveness *lv)
                // walk backward, emit pcdata and populate the maps
                pos = bb->lastbitmapindex;
                if(pos < 0) {
-                       // the first block we encounter should have the ATEXT so
+                       // the first block we encounter should have the arch.ATEXT so
                        // at no point should pos ever be less than zero.
                        fatal("livenessepilogue");
                }
@@ -1579,7 +1565,7 @@ livenessepilogue(Liveness *lv)
                                // Useful sanity check: on entry to the function,
                                // the only things that can possibly be live are the
                                // input parameters.
-                               if(p->as == ATEXT) {
+                               if(p->as == arch.ATEXT) {
                                        for(j = 0; j < liveout->n; j++) {
                                                if(!bvget(liveout, j))
                                                        continue;
@@ -1597,7 +1583,7 @@ livenessepilogue(Liveness *lv)
                                // Ambiguously live variables are zeroed immediately after
                                // function entry. Mark them live for all the non-entry bitmaps
                                // so that GODEBUG=gcdead=1 mode does not poison them.
-                               if(p->as == ACALL)
+                               if(p->as == arch.ACALL)
                                        bvor(locals, locals, ambig);
 
                                // Show live pointer bitmaps.
@@ -1607,9 +1593,9 @@ livenessepilogue(Liveness *lv)
                                if(msg != nil) {
                                        fmtstrinit(&fmt);
                                        fmtprint(&fmt, "%L: live at ", p->lineno);
-                                       if(p->as == ACALL && p->to.node)
+                                       if(p->as == arch.ACALL && p->to.node)
                                                fmtprint(&fmt, "call to %s:", ((Node*)(p->to.node))->sym->name);
-                                       else if(p->as == ACALL)
+                                       else if(p->as == arch.ACALL)
                                                fmtprint(&fmt, "indirect call:");
                                        else
                                                fmtprint(&fmt, "entry to %s:", ((Node*)(p->from.node))->sym->name);
@@ -1630,7 +1616,7 @@ livenessepilogue(Liveness *lv)
 
                                // Only CALL instructions need a PCDATA annotation.
                                // The TEXT instruction annotation is implicit.
-                               if(p->as == ACALL) {
+                               if(p->as == arch.ACALL) {
                                        if(isdeferreturn(p)) {
                                                // runtime.deferreturn modifies its return address to return
                                                // back to the CALL, not to the subsequent instruction.
@@ -1773,7 +1759,7 @@ livenesscompact(Liveness *lv)
        
        // Rewrite PCDATA instructions to use new numbering.
        for(p=lv->ptxt; p != P; p=p->link) {
-               if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) {
+               if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex) {
                        i = p->to.offset;
                        if(i >= 0)
                                p->to.offset = remap[i];
@@ -1860,7 +1846,7 @@ livenessprintdebug(Liveness *lv)
                // program listing, with individual effects listed
                for(p = bb->first;; p = p->link) {
                        print("%P\n", p);
-                       if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex)
+                       if(p->as == arch.APCDATA && p->from.offset == PCDATA_StackMapIndex)
                                pcdata = p->to.offset;
                        progeffects(p, lv->vars, uevar, varkill, avarinit);
                        printed = 0;
@@ -1937,7 +1923,7 @@ twobitwritesymbol(Array *arr, Sym *sym)
                }
        }
        duint32(sym, 0, i); // number of bitmaps
-       ggloblsym(sym, off, RODATA);
+       arch.ggloblsym(sym, off, RODATA);
 }
 
 static void
index 6d12d205267727cb37c86651b530be25178b243e..ee771aba6a8e2c7c8d0e76a254a0081cd9652326 100644 (file)
@@ -34,8 +34,7 @@
 
 #include       <u.h>
 #include       <libc.h>
-#include       "gg.h"
-#include       "opt.h"
+#include       "go.h"
 
 // p is a call instruction. Does the call fail to return?
 int
@@ -82,7 +81,7 @@ chasejmp(Prog *p, int *jmploop)
        int n;
 
        n = 0;
-       while(p != P && p->as == AJMP && p->to.type == D_BRANCH) {
+       while(p != P && p->as == arch.AJMP && p->to.type == arch.D_BRANCH) {
                if(++n > 10) {
                        *jmploop = 1;
                        break;
@@ -113,9 +112,9 @@ mark(Prog *firstp)
                if(p->opt != dead)
                        break;
                p->opt = alive;
-               if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch)
+               if(p->as != arch.ACALL && p->to.type == arch.D_BRANCH && p->to.u.branch)
                        mark(p->to.u.branch);
-               if(p->as == AJMP || p->as == ARET || p->as == AUNDEF)
+               if(p->as == arch.AJMP || p->as == arch.ARET || p->as == arch.AUNDEF)
                        break;
        }
 }
@@ -134,7 +133,7 @@ fixjmp(Prog *firstp)
        for(p=firstp; p; p=p->link) {
                if(debug['R'] && debug['v'])
                        print("%P\n", p);
-               if(p->as != ACALL && p->to.type == D_BRANCH && p->to.u.branch && p->to.u.branch->as == AJMP) {
+               if(p->as != arch.ACALL && p->to.type == arch.D_BRANCH && p->to.u.branch && p->to.u.branch->as == arch.AJMP) {
                        p->to.u.branch = chasejmp(p->to.u.branch, &jmploop);
                        if(debug['R'] && debug['v'])
                                print("->%P\n", p);
@@ -151,8 +150,8 @@ fixjmp(Prog *firstp)
        last = nil;
        for(p=firstp; p; p=p->link) {
                if(p->opt == dead) {
-                       if(p->link == P && p->as == ARET && last && last->as != ARET) {
-                               // This is the final ARET, and the code so far doesn't have one.
+                       if(p->link == P && p->as == arch.ARET && last && last->as != arch.ARET) {
+                               // This is the final arch.ARET, and the code so far doesn't have one.
                                // Let it stay. The register allocator assumes that all live code in
                                // the function can be traversed by starting at all the RET instructions
                                // and following predecessor links. If we remove the final RET,
@@ -177,7 +176,7 @@ fixjmp(Prog *firstp)
        if(!jmploop) {
                last = nil;
                for(p=firstp; p; p=p->link) {
-                       if(p->as == AJMP && p->to.type == D_BRANCH && p->to.u.branch == p->link) {
+                       if(p->as == arch.AJMP && p->to.type == arch.D_BRANCH && p->to.u.branch == p->link) {
                                if(debug['R'] && debug['v'])
                                        print("del %P\n", p);
                                continue;
@@ -233,7 +232,7 @@ flowstart(Prog *firstp, int size)
        nf = 0;
        for(p = firstp; p != P; p = p->link) {
                p->opt = nil; // should be already, but just in case
-               proginfo(&info, p);
+               arch.proginfo(&info, p);
                if(info.flags & Skip)
                        continue;
                p->opt = (void*)1;
@@ -270,13 +269,13 @@ flowstart(Prog *firstp, int size)
        // Fill in pred/succ information.
        for(f = start; f != nil; f = f->link) {
                p = f->prog;
-               proginfo(&info, p);
+               arch.proginfo(&info, p);
                if(!(info.flags & Break)) {
                        f1 = f->link;
                        f->s1 = f1;
                        f1->p1 = f;
                }
-               if(p->to.type == D_BRANCH) {
+               if(p->to.type == arch.D_BRANCH) {
                        if(p->to.u.branch == P)
                                fatal("pnil %P", p);
                        f1 = p->to.u.branch->opt;
@@ -384,6 +383,10 @@ loophead(int32 *idom, Flow *r)
        return 0;
 }
 
+enum {
+       LOOP = 3,
+};
+
 static void
 loopmark(Flow **rpo2r, int32 head, Flow *r)
 {
@@ -584,7 +587,7 @@ mergetemp(Prog *firstp)
        // single-use (that's why we have so many!).
        for(r = (TempFlow*)g->start; r != nil; r = (TempFlow*)r->f.link) {
                p = r->f.prog;
-               proginfo(&info, p);
+               arch.proginfo(&info, p);
 
                if(p->from.node != N && ((Node*)(p->from.node))->opt && p->to.node != N && ((Node*)(p->to.node))->opt)
                        fatal("double node %P", p);
@@ -604,7 +607,7 @@ mergetemp(Prog *firstp)
        }
        
        if(Debug > 1)
-               dumpit("before", g->start, 0);
+               arch.dumpit("before", g->start, 0);
        
        nkill = 0;
 
@@ -615,10 +618,10 @@ mergetemp(Prog *firstp)
                // Used in only one instruction, which had better be a write.
                if((r = v->use) != nil && r->uselink == nil) {
                        p = r->f.prog;
-                       proginfo(&info, p);
+                       arch.proginfo(&info, p);
                        if(p->to.node == v->node && (info.flags & RightWrite) && !(info.flags & RightRead)) {
-                               p->as = ANOP;
-                               p->to = zprog.to;
+                               p->as = arch.ANOP;
+                               p->to = arch.zprog.to;
                                v->removed = 1;
                                if(Debug)
                                        print("drop write-only %S\n", v->node->sym);
@@ -632,9 +635,9 @@ mergetemp(Prog *firstp)
                // no jumps to the next instruction. Happens mainly in 386 compiler.
                if((r = v->use) != nil && r->f.link == &r->uselink->f && r->uselink->uselink == nil && uniqp(r->f.link) == &r->f) {
                        p = r->f.prog;
-                       proginfo(&info, p);
+                       arch.proginfo(&info, p);
                        p1 = r->f.link->prog;
-                       proginfo(&info1, p1);
+                       arch.proginfo(&info1, p1);
                        enum {
                                SizeAny = SizeB | SizeW | SizeL | SizeQ | SizeF | SizeD,
                        };
@@ -642,7 +645,7 @@ mergetemp(Prog *firstp)
                           !((info.flags|info1.flags) & (LeftAddr|RightAddr)) &&
                           (info.flags & SizeAny) == (info1.flags & SizeAny)) {
                                p1->from = p->from;
-                               excise(&r->f);
+                               arch.excise(&r->f);
                                v->removed = 1;
                                if(Debug)
                                        print("drop immediate-use %S\n", v->node->sym);
@@ -738,7 +741,7 @@ mergetemp(Prog *firstp)
                }
        
                if(Debug > 1)
-                       dumpit("after", g->start, 0);
+                       arch.dumpit("after", g->start, 0);
        }
 
        // Update node references to use merged temporaries.
@@ -810,7 +813,7 @@ varkillwalk(TempVar *v, TempFlow *r0, uint32 gen)
                        v->end = p->pc;
                if(v->start > p->pc)
                        v->start = p->pc;
-               if(p->as == ARET || (p->as == AVARKILL && p->to.node == v->node))
+               if(p->as == arch.ARET || (p->as == arch.AVARKILL && p->to.node == v->node))
                        break;
        }
        
@@ -856,16 +859,16 @@ nilopt(Prog *firstp)
                return;
 
        if(debug_checknil > 1 /* || strcmp(curfn->nname->sym->name, "f1") == 0 */)
-               dumpit("nilopt", g->start, 0);
+               arch.dumpit("nilopt", g->start, 0);
 
        ncheck = 0;
        nkill = 0;
        for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
                p = r->f.prog;
-               if(p->as != ACHECKNIL || !regtyp(&p->from))
+               if(p->as != arch.ACHECKNIL || !arch.regtyp(&p->from))
                        continue;
                ncheck++;
-               if(stackaddr(&p->from)) {
+               if(arch.stackaddr(&p->from)) {
                        if(debug_checknil && p->lineno > 1)
                                warnl(p->lineno, "removed nil check of SP address");
                        r->kill = 1;
@@ -888,7 +891,7 @@ nilopt(Prog *firstp)
        for(r = (NilFlow*)g->start; r != nil; r = (NilFlow*)r->f.link) {
                if(r->kill) {
                        nkill++;
-                       excise(&r->f);
+                       arch.excise(&r->f);
                }
        }
 
@@ -907,13 +910,13 @@ nilwalkback(NilFlow *rcheck)
        
        for(r = rcheck; r != nil; r = (NilFlow*)uniqp(&r->f)) {
                p = r->f.prog;
-               proginfo(&info, p);
-               if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
+               arch.proginfo(&info, p);
+               if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from)) {
                        // Found initialization of value we're checking for nil.
                        // without first finding the check, so this one is unchecked.
                        return;
                }
-               if(r != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from)) {
+               if(r != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from)) {
                        rcheck->kill = 1;
                        return;
                }
@@ -934,11 +937,11 @@ nilwalkback(NilFlow *rcheck)
                
                // If same check, stop this loop but still check
                // alternate predecessors up to this point.
-               if(r1 != rcheck && p->as == ACHECKNIL && sameaddr(&p->from, &rcheck->f.prog->from))
+               if(r1 != rcheck && p->as == arch.ACHECKNIL && arch.sameaddr(&p->from, &rcheck->f.prog->from))
                        break;
 
-               proginfo(&info, p);
-               if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from)) {
+               arch.proginfo(&info, p);
+               if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from)) {
                        // Found initialization of value we're checking for nil.
                        // without first finding the check, so this one is unchecked.
                        rcheck->kill = 0;
@@ -948,8 +951,8 @@ nilwalkback(NilFlow *rcheck)
                if(r1->f.p1 == nil && r1->f.p2 == nil) {
                        print("lost pred for %P\n", rcheck->f.prog);
                        for(r1=r0; r1!=nil; r1=(NilFlow*)r1->f.p1) {
-                               proginfo(&info, r1->f.prog);
-                               print("\t%P %d %d %D %D\n", r1->f.prog, info.flags&RightWrite, sameaddr(&r1->f.prog->to, &rcheck->f.prog->from), &r1->f.prog->to, &rcheck->f.prog->from);
+                               arch.proginfo(&info, r1->f.prog);
+                               print("\t%P %d %d %D %D\n", r1->f.prog, info.flags&RightWrite, arch.sameaddr(&r1->f.prog->to, &rcheck->f.prog->from), &r1->f.prog->to, &rcheck->f.prog->from);
                        }
                        fatal("lost pred trail");
                }
@@ -978,25 +981,25 @@ nilwalkfwd(NilFlow *rcheck)
        last = nil;
        for(r = (NilFlow*)uniqs(&rcheck->f); r != nil; r = (NilFlow*)uniqs(&r->f)) {
                p = r->f.prog;
-               proginfo(&info, p);
+               arch.proginfo(&info, p);
                
-               if((info.flags & LeftRead) && smallindir(&p->from, &rcheck->f.prog->from)) {
+               if((info.flags & LeftRead) && arch.smallindir(&p->from, &rcheck->f.prog->from)) {
                        rcheck->kill = 1;
                        return;
                }
-               if((info.flags & (RightRead|RightWrite)) && smallindir(&p->to, &rcheck->f.prog->from)) {
+               if((info.flags & (RightRead|RightWrite)) && arch.smallindir(&p->to, &rcheck->f.prog->from)) {
                        rcheck->kill = 1;
                        return;
                }
                
                // Stop if another nil check happens.
-               if(p->as == ACHECKNIL)
+               if(p->as == arch.ACHECKNIL)
                        return;
                // Stop if value is lost.
-               if((info.flags & RightWrite) && sameaddr(&p->to, &rcheck->f.prog->from))
+               if((info.flags & RightWrite) && arch.sameaddr(&p->to, &rcheck->f.prog->from))
                        return;
                // Stop if memory write.
-               if((info.flags & RightWrite) && !regtyp(&p->to))
+               if((info.flags & RightWrite) && !arch.regtyp(&p->to))
                        return;
                // Stop if we jump backward.
                // This test is valid because all the NilFlow* are pointers into
diff --git a/src/cmd/gc/popt.h b/src/cmd/gc/popt.h
deleted file mode 100644 (file)
index 8d5dfff..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-typedef struct Flow Flow;
-typedef struct Graph Graph;
-
-struct Flow {
-       Prog*   prog;           // actual instruction
-       Flow*   p1;             // predecessors of this instruction: p1,
-       Flow*   p2;             // and then p2 linked though p2link.
-       Flow*   p2link;
-       Flow*   s1;             // successors of this instruction (at most two: s1 and s2).
-       Flow*   s2;
-       Flow*   link;           // next instruction in function code
-       
-       int32   active; // usable by client
-
-       int32   rpo;            // reverse post ordering
-       uint16  loop;           // x5 for every loop
-       uchar   refset;         // diagnostic generated
-};
-
-struct Graph
-{
-       Flow*   start;
-       int     num;
-       
-       // After calling flowrpo, rpo lists the flow nodes in reverse postorder,
-       // and each non-dead Flow node f has g->rpo[f->rpo] == f.
-       Flow**  rpo;
-};
-
-void   fixjmp(Prog*);
-Graph* flowstart(Prog*, int);
-void   flowrpo(Graph*);
-void   flowend(Graph*);
-void   mergetemp(Prog*);
-void   nilopt(Prog*);
-int    noreturn(Prog*);
-int    regtyp(Addr*);
-int    sameaddr(Addr*, Addr*);
-int    smallindir(Addr*, Addr*);
-int    stackaddr(Addr*);
-Flow*  uniqp(Flow*);
-Flow*  uniqs(Flow*);
index fde473ac49c1413f88932f45bee073cfbe131599..bc6c530939236d8d7f03fa90cef3b2cb9a4143cd 100644 (file)
@@ -523,15 +523,15 @@ dimportpath(Pkg *p)
        n->xoffset = 0;
        p->pathsym = n->sym;
 
-       gdatastring(n, p->path);
-       ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
+       arch.gdatastring(n, p->path);
+       arch.ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
 }
 
 static int
 dgopkgpath(Sym *s, int ot, Pkg *pkg)
 {
        if(pkg == nil)
-               return dgostringptr(s, ot, nil);
+               return arch.dgostringptr(s, ot, nil);
 
        // Emit reference to go.importpath.""., which 6l will
        // rewrite using the correct import path.  Every package
@@ -541,11 +541,11 @@ dgopkgpath(Sym *s, int ot, Pkg *pkg)
 
                if(ns == nil)
                        ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
-               return dsymptr(s, ot, ns, 0);
+               return arch.dsymptr(s, ot, ns, 0);
        }
 
        dimportpath(pkg);
-       return dsymptr(s, ot, pkg->pathsym, 0);
+       return arch.dsymptr(s, ot, pkg->pathsym, 0);
 }
 
 /*
@@ -565,7 +565,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
 
        // fill in *extraType pointer in header
        off = rnd(off, widthptr);
-       dsymptr(sym, ptroff, sym, off);
+       arch.dsymptr(sym, ptroff, sym, off);
 
        n = 0;
        for(a=m; a; a=a->link) {
@@ -576,18 +576,18 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
        ot = off;
        s = sym;
        if(t->sym) {
-               ot = dgostringptr(s, ot, t->sym->name);
+               ot = arch.dgostringptr(s, ot, t->sym->name);
                if(t != types[t->etype] && t != errortype)
                        ot = dgopkgpath(s, ot, t->sym->pkg);
                else
-                       ot = dgostringptr(s, ot, nil);
+                       ot = arch.dgostringptr(s, ot, nil);
        } else {
-               ot = dgostringptr(s, ot, nil);
-               ot = dgostringptr(s, ot, nil);
+               ot = arch.dgostringptr(s, ot, nil);
+               ot = arch.dgostringptr(s, ot, nil);
        }
 
        // slice header
-       ot = dsymptr(s, ot, s, ot + widthptr + 2*widthint);
+       ot = arch.dsymptr(s, ot, s, ot + widthptr + 2*widthint);
        ot = duintxx(s, ot, n, widthint);
        ot = duintxx(s, ot, n, widthint);
 
@@ -595,16 +595,16 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
        for(a=m; a; a=a->link) {
                // method
                // ../../runtime/type.go:/method
-               ot = dgostringptr(s, ot, a->name);
+               ot = arch.dgostringptr(s, ot, a->name);
                ot = dgopkgpath(s, ot, a->pkg);
-               ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
-               ot = dsymptr(s, ot, dtypesym(a->type), 0);
+               ot = arch.dsymptr(s, ot, dtypesym(a->mtype), 0);
+               ot = arch.dsymptr(s, ot, dtypesym(a->type), 0);
                if(a->isym)
-                       ot = dsymptr(s, ot, a->isym, 0);
+                       ot = arch.dsymptr(s, ot, a->isym, 0);
                else
                        ot = duintptr(s, ot, 0);
                if(a->tsym)
-                       ot = dsymptr(s, ot, a->tsym, 0);
+                       ot = arch.dsymptr(s, ot, a->tsym, 0);
                else
                        ot = duintptr(s, ot, 0);
        }
@@ -792,17 +792,17 @@ dcommontype(Sym *s, int ot, Type *t)
                i |= KindGCProg;
        ot = duint8(s, ot, i);  // kind
        if(algsym == S)
-               ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
+               ot = arch.dsymptr(s, ot, algarray, alg*sizeofAlg);
        else
-               ot = dsymptr(s, ot, algsym, 0);
+               ot = arch.dsymptr(s, ot, algsym, 0);
        // gc
        if(gcprog) {
                gengcprog(t, &gcprog0, &gcprog1);
                if(gcprog0 != S)
-                       ot = dsymptr(s, ot, gcprog0, 0);
+                       ot = arch.dsymptr(s, ot, gcprog0, 0);
                else
                        ot = duintptr(s, ot, 0);
-               ot = dsymptr(s, ot, gcprog1, 0);
+               ot = arch.dsymptr(s, ot, gcprog1, 0);
        } else {
                gengcmask(t, gcmask);
                x1 = 0;
@@ -821,14 +821,14 @@ dcommontype(Sym *s, int ot, Type *t)
                        sbits->flags |= SymUniq;
                        for(i = 0; i < 2*widthptr; i++)
                                duint8(sbits, i, gcmask[i]);
-                       ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
+                       arch.ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
                }
-               ot = dsymptr(s, ot, sbits, 0);
+               ot = arch.dsymptr(s, ot, sbits, 0);
                ot = duintptr(s, ot, 0);
        }
        p = smprint("%-uT", t);
        //print("dcommontype: %s\n", p);
-       ot = dgostringptr(s, ot, p);    // string
+       ot = arch.dgostringptr(s, ot, p);       // string
        free(p);
 
        // skip pointer to extraType,
@@ -837,8 +837,8 @@ dcommontype(Sym *s, int ot, Type *t)
        // otherwise linker will assume 0.
        ot += widthptr;
 
-       ot = dsymptr(s, ot, sptr, 0);  // ptrto type
-       ot = dsymptr(s, ot, zero, 0);  // ptr to zero value
+       ot = arch.dsymptr(s, ot, sptr, 0);  // ptrto type
+       ot = arch.dsymptr(s, ot, zero, 0);  // ptr to zero value
        return ot;
 }
 
@@ -1068,15 +1068,15 @@ ok:
                        s2 = dtypesym(t2);
                        ot = dcommontype(s, ot, t);
                        xt = ot - 3*widthptr;
-                       ot = dsymptr(s, ot, s1, 0);
-                       ot = dsymptr(s, ot, s2, 0);
+                       ot = arch.dsymptr(s, ot, s1, 0);
+                       ot = arch.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 = dsymptr(s, ot, s1, 0);
+                       ot = arch.dsymptr(s, ot, s1, 0);
                }
                break;
 
@@ -1085,7 +1085,7 @@ ok:
                s1 = dtypesym(t->type);
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = dsymptr(s, ot, s1, 0);
+               ot = arch.dsymptr(s, ot, s1, 0);
                ot = duintptr(s, ot, t->chan);
                break;
 
@@ -1106,21 +1106,21 @@ ok:
 
                // two slice headers: in and out.
                ot = rnd(ot, widthptr);
-               ot = dsymptr(s, ot, s, ot+2*(widthptr+2*widthint));
+               ot = arch.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 = dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr);
+               ot = arch.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 = dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
                for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
-                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
                for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
-                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
                break;
 
        case TINTER:
@@ -1134,14 +1134,14 @@ ok:
                // ../../runtime/type.go:/InterfaceType
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+               ot = arch.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 = dgostringptr(s, ot, a->name);
+                       ot = arch.dgostringptr(s, ot, a->name);
                        ot = dgopkgpath(s, ot, a->pkg);
-                       ot = dsymptr(s, ot, dtypesym(a->type), 0);
+                       ot = arch.dsymptr(s, ot, dtypesym(a->type), 0);
                }
                break;
 
@@ -1153,10 +1153,10 @@ ok:
                s4 = dtypesym(hmap(t));
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = dsymptr(s, ot, s1, 0);
-               ot = dsymptr(s, ot, s2, 0);
-               ot = dsymptr(s, ot, s3, 0);
-               ot = dsymptr(s, ot, s4, 0);
+               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);
                if(t->down->width > MAXKEYSIZE) {
                        ot = duint8(s, ot, widthptr);
                        ot = duint8(s, ot, 1); // indirect
@@ -1186,7 +1186,7 @@ ok:
                s1 = dtypesym(t->type);
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = dsymptr(s, ot, s1, 0);
+               ot = arch.dsymptr(s, ot, s1, 0);
                break;
 
        case TSTRUCT:
@@ -1199,32 +1199,32 @@ ok:
                }
                ot = dcommontype(s, ot, t);
                xt = ot - 3*widthptr;
-               ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
+               ot = arch.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 = dgostringptr(s, ot, t1->sym->name);
+                               ot = arch.dgostringptr(s, ot, t1->sym->name);
                                if(exportname(t1->sym->name))
-                                       ot = dgostringptr(s, ot, nil);
+                                       ot = arch.dgostringptr(s, ot, nil);
                                else
                                        ot = dgopkgpath(s, ot, t1->sym->pkg);
                        } else {
-                               ot = dgostringptr(s, ot, nil);
+                               ot = arch.dgostringptr(s, ot, nil);
                                if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg)
                                        ot = dgopkgpath(s, ot, localpkg);
                                else
-                                       ot = dgostringptr(s, ot, nil);
+                                       ot = arch.dgostringptr(s, ot, nil);
                        }
-                       ot = dsymptr(s, ot, dtypesym(t1->type), 0);
-                       ot = dgostrlitptr(s, ot, t1->note);
+                       ot = arch.dsymptr(s, ot, dtypesym(t1->type), 0);
+                       ot = arch.dgostrlitptr(s, ot, t1->note);
                        ot = duintptr(s, ot, t1->width);        // field offset
                }
                break;
        }
        ot = dextratype(s, ot, t, xt);
-       ggloblsym(s, ot, dupok|RODATA);
+       arch.ggloblsym(s, ot, dupok|RODATA);
 
        // generate typelink.foo pointing at s = type.foo.
        // The linker will leave a table of all the typelinks for
@@ -1237,8 +1237,8 @@ ok:
                case TCHAN:
                case TMAP:
                        slink = typelinksym(t);
-                       dsymptr(slink, 0, s, 0);
-                       ggloblsym(slink, widthptr, dupok|RODATA);
+                       arch.dsymptr(slink, 0, s, 0);
+                       arch.ggloblsym(slink, widthptr, dupok|RODATA);
                }
        }
 
@@ -1330,18 +1330,18 @@ dalgsym(Type *t)
                hashfunc = pkglookup(p, typepkg);
                free(p);
                ot = 0;
-               ot = dsymptr(hashfunc, ot, pkglookup("memhash_varlen", runtimepkg), 0);
+               ot = arch.dsymptr(hashfunc, ot, pkglookup("memhash_varlen", runtimepkg), 0);
                ot = duintxx(hashfunc, ot, t->width, widthptr); // size encoded in closure
-               ggloblsym(hashfunc, ot, DUPOK|RODATA);
+               arch.ggloblsym(hashfunc, ot, DUPOK|RODATA);
 
                // make equality closure
                p = smprint(".eqfunc%lld", t->width);
                eqfunc = pkglookup(p, typepkg);
                free(p);
                ot = 0;
-               ot = dsymptr(eqfunc, ot, pkglookup("memequal_varlen", runtimepkg), 0);
+               ot = arch.dsymptr(eqfunc, ot, pkglookup("memequal_varlen", runtimepkg), 0);
                ot = duintxx(eqfunc, ot, t->width, widthptr);
-               ggloblsym(eqfunc, ot, DUPOK|RODATA);
+               arch.ggloblsym(eqfunc, ot, DUPOK|RODATA);
        } else {
                // generate an alg table specific to this type
                s = typesymprefix(".alg", t);
@@ -1354,16 +1354,16 @@ dalgsym(Type *t)
                geneq(eq, t);
 
                // make Go funcs (closures) for calling hash and equal from Go
-               dsymptr(hashfunc, 0, hash, 0);
-               ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
-               dsymptr(eqfunc, 0, eq, 0);
-               ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
+               arch.dsymptr(hashfunc, 0, hash, 0);
+               arch.ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
+               arch.dsymptr(eqfunc, 0, eq, 0);
+               arch.ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
        }
        // ../../runtime/alg.go:/typeAlg
        ot = 0;
-       ot = dsymptr(s, ot, hashfunc, 0);
-       ot = dsymptr(s, ot, eqfunc, 0);
-       ggloblsym(s, ot, DUPOK|RODATA);
+       ot = arch.dsymptr(s, ot, hashfunc, 0);
+       ot = arch.dsymptr(s, ot, eqfunc, 0);
+       arch.ggloblsym(s, ot, DUPOK|RODATA);
        return s;
 }
 
@@ -1546,7 +1546,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);
-               ggloblsym(gc0, size, DUPOK|NOPTR);
+               arch.ggloblsym(gc0, size, DUPOK|NOPTR);
                *pgc0 = gc0;
        }
 
@@ -1556,7 +1556,7 @@ gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
        xoffset = 0;
        gengcprog1(&g, t, &xoffset);
        ot = proggenfini(&g);
-       ggloblsym(gc1, ot, DUPOK|RODATA);
+       arch.ggloblsym(gc1, ot, DUPOK|RODATA);
        *pgc1 = gc1;
 }
 
index 8c24c122d6882fc04e5153555fca440ec8d49948..3d303eda09583493b7dfb20f7c7df5bc8a29cac3 100644 (file)
@@ -302,13 +302,13 @@ staticcopy(Node *l, Node *r, NodeList **out)
        case OLITERAL:
                if(iszero(r))
                        return 1;
-               gdata(l, r, l->type->width);
+               arch.gdata(l, r, l->type->width);
                return 1;
 
        case OADDR:
                switch(r->left->op) {
                case ONAME:
-                       gdata(l, r, l->type->width);
+                       arch.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
-                       gdata(l, nod(OADDR, r->nname, N), l->type->width);
+                       arch.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;
-                       gdata(&n1, nod(OADDR, a, N), widthptr);
+                       arch.gdata(&n1, nod(OADDR, a, N), widthptr);
                        n1.xoffset = l->xoffset + Array_nel;
-                       gdata(&n1, r->right, widthint);
+                       arch.gdata(&n1, r->right, widthint);
                        n1.xoffset = l->xoffset + Array_cap;
-                       gdata(&n1, r->right, widthint);
+                       arch.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)
-                               gdata(&n1, e->expr, n1.type->width);
+                               arch.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;
-               gdata(l, r, l->type->width);
+               arch.gdata(l, r, l->type->width);
                return 1;
 
        case OADDR:
                if(stataddr(&nam, r->left)) {
                        n1 = *r;
                        n1.left = &nam;
-                       gdata(l, &n1, l->type->width);
+                       arch.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;
-                       gdata(l, nod(OADDR, a, N), l->type->width);
+                       arch.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;
-                       gdata(&n1, nod(OADDR, a, N), widthptr);
+                       arch.gdata(&n1, nod(OADDR, a, N), widthptr);
                        n1.xoffset = l->xoffset + Array_nel;
-                       gdata(&n1, r->right, widthint);
+                       arch.gdata(&n1, r->right, widthint);
                        n1.xoffset = l->xoffset + Array_cap;
-                       gdata(&n1, r->right, widthint);
+                       arch.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)
-                               gdata(&n1, e->expr, n1.type->width);
+                               arch.gdata(&n1, e->expr, n1.type->width);
                        else {
                                a = nod(OXXX, N, N);
                                *a = n1;
@@ -1223,7 +1223,7 @@ stataddr(Node *nam, Node *n)
                if(l < 0)
                        break;
                // Check for overflow.
-               if(n->type->width != 0 && MAXWIDTH/n->type->width <= l)
+               if(n->type->width != 0 && arch.MAXWIDTH/n->type->width <= l)
                        break;
                nam->xoffset += l*n->type->width;
                nam->type = n->type;
@@ -1303,16 +1303,16 @@ gen_as_init(Node *n)
        case TPTR64:
        case TFLOAT32:
        case TFLOAT64:
-               gdata(&nam, nr, nr->type->width);
+               arch.gdata(&nam, nr, nr->type->width);
                break;
 
        case TCOMPLEX64:
        case TCOMPLEX128:
-               gdatacomplex(&nam, nr->val.u.cval);
+               arch.gdatacomplex(&nam, nr->val.u.cval);
                break;
 
        case TSTRING:
-               gdatastring(&nam, nr->val.u.sval);
+               arch.gdatastring(&nam, nr->val.u.sval);
                break;
        }
 
@@ -1320,7 +1320,7 @@ yes:
        return 1;
 
 slice:
-       gused(N); // in case the data is the dest of a goto
+       arch.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;
-       gdata(&nam, nl, types[tptr]->width);
+       arch.gdata(&nam, nl, types[tptr]->width);
 
        nam.xoffset += Array_nel-Array_array;
        nodconst(&nod1, types[TINT], nr->type->bound);
-       gdata(&nam, &nod1, widthint);
+       arch.gdata(&nam, &nod1, widthint);
 
        nam.xoffset += Array_cap-Array_nel;
-       gdata(&nam, &nod1, widthint);
+       arch.gdata(&nam, &nod1, widthint);
 
        goto yes;
 
index 871f723fdab7c50f6241eaeb2a64cdc66248ae95..39d6d96bda3ea4771bfeab2b3da6ffdeaefa3823 100644 (file)
@@ -2121,10 +2121,10 @@ setmaxarg(Type *t, int32 extra)
 
        dowidth(t);
        w = t->argwid;
-       if(w >= MAXWIDTH)
+       if(w >= arch.MAXWIDTH)
                fatal("bad argwid %T", t);
        w += extra;
-       if(w >= MAXWIDTH)
+       if(w >= arch.MAXWIDTH)
                fatal("bad argwid %d + %T", extra, t);
        if(w > maxarg)
                maxarg = w;
index 1d2dcf744765a4e952b3de328ce227d518860627..3350a0dfe04b4cebe940efd28dcfee98c34dd88d 100644 (file)
@@ -921,7 +921,7 @@ walkexpr(Node **np, NodeList **init)
                                l->class = PEXTERN;
                                l->xoffset = 0;
                                sym->def = l;
-                               ggloblsym(sym, widthptr, DUPOK|NOPTR);
+                               arch.ggloblsym(sym, widthptr, DUPOK|NOPTR);
                        }
                        l = nod(OADDR, sym->def, N);
                        l->addable = 1;
@@ -989,7 +989,7 @@ walkexpr(Node **np, NodeList **init)
 
        case OCONV:
        case OCONVNOP:
-               if(thechar == '5') {
+               if(arch.thechar == '5') {
                        if(isfloat[n->left->type->etype]) {
                                if(n->type->etype == TINT64) {
                                        n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
@@ -1579,7 +1579,7 @@ ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
                        l = tmp;
                }
 
-               a = nod(OAS, l, nodarg(r, fp));
+               a = nod(OAS, l, arch.nodarg(r, fp));
                a = convas(a, init);
                ullmancalc(a);
                if(a->ullman >= UINF) {
@@ -1632,7 +1632,7 @@ mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Nod
                walkexpr(&n, init);
        }
 
-       a = nod(OAS, nodarg(l, fp), n);
+       a = nod(OAS, arch.nodarg(l, fp), n);
        nn = list(nn, convas(a, init));
        return nn;
 }
@@ -1712,7 +1712,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 = nodarg(*nl, fp);
+                       a = arch.nodarg(*nl, fp);
                        r = nod(OCONVNOP, r, N);
                        r->type = a->type;
                        nn = list1(convas(nod(OAS, a, r), init));
@@ -1749,7 +1749,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, nodarg(l, fp), r);
+                       a = nod(OAS, arch.nodarg(l, fp), r);
                        a = convas(a, init);
                        nn = list(nn, a);
                        goto ret;
@@ -1774,7 +1774,7 @@ loop:
                goto ret;
        }
 
-       a = nod(OAS, nodarg(l, fp), r);
+       a = nod(OAS, arch.nodarg(l, fp), r);
        a = convas(a, init);
        nn = list(nn, a);
 
@@ -2527,7 +2527,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, nodarg(t, 1), N));
+                       nn = list(nn, nod(OAS, arch.nodarg(t, 1), N));
                }
                if(v == N || !(v->class & PHEAP))
                        continue;
@@ -3398,7 +3398,7 @@ walkrotate(Node **np)
        Node *l, *r;
        Node *n;
 
-       if(thechar == '9')
+       if(arch.thechar == '9')
                return;
        
        n = *np;
@@ -3526,7 +3526,7 @@ walkdiv(Node **np, NodeList **init)
        Magic m;
 
        // TODO(minux)
-       if(thechar == '9')
+       if(arch.thechar == '9')
                return;
 
        n = *np;