]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove gins
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 15 Sep 2016 15:07:54 +0000 (08:07 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 15 Sep 2016 16:26:44 +0000 (16:26 +0000)
The only remaining consumers of gins were
ginsnop and arch-independent opcodes like GVARDEF.
Rewrite ginsnop to create and populate progs directly.
Move arch-independent opcodes to package gc
and simplify.
Delete some now unused code.
There is more.
Step one towards eliminating gc.Node.Reg.

Change-Id: I7c34cd8a848f6fc3b030705ab8e293838e0b6c20
Reviewed-on: https://go-review.googlesource.com/29220
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
22 files changed:
src/cmd/compile/internal/amd64/galign.go
src/cmd/compile/internal/amd64/gsubr.go
src/cmd/compile/internal/arm/galign.go
src/cmd/compile/internal/arm/ggen.go
src/cmd/compile/internal/arm/gsubr.go
src/cmd/compile/internal/arm64/galign.go
src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/arm64/gsubr.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/mips64/galign.go
src/cmd/compile/internal/mips64/ggen.go
src/cmd/compile/internal/mips64/gsubr.go
src/cmd/compile/internal/ppc64/galign.go
src/cmd/compile/internal/ppc64/ggen.go
src/cmd/compile/internal/ppc64/gsubr.go
src/cmd/compile/internal/s390x/galign.go
src/cmd/compile/internal/s390x/ggen.go
src/cmd/compile/internal/s390x/gsubr.go
src/cmd/compile/internal/x86/galign.go
src/cmd/compile/internal/x86/gsubr.go

index 22a25af1d7969cfa1ecae1ca6ffd6e5006c07e9e..25d71e6fa65f4e68333a5c929765dbf2d724065a 100644 (file)
@@ -45,7 +45,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index 76fca896e7606793b7b05f9eda62e27e5922ae88..1f5749315f789138b4549d5e65fbfe81107c9091 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/compile/internal/gc"
        "cmd/internal/obj"
        "cmd/internal/obj/x86"
-       "fmt"
 )
 
 var resvd = []int{
@@ -47,117 +46,13 @@ var resvd = []int{
        x86.REG_SP, // for stack
 }
 
-func samaddr(f *gc.Node, t *gc.Node) bool {
-       if f.Op != t.Op {
-               return false
-       }
-
-       switch f.Op {
-       case gc.OREGISTER:
-               if f.Reg != t.Reg {
-                       break
-               }
-               return true
-       }
-
-       return false
-}
-
-/*
- * generate one instruction:
- *     as f, t
- */
-func gins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       //      Node nod;
-
-       //      if(f != N && f->op == OINDEX) {
-       //              gc.Regalloc(&nod, &regnode, Z);
-       //              v = constnode.vconst;
-       //              gc.Cgen(f->right, &nod);
-       //              constnode.vconst = v;
-       //              idx.reg = nod.reg;
-       //              gc.Regfree(&nod);
-       //      }
-       //      if(t != N && t->op == OINDEX) {
-       //              gc.Regalloc(&nod, &regnode, Z);
-       //              v = constnode.vconst;
-       //              gc.Cgen(t->right, &nod);
-       //              constnode.vconst = v;
-       //              idx.reg = nod.reg;
-       //              gc.Regfree(&nod);
-       //      }
-
-       if f != nil && f.Op == gc.OADDR && (as == x86.AMOVL || as == x86.AMOVQ) {
-               // Turn MOVL $xxx into LEAL xxx.
-               // These should be equivalent but most of the backend
-               // only expects to see LEAL, because that's what we had
-               // historically generated. Various hidden assumptions are baked in by now.
-               if as == x86.AMOVL {
-                       as = x86.ALEAL
-               } else {
-                       as = x86.ALEAQ
-               }
-               f = f.Left
-       }
-
-       switch as {
-       case x86.AMOVB,
-               x86.AMOVW,
-               x86.AMOVL,
-               x86.AMOVQ,
-               x86.AMOVSS,
-               x86.AMOVSD:
-               if f != nil && t != nil && samaddr(f, t) {
-                       return nil
-               }
-
-       case x86.ALEAQ:
-               if f != nil && gc.Isconst(f, gc.CTNIL) {
-                       gc.Fatalf("gins LEAQ nil %v", f.Type)
-               }
-       }
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := int32(0)
-       switch as {
-       case x86.AMOVB:
-               w = 1
-
-       case x86.AMOVW:
-               w = 2
-
-       case x86.AMOVL:
-               w = 4
-
-       case x86.AMOVQ:
-               w = 8
-       }
-
-       if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Width > int64(w))) {
-               gc.Dump("f", f)
-               gc.Dump("t", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       if p.To.Type == obj.TYPE_ADDR && w > 0 {
-               gc.Fatalf("bad use of addr: %v", p)
-       }
-
-       return p
-}
-
 func ginsnop() {
        // This is actually not the x86 NOP anymore,
        // but at the point where it gets used, AX is dead
        // so it's okay if we lose the high bits.
-       var reg gc.Node
-       gc.Nodreg(&reg, gc.Types[gc.TINT], x86.REG_AX)
-       gins(x86.AXCHGL, &reg, &reg)
+       p := gc.Prog(x86.AXCHGL)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = x86.REG_AX
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = x86.REG_AX
 }
index acd150846f502ef57570d62a886c7225562b7ef2..090a6c25fb38a4551585c857754d4082379f5582 100644 (file)
@@ -29,7 +29,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index 66acf03a8f1c8f9c405d610ae17233546c41f2e1..07278d15bdeb99555054964fdeb531e7c86f025c 100644 (file)
@@ -96,8 +96,10 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Pr
 }
 
 func ginsnop() {
-       var r gc.Node
-       gc.Nodreg(&r, gc.Types[gc.TINT], arm.REG_R0)
-       p := gins(arm.AAND, &r, &r)
+       p := gc.Prog(arm.AAND)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = arm.REG_R0
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = arm.REG_R0
        p.Scond = arm.C_SCOND_EQ
 }
index 2ef4760013685f6a5aba964010fca287fef59b53..e6e2139d48028def2deea1f2a0c7b57800e0b58a 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/compile/internal/gc"
        "cmd/internal/obj"
        "cmd/internal/obj/arm"
-       "fmt"
 )
 
 var resvd = []int{
@@ -42,85 +41,6 @@ var resvd = []int{
        arm.REG_R10, // reserved for g
 }
 
-/*
- * generate one instruction:
- *     as f, t
- */
-func gins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       //      Node nod;
-       //      int32 v;
-
-       if f != nil && f.Op == gc.OINDEX {
-               gc.Fatalf("gins OINDEX not implemented")
-       }
-
-       //              gc.Regalloc(&nod, &regnode, Z);
-       //              v = constnode.vconst;
-       //              gc.Cgen(f->right, &nod);
-       //              constnode.vconst = v;
-       //              idx.reg = nod.reg;
-       //              gc.Regfree(&nod);
-       if t != nil && t.Op == gc.OINDEX {
-               gc.Fatalf("gins OINDEX not implemented")
-       }
-
-       //              gc.Regalloc(&nod, &regnode, Z);
-       //              v = constnode.vconst;
-       //              gc.Cgen(t->right, &nod);
-       //              constnode.vconst = v;
-       //              idx.reg = nod.reg;
-       //              gc.Regfree(&nod);
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       switch as {
-       case arm.ABL:
-               if p.To.Type == obj.TYPE_REG {
-                       p.To.Type = obj.TYPE_MEM
-               }
-
-       case arm.ACMP, arm.ACMPF, arm.ACMPD:
-               if t != nil {
-                       if f.Op != gc.OREGISTER {
-                               /* generate a comparison
-                               TODO(kaib): one of the args can actually be a small constant. relax the constraint and fix call sites.
-                               */
-                               gc.Fatalf("bad operands to gcmp")
-                       }
-                       p.From = p.To
-                       p.To = obj.Addr{}
-                       raddr(f, p)
-               }
-
-       case arm.AMULU:
-               if f != nil && f.Op != gc.OREGISTER {
-                       gc.Fatalf("bad operands to mul")
-               }
-
-       case arm.AMOVW:
-               if (p.From.Type == obj.TYPE_MEM || p.From.Type == obj.TYPE_ADDR || p.From.Type == obj.TYPE_CONST) && (p.To.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_ADDR) {
-                       gc.Fatalf("gins double memory")
-               }
-
-       case arm.AADD:
-               if p.To.Type == obj.TYPE_MEM {
-                       gc.Fatalf("gins arith to mem")
-               }
-
-       case arm.ARSB:
-               if p.From.Type == obj.TYPE_NONE {
-                       gc.Fatalf("rsb with no from")
-               }
-       }
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-       return p
-}
-
 /*
  * insert n into reg slot of p
  */
index 696434ba6931518da376351c452546ef60eb1e2d..6677fe683085623d2fa6cc113a17956dbbe69274 100644 (file)
@@ -30,7 +30,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index 0ea3e4adeac16956db6b5a39325146223c8489fc..05ba855440c90cef84241b9991d7104964ec03f3 100644 (file)
@@ -106,7 +106,6 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
 }
 
 func ginsnop() {
-       var con gc.Node
-       gc.Nodconst(&con, gc.Types[gc.TINT], 0)
-       gins(arm64.AHINT, &con, nil)
+       p := gc.Prog(arm64.AHINT)
+       p.From.Type = obj.TYPE_CONST
 }
index 3bc1bd82739e9cb513f1f92ae53b383d7f53bfb2..b6b71f01bea98f2baf63d6a685dfde20df35d431 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/compile/internal/gc"
        "cmd/internal/obj"
        "cmd/internal/obj/arm64"
-       "fmt"
 )
 
 var resvd = []int{
@@ -45,115 +44,6 @@ var resvd = []int{
        arm64.REG_R31, // REGZERO and REGSP
 }
 
-/*
- * generate
- *     as $c, n
- */
-func ginscon(as obj.As, c int64, n2 *gc.Node) {
-       var n1 gc.Node
-
-       gc.Nodconst(&n1, gc.Types[gc.TINT64], c)
-
-       if as != arm64.AMOVD && (c < -arm64.BIG || c > arm64.BIG) || as == arm64.AMUL || n2 != nil && n2.Op != gc.OREGISTER {
-               // cannot have more than 16-bit of immediate in ADD, etc.
-               // instead, MOV into register first.
-               var ntmp gc.Node
-               gc.Regalloc(&ntmp, gc.Types[gc.TINT64], nil)
-
-               gins(arm64.AMOVD, &n1, &ntmp)
-               gins(as, &ntmp, n2)
-               gc.Regfree(&ntmp)
-               return
-       }
-
-       rawgins(as, &n1, n2)
-}
-
-// gins is called by the front end.
-// It synthesizes some multiple-instruction sequences
-// so the front end can stay simpler.
-func gins(as obj.As, f, t *gc.Node) *obj.Prog {
-       if as >= obj.A_ARCHSPECIFIC {
-               if x, ok := f.IntLiteral(); ok {
-                       ginscon(as, x, t)
-                       return nil // caller must not use
-               }
-       }
-       return rawgins(as, f, t)
-}
-
-/*
- * generate one instruction:
- *     as f, t
- */
-func rawgins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       // TODO(austin): Add self-move test like in 6g (but be careful
-       // of truncation moves)
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       switch as {
-       case arm64.ACMP, arm64.AFCMPS, arm64.AFCMPD:
-               if t != nil {
-                       if f.Op != gc.OREGISTER {
-                               gc.Fatalf("bad operands to gcmp")
-                       }
-                       p.From = p.To
-                       p.To = obj.Addr{}
-                       raddr(f, p)
-               }
-       }
-
-       // Bad things the front end has done to us. Crash to find call stack.
-       switch as {
-       case arm64.AAND, arm64.AMUL:
-               if p.From.Type == obj.TYPE_CONST {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       case arm64.ACMP:
-               if p.From.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_MEM {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       }
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := int32(0)
-       switch as {
-       case arm64.AMOVB,
-               arm64.AMOVBU:
-               w = 1
-
-       case arm64.AMOVH,
-               arm64.AMOVHU:
-               w = 2
-
-       case arm64.AMOVW,
-               arm64.AMOVWU:
-               w = 4
-
-       case arm64.AMOVD:
-               if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
-                       break
-               }
-               w = 8
-       }
-
-       if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
-               gc.Dump("f", f)
-               gc.Dump("t", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       return p
-}
-
 /*
  * insert n into reg slot of p
  */
index c4cf9abbb8187a52abce2db3cf244f2c5a08c6b7..f4696945cdf86666c71712b90096433301ca5fe2 100644 (file)
@@ -370,7 +370,6 @@ type Arch struct {
 
        Betypeinit func()
        Defframe   func(*obj.Prog)
-       Gins       func(obj.As, *Node, *Node) *obj.Prog
        Proginfo   func(*obj.Prog) // fills in Prog.Info
        Use387     bool            // should 8g use 387 FP instructions instead of sse2.
 
index 4326852a006aac20bccc8636fc4ad986667a5fd7..c0150fd0304a26f86aae88b0e6765a02fca81593 100644 (file)
@@ -34,8 +34,6 @@ import (
        "cmd/internal/obj"
        "cmd/internal/sys"
        "fmt"
-       "runtime"
-       "strings"
 )
 
 var (
@@ -75,19 +73,6 @@ func Prog(as obj.As) *obj.Prog {
        return p
 }
 
-func Nodreg(n *Node, t *Type, r int) {
-       if t == nil {
-               Fatalf("nodreg: t nil")
-       }
-
-       *n = Node{}
-       n.Op = OREGISTER
-       n.Addable = true
-       ullmancalc(n)
-       n.Reg = int16(r)
-       n.Type = t
-}
-
 func Afunclit(a *obj.Addr, n *Node) {
        if a.Type == obj.TYPE_ADDR && a.Name == obj.NAME_EXTERN {
                a.Type = obj.TYPE_MEM
@@ -176,7 +161,7 @@ func fixautoused(p *obj.Prog) {
 }
 
 func ggloblnod(nam *Node) {
-       p := Thearch.Gins(obj.AGLOBL, nam, nil)
+       p := Gins(obj.AGLOBL, nam, nil)
        p.Lineno = nam.Lineno
        p.From.Sym.Gotype = Linksym(ngotype(nam))
        p.To.Sym = nil
@@ -196,7 +181,7 @@ func ggloblsym(s *Sym, width int32, flags int16) {
 }
 
 func ggloblLSym(s *obj.LSym, width int32, flags int16) {
-       p := Thearch.Gins(obj.AGLOBL, nil, nil)
+       p := Gins(obj.AGLOBL, nil, nil)
        p.From.Type = obj.TYPE_MEM
        p.From.Name = obj.NAME_EXTERN
        p.From.Sym = s
@@ -211,7 +196,7 @@ func ggloblLSym(s *obj.LSym, width int32, flags int16) {
 }
 
 func gtrack(s *Sym) {
-       p := Thearch.Gins(obj.AUSEFIELD, nil, nil)
+       p := Gins(obj.AUSEFIELD, nil, nil)
        p.From.Type = obj.TYPE_MEM
        p.From.Name = obj.NAME_EXTERN
        p.From.Sym = Linksym(s)
@@ -598,6 +583,25 @@ func Patch(p *obj.Prog, to *obj.Prog) {
        p.To.Offset = to.Pc
 }
 
+// Gins inserts instruction as. f is from, t is to.
+func Gins(as obj.As, f, t *Node) *obj.Prog {
+       switch as {
+       case obj.AVARKILL, obj.AVARLIVE, obj.AVARDEF, obj.ATYPE,
+               obj.ATEXT, obj.AFUNCDATA, obj.AUSEFIELD, obj.AGLOBL:
+       default:
+               Fatalf("unhandled gins op %v", as)
+       }
+
+       p := Prog(as)
+       Naddr(&p.From, f)
+       Naddr(&p.To, t)
+
+       if Debug['g'] != 0 {
+               fmt.Printf("%v\n", p)
+       }
+       return p
+}
+
 var reg [100]int       // count of references to reg
 var regstk [100][]byte // allocation sites, when -v is given
 
@@ -617,131 +621,3 @@ func ginit() {
                reg[r-Thearch.REGMIN] = 1
        }
 }
-
-// allocate register of type t, leave in n.
-// if o != N, o may be reusable register.
-// caller must Regfree(n).
-func Regalloc(n *Node, t *Type, o *Node) {
-       if t == nil {
-               Fatalf("regalloc: t nil")
-       }
-       et := simtype[t.Etype]
-       if Ctxt.Arch.RegSize == 4 && (et == TINT64 || et == TUINT64) {
-               Fatalf("regalloc 64bit")
-       }
-
-       var i int
-Switch:
-       switch et {
-       default:
-               Fatalf("regalloc: unknown type %v", t)
-
-       case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TPTR32, TPTR64, TBOOL:
-               if o != nil && o.Op == OREGISTER {
-                       i = int(o.Reg)
-                       if Thearch.REGMIN <= i && i <= Thearch.REGMAX {
-                               break Switch
-                       }
-               }
-               for i = Thearch.REGMIN; i <= Thearch.REGMAX; i++ {
-                       if reg[i-Thearch.REGMIN] == 0 {
-                               break Switch
-                       }
-               }
-               flusherrors()
-               regdump()
-               Fatalf("out of fixed registers")
-
-       case TFLOAT32, TFLOAT64:
-               if Thearch.Use387 {
-                       i = Thearch.FREGMIN // x86.REG_F0
-                       break Switch
-               }
-               if o != nil && o.Op == OREGISTER {
-                       i = int(o.Reg)
-                       if Thearch.FREGMIN <= i && i <= Thearch.FREGMAX {
-                               break Switch
-                       }
-               }
-               for i = Thearch.FREGMIN; i <= Thearch.FREGMAX; i++ {
-                       if reg[i-Thearch.REGMIN] == 0 { // note: REGMIN, not FREGMIN
-                               break Switch
-                       }
-               }
-               flusherrors()
-               regdump()
-               Fatalf("out of floating registers")
-
-       case TCOMPLEX64, TCOMPLEX128:
-               tempname(n, t)
-               return
-       }
-
-       ix := i - Thearch.REGMIN
-       if reg[ix] == 0 && Debug['v'] > 0 {
-               if regstk[ix] == nil {
-                       regstk[ix] = make([]byte, 4096)
-               }
-               stk := regstk[ix]
-               n := runtime.Stack(stk[:cap(stk)], false)
-               regstk[ix] = stk[:n]
-       }
-       reg[ix]++
-       Nodreg(n, t, i)
-}
-
-func Regfree(n *Node) {
-       if n.Op == ONAME {
-               return
-       }
-       if n.Op != OREGISTER && n.Op != OINDREG {
-               Fatalf("regfree: not a register")
-       }
-       i := int(n.Reg)
-       if i == Thearch.REGSP {
-               return
-       }
-       switch {
-       case Thearch.REGMIN <= i && i <= Thearch.REGMAX,
-               Thearch.FREGMIN <= i && i <= Thearch.FREGMAX:
-               // ok
-       default:
-               Fatalf("regfree: reg out of range")
-       }
-
-       i -= Thearch.REGMIN
-       if reg[i] <= 0 {
-               Fatalf("regfree: reg not allocated")
-       }
-       reg[i]--
-       if reg[i] == 0 {
-               regstk[i] = regstk[i][:0]
-       }
-}
-
-func regdump() {
-       if Debug['v'] == 0 {
-               fmt.Printf("run compiler with -v for register allocation sites\n")
-               return
-       }
-
-       dump := func(r int) {
-               stk := regstk[r-Thearch.REGMIN]
-               if len(stk) == 0 {
-                       return
-               }
-               fmt.Printf("reg %v allocated at:\n", obj.Rconv(r))
-               fmt.Printf("\t%s\n", strings.Replace(strings.TrimSpace(string(stk)), "\n", "\n\t", -1))
-       }
-
-       for r := Thearch.REGMIN; r <= Thearch.REGMAX; r++ {
-               if reg[r-Thearch.REGMIN] != 0 {
-                       dump(r)
-               }
-       }
-       for r := Thearch.FREGMIN; r <= Thearch.FREGMAX; r++ {
-               if reg[r-Thearch.REGMIN] == 0 {
-                       dump(r)
-               }
-       }
-}
index 04f98016652377dbcd130e0d4b9b92a2f7d43e43..bfe1cd21b0443d6cb5fb3824bb8d7a7cb9cc61b0 100644 (file)
@@ -24,7 +24,7 @@ func makefuncdatasym(nameprefix string, funcdatakind int64) *Sym {
        pnod := newname(sym)
        pnod.Class = PEXTERN
        Nodconst(&nod, Types[TINT32], funcdatakind)
-       Thearch.Gins(obj.AFUNCDATA, &nod, pnod)
+       Gins(obj.AFUNCDATA, &nod, pnod)
        return sym
 }
 
@@ -96,9 +96,9 @@ func gvardefx(n *Node, as obj.As) {
        switch n.Class {
        case PAUTO, PPARAM, PPARAMOUT:
                if as == obj.AVARLIVE {
-                       Thearch.Gins(as, n, nil)
+                       Gins(as, n, nil)
                } else {
-                       Thearch.Gins(as, nil, n)
+                       Gins(as, nil, n)
                }
        }
 }
@@ -389,7 +389,7 @@ func compile(fn *Node) {
        if isblank(nam) {
                nam = nil
        }
-       ptxt := Thearch.Gins(obj.ATEXT, nam, &nod1)
+       ptxt := Gins(obj.ATEXT, nam, &nod1)
        Afunclit(&ptxt.From, Curfn.Func.Nname)
        ptxt.From3 = new(obj.Addr)
        if fn.Func.Dupok {
@@ -443,7 +443,7 @@ func compile(fn *Node) {
                switch n.Class {
                case PAUTO, PPARAM, PPARAMOUT:
                        Nodconst(&nod1, Types[TUINTPTR], n.Type.Width)
-                       p := Thearch.Gins(obj.ATYPE, n, &nod1)
+                       p := Gins(obj.ATYPE, n, &nod1)
                        p.From.Gotype = Linksym(ngotype(n))
                }
        }
index ca1cb689ffc36596ebcd2454a5859427993e4460..d8d12dec50c3e6f12afb5eaff6ed574636627be3 100644 (file)
@@ -33,7 +33,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index c8c0d91fdda54ed34bd34b255ba19dbac8a678a3..d1b5a118dce689be1f42a12c233a77d49e35aa6b 100644 (file)
@@ -101,7 +101,9 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
 }
 
 func ginsnop() {
-       var reg gc.Node
-       gc.Nodreg(&reg, gc.Types[gc.TINT], mips.REG_R0)
-       gins(mips.ANOR, &reg, &reg)
+       p := gc.Prog(mips.ANOR)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = mips.REG_R0
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = mips.REG_R0
 }
index ecf83594ce263317d454f10f5a8b2d97c91624ed..c67ad5530331e198e190d744767f349d07b53bba 100644 (file)
 
 package mips64
 
-import (
-       "cmd/compile/internal/gc"
-       "cmd/internal/obj"
-       "cmd/internal/obj/mips"
-       "fmt"
-)
+import "cmd/internal/obj/mips"
 
 var resvd = []int{
        mips.REGZERO,
@@ -47,136 +42,3 @@ var resvd = []int{
        mips.REG_R26, // kernel
        mips.REG_R27, // kernel
 }
-
-/*
- * generate
- *      as $c, n
- */
-func ginscon(as obj.As, c int64, n2 *gc.Node) {
-       var n1 gc.Node
-
-       gc.Nodconst(&n1, gc.Types[gc.TINT64], c)
-
-       if as != mips.AMOVV && (c < -mips.BIG || c > mips.BIG) || n2.Op != gc.OREGISTER || as == mips.AMUL || as == mips.AMULU || as == mips.AMULV || as == mips.AMULVU {
-               // cannot have more than 16-bit of immediate in ADD, etc.
-               // instead, MOV into register first.
-               var ntmp gc.Node
-               gc.Regalloc(&ntmp, gc.Types[gc.TINT64], nil)
-
-               rawgins(mips.AMOVV, &n1, &ntmp)
-               rawgins(as, &ntmp, n2)
-               gc.Regfree(&ntmp)
-               return
-       }
-
-       rawgins(as, &n1, n2)
-}
-
-// gins is called by the front end.
-// It synthesizes some multiple-instruction sequences
-// so the front end can stay simpler.
-func gins(as obj.As, f, t *gc.Node) *obj.Prog {
-       if as >= obj.A_ARCHSPECIFIC {
-               if x, ok := f.IntLiteral(); ok {
-                       ginscon(as, x, t)
-                       return nil // caller must not use
-               }
-       }
-       return rawgins(as, f, t)
-}
-
-/*
- * generate one instruction:
- *     as f, t
- */
-func rawgins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       // TODO(austin): Add self-move test like in 6g (but be careful
-       // of truncation moves)
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       switch as {
-       case obj.ACALL:
-               if p.To.Type == obj.TYPE_REG {
-                       // Allow front end to emit CALL REG, and rewrite into CALL (REG).
-                       p.From = obj.Addr{}
-                       p.To.Type = obj.TYPE_MEM
-                       p.To.Offset = 0
-
-                       if gc.Debug['g'] != 0 {
-                               fmt.Printf("%v\n", p)
-                       }
-
-                       return p
-               }
-
-       // Bad things the front end has done to us. Crash to find call stack.
-       case mips.AAND:
-               if p.From.Type == obj.TYPE_CONST {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       case mips.ASGT, mips.ASGTU:
-               if p.From.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_MEM {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-
-       // Special cases
-       case mips.AMUL, mips.AMULU, mips.AMULV, mips.AMULVU:
-               if p.From.Type == obj.TYPE_CONST {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-
-               pp := gc.Prog(mips.AMOVV)
-               pp.From.Type = obj.TYPE_REG
-               pp.From.Reg = mips.REG_LO
-               pp.To = p.To
-
-               p.Reg = p.To.Reg
-               p.To = obj.Addr{}
-
-       case mips.ASUBVU:
-               // unary
-               if f == nil {
-                       p.From = p.To
-                       p.Reg = mips.REGZERO
-               }
-       }
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := int32(0)
-       switch as {
-       case mips.AMOVB,
-               mips.AMOVBU:
-               w = 1
-
-       case mips.AMOVH,
-               mips.AMOVHU:
-               w = 2
-
-       case mips.AMOVW,
-               mips.AMOVWU:
-               w = 4
-
-       case mips.AMOVV:
-               if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
-                       break
-               }
-               w = 8
-       }
-
-       if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
-               gc.Dump("f", f)
-               gc.Dump("t", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       return p
-}
index 5491c125e1f2011ce544a09fbecb42378b598dee..ddadf80aae0f2f2baa6f72092b6647fcd51e2349 100644 (file)
@@ -36,7 +36,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index bc7a91cec71c5288fd3afdb54983915bc0c99697..9e51c28735ddbd08eae3668bd941afb3bf9109f4 100644 (file)
@@ -93,7 +93,9 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
 }
 
 func ginsnop() {
-       var reg gc.Node
-       gc.Nodreg(&reg, gc.Types[gc.TINT], ppc64.REG_R0)
-       gins(ppc64.AOR, &reg, &reg)
+       p := gc.Prog(ppc64.AOR)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = ppc64.REG_R0
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = ppc64.REG_R0
 }
index ab9c16ced8e3fc4bd0a347d3571e32b1d975f4a3..16671b23eea351054b7c1929510008afa92684a0 100644 (file)
 
 package ppc64
 
-import (
-       "cmd/compile/internal/gc"
-       "cmd/internal/obj"
-       "cmd/internal/obj/ppc64"
-       "fmt"
-)
+import "cmd/internal/obj/ppc64"
 
 var resvd = []int{
        ppc64.REGZERO,
@@ -51,153 +46,3 @@ var resvd = []int{
        ppc64.REGG,
        ppc64.REGTMP, // REGTMP
 }
-
-/*
- * generate
- *     as $c, n
- */
-func ginscon(as obj.As, c int64, n2 *gc.Node) {
-       var n1 gc.Node
-
-       gc.Nodconst(&n1, gc.Types[gc.TINT64], c)
-
-       if as != ppc64.AMOVD && (c < -ppc64.BIG || c > ppc64.BIG) || n2.Op != gc.OREGISTER || as == ppc64.AMULLD {
-               // cannot have more than 16-bit of immediate in ADD, etc.
-               // instead, MOV into register first.
-               var ntmp gc.Node
-               gc.Regalloc(&ntmp, gc.Types[gc.TINT64], nil)
-
-               rawgins(ppc64.AMOVD, &n1, &ntmp)
-               rawgins(as, &ntmp, n2)
-               gc.Regfree(&ntmp)
-               return
-       }
-
-       rawgins(as, &n1, n2)
-}
-
-// gins is called by the front end.
-// It synthesizes some multiple-instruction sequences
-// so the front end can stay simpler.
-func gins(as obj.As, f, t *gc.Node) *obj.Prog {
-       if as >= obj.A_ARCHSPECIFIC {
-               if x, ok := f.IntLiteral(); ok {
-                       ginscon(as, x, t)
-                       return nil // caller must not use
-               }
-       }
-       return rawgins(as, f, t)
-}
-
-/*
- * generate one instruction:
- *     as f, t
- */
-func rawgins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       // TODO(austin): Add self-move test like in 6g (but be careful
-       // of truncation moves)
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       switch as {
-       case obj.ACALL:
-               if p.To.Type == obj.TYPE_REG && p.To.Reg != ppc64.REG_CTR {
-                       // Allow front end to emit CALL REG, and rewrite into MOV REG, CTR; CALL CTR.
-                       if gc.Ctxt.Flag_shared {
-                               // Make sure function pointer is in R12 as well when
-                               // compiling Go into PIC.
-                               // TODO(mwhudson): it would obviously be better to
-                               // change the register allocation to put the value in
-                               // R12 already, but I don't know how to do that.
-                               q := gc.Prog(as)
-                               q.As = ppc64.AMOVD
-                               q.From = p.To
-                               q.To.Type = obj.TYPE_REG
-                               q.To.Reg = ppc64.REG_R12
-                       }
-                       pp := gc.Prog(as)
-                       pp.From = p.From
-                       pp.To.Type = obj.TYPE_REG
-                       pp.To.Reg = ppc64.REG_CTR
-
-                       p.As = ppc64.AMOVD
-                       p.From = p.To
-                       p.To.Type = obj.TYPE_REG
-                       p.To.Reg = ppc64.REG_CTR
-
-                       if gc.Ctxt.Flag_shared {
-                               // When compiling Go into PIC, the function we just
-                               // called via pointer might have been implemented in
-                               // a separate module and so overwritten the TOC
-                               // pointer in R2; reload it.
-                               q := gc.Prog(ppc64.AMOVD)
-                               q.From.Type = obj.TYPE_MEM
-                               q.From.Offset = 24
-                               q.From.Reg = ppc64.REGSP
-                               q.To.Type = obj.TYPE_REG
-                               q.To.Reg = ppc64.REG_R2
-                       }
-
-                       if gc.Debug['g'] != 0 {
-                               fmt.Printf("%v\n", p)
-                               fmt.Printf("%v\n", pp)
-                       }
-
-                       return pp
-               }
-
-       // Bad things the front end has done to us. Crash to find call stack.
-       case ppc64.AAND, ppc64.AMULLD:
-               if p.From.Type == obj.TYPE_CONST {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       case ppc64.ACMP, ppc64.ACMPU:
-               if p.From.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_MEM {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       }
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := int32(0)
-       switch as {
-       case ppc64.AMOVB,
-               ppc64.AMOVBU,
-               ppc64.AMOVBZ,
-               ppc64.AMOVBZU:
-               w = 1
-
-       case ppc64.AMOVH,
-               ppc64.AMOVHU,
-               ppc64.AMOVHZ,
-               ppc64.AMOVHZU:
-               w = 2
-
-       case ppc64.AMOVW,
-               ppc64.AMOVWU,
-               ppc64.AMOVWZ,
-               ppc64.AMOVWZU:
-               w = 4
-
-       case ppc64.AMOVD,
-               ppc64.AMOVDU:
-               if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
-                       break
-               }
-               w = 8
-       }
-
-       if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
-               gc.Dump("f", f)
-               gc.Dump("t", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       return p
-}
index 93ece5a7ffb1135ee20ceb5aa9055662f864eff0..a178041c808d7ae124325c20a5c5b20f00062510 100644 (file)
@@ -28,7 +28,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index 60b08c89f07df5711c2ff0d384561b596fe7197b..15c65546d6914a406ff2130ce1165f62c4a72192 100644 (file)
@@ -144,7 +144,9 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
 }
 
 func ginsnop() {
-       var reg gc.Node
-       gc.Nodreg(&reg, gc.Types[gc.TINT], s390x.REG_R0)
-       gins(s390x.AOR, &reg, &reg)
+       p := gc.Prog(s390x.AOR)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = int16(s390x.REG_R0)
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = int16(s390x.REG_R0)
 }
index dbacad9ea2bdb253a1900fe317a664fa69ee6467..06043e225b792faafe27d698b8190b56c45690aa 100644 (file)
 
 package s390x
 
-import (
-       "cmd/compile/internal/gc"
-       "cmd/internal/obj"
-       "cmd/internal/obj/s390x"
-       "fmt"
-)
+import "cmd/internal/obj/s390x"
 
 var resvd = []int{
        s390x.REGZERO, // R0
@@ -46,110 +41,3 @@ var resvd = []int{
        s390x.REG_LR,  // R14
        s390x.REGSP,   // R15
 }
-
-// generate
-//     as $c, n
-func ginscon(as obj.As, c int64, n2 *gc.Node) {
-       var n1 gc.Node
-
-       gc.Nodconst(&n1, gc.Types[gc.TINT64], c)
-
-       if as != s390x.AMOVD && (c < -s390x.BIG || c > s390x.BIG) || n2.Op != gc.OREGISTER {
-               // cannot have more than 16-bit of immediate in ADD, etc.
-               // instead, MOV into register first.
-               var ntmp gc.Node
-               gc.Regalloc(&ntmp, gc.Types[gc.TINT64], nil)
-
-               rawgins(s390x.AMOVD, &n1, &ntmp)
-               rawgins(as, &ntmp, n2)
-               gc.Regfree(&ntmp)
-               return
-       }
-
-       rawgins(as, &n1, n2)
-}
-
-func intLiteral(n *gc.Node) (x int64, ok bool) {
-       switch {
-       case n == nil:
-               return
-       case gc.Isconst(n, gc.CTINT):
-               return n.Int64(), true
-       case gc.Isconst(n, gc.CTBOOL):
-               return int64(obj.Bool2int(n.Bool())), true
-       }
-       return
-}
-
-// gins is called by the front end.
-// It synthesizes some multiple-instruction sequences
-// so the front end can stay simpler.
-func gins(as obj.As, f, t *gc.Node) *obj.Prog {
-       if t != nil {
-               if as >= obj.A_ARCHSPECIFIC {
-                       if x, ok := intLiteral(f); ok {
-                               ginscon(as, x, t)
-                               return nil // caller must not use
-                       }
-               }
-       }
-       return rawgins(as, f, t)
-}
-
-// generate one instruction:
-//     as f, t
-func rawgins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       // self move check
-       // TODO(mundaym): use sized math and extend to MOVB, MOVWZ etc.
-       switch as {
-       case s390x.AMOVD, s390x.AFMOVS, s390x.AFMOVD:
-               if f != nil && t != nil &&
-                       f.Op == gc.OREGISTER && t.Op == gc.OREGISTER &&
-                       f.Reg == t.Reg {
-                       return nil
-               }
-       }
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       switch as {
-       // Bad things the front end has done to us. Crash to find call stack.
-       case s390x.ACMP, s390x.ACMPU:
-               if p.From.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_MEM {
-                       gc.Debug['h'] = 1
-                       gc.Fatalf("bad inst: %v", p)
-               }
-       }
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := int32(0)
-       switch as {
-       case s390x.AMOVB, s390x.AMOVBZ:
-               w = 1
-
-       case s390x.AMOVH, s390x.AMOVHZ:
-               w = 2
-
-       case s390x.AMOVW, s390x.AMOVWZ:
-               w = 4
-
-       case s390x.AMOVD:
-               if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
-                       break
-               }
-               w = 8
-       }
-
-       if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
-               gc.Dump("f", f)
-               gc.Dump("t", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       return p
-}
index 269ff56938bedfd0a48efaa18ad530cea79efd41..df9f7748f3b636007fe0263b0f2dc79f419af8fa 100644 (file)
@@ -41,7 +41,6 @@ func Main() {
 
        gc.Thearch.Betypeinit = betypeinit
        gc.Thearch.Defframe = defframe
-       gc.Thearch.Gins = gins
        gc.Thearch.Proginfo = proginfo
 
        gc.Thearch.SSARegToReg = ssaRegToReg
index a0d36a2d70b62a923dc55db7bc2f13646d0fd3df..96105356fd72f768baf7e232eba449e0be66afdb 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/compile/internal/gc"
        "cmd/internal/obj"
        "cmd/internal/obj/x86"
-       "fmt"
 )
 
 var resvd = []int{
@@ -47,95 +46,10 @@ var resvd = []int{
        x86.REG_SP, // for stack
 }
 
-func samaddr(f *gc.Node, t *gc.Node) bool {
-       if f.Op != t.Op {
-               return false
-       }
-
-       switch f.Op {
-       case gc.OREGISTER:
-               if f.Reg != t.Reg {
-                       break
-               }
-               return true
-       }
-
-       return false
-}
-
-/*
- * generate one instruction:
- *     as f, t
- */
-func gins(as obj.As, f *gc.Node, t *gc.Node) *obj.Prog {
-       if as == x86.AFMOVF && f != nil && f.Op == gc.OREGISTER && t != nil && t.Op == gc.OREGISTER {
-               gc.Fatalf("gins MOVF reg, reg")
-       }
-       if as == x86.ACVTSD2SS && f != nil && f.Op == gc.OLITERAL {
-               gc.Fatalf("gins CVTSD2SS const")
-       }
-       if as == x86.AMOVSD && t != nil && t.Op == gc.OREGISTER && t.Reg == x86.REG_F0 {
-               gc.Fatalf("gins MOVSD into F0")
-       }
-
-       if as == x86.AMOVL && f != nil && f.Op == gc.OADDR && f.Left.Op == gc.ONAME && f.Left.Class != gc.PEXTERN && f.Left.Class != gc.PFUNC {
-               // Turn MOVL $xxx(FP/SP) into LEAL xxx.
-               // These should be equivalent but most of the backend
-               // only expects to see LEAL, because that's what we had
-               // historically generated. Various hidden assumptions are baked in by now.
-               as = x86.ALEAL
-               f = f.Left
-       }
-
-       switch as {
-       case x86.AMOVB,
-               x86.AMOVW,
-               x86.AMOVL:
-               if f != nil && t != nil && samaddr(f, t) {
-                       return nil
-               }
-
-       case x86.ALEAL:
-               if f != nil && gc.Isconst(f, gc.CTNIL) {
-                       gc.Fatalf("gins LEAL nil %v", f.Type)
-               }
-       }
-
-       p := gc.Prog(as)
-       gc.Naddr(&p.From, f)
-       gc.Naddr(&p.To, t)
-
-       if gc.Debug['g'] != 0 {
-               fmt.Printf("%v\n", p)
-       }
-
-       w := 0
-       switch as {
-       case x86.AMOVB:
-               w = 1
-
-       case x86.AMOVW:
-               w = 2
-
-       case x86.AMOVL:
-               w = 4
-       }
-
-       if true && w != 0 && f != nil && (p.From.Width > int64(w) || p.To.Width > int64(w)) {
-               gc.Dump("bad width from:", f)
-               gc.Dump("bad width to:", t)
-               gc.Fatalf("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
-       }
-
-       if p.To.Type == obj.TYPE_ADDR && w > 0 {
-               gc.Fatalf("bad use of addr: %v", p)
-       }
-
-       return p
-}
-
 func ginsnop() {
-       var reg gc.Node
-       gc.Nodreg(&reg, gc.Types[gc.TINT], x86.REG_AX)
-       gins(x86.AXCHGL, &reg, &reg)
+       p := gc.Prog(x86.AXCHGL)
+       p.From.Type = obj.TYPE_REG
+       p.From.Reg = x86.REG_AX
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = x86.REG_AX
 }