cmd/internal/gc: move cgen, regalloc, et al to portable code

This CL moves the bulk of the code that has been copy-and-pasted
since the initial 386 port back into a shared place, cutting 5 copies to 1.

The motivation here is not cleanup per se but instead to reduce the
cost of introducing changes in shared concepts like regalloc or general
expression evaluation. For example, a change after this one will
implement x.(*T) without a call into the runtime. This CL makes that
followup work 5x easier.

The single copy still has more special cases for architecture details
than I'd like, but having them called out explicitly like this at least
opens the door to generalizing the conditions and smoothing out
the distinctions in the future.

This is a LARGE CL. I started by trying to pull in one function at a time
in a sequence of CLs and it became clear that everything was so
interrelated that it had to be moved as a whole. Apologies for the size.

It is not clear how many more releases this code will matter for;
eventually it will be replaced by Keith's SSA work. But as noted above,
the deduplication was necessary to reduce the cost of working on
the current code while we have it.

Passes tests on amd64, 386, arm, and ppc64le.
Can build arm64 binaries but not tested there.
Being able to build binaries means it is probably very close.

Change-Id: I735977f04c0614f80215fb12966dfe9bbd1f5861
Reviewed-on: https://go-review.googlesource.com/7853
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/cmd/internal/gc/go.go b/src/cmd/internal/gc/go.go
index 26f545a..c33664f 100644
--- a/src/cmd/internal/gc/go.go
+++ b/src/cmd/internal/gc/go.go
@@ -777,47 +777,60 @@
 )
 
 type Arch struct {
-	Thechar        int
-	Thestring      string
-	Thelinkarch    *obj.LinkArch
-	Typedefs       []Typedef
-	REGSP          int
-	REGCTXT        int
-	MAXWIDTH       int64
-	Anyregalloc    func() bool
-	Betypeinit     func()
-	Bgen           func(*Node, bool, int, *obj.Prog)
-	Cgen           func(*Node, *Node)
-	Cgen_call      func(*Node, int)
-	Cgen_callinter func(*Node, *Node, int)
-	Cgen_ret       func(*Node)
-	Clearfat       func(*Node)
-	Defframe       func(*obj.Prog)
-	Excise         func(*Flow)
-	Expandchecks   func(*obj.Prog)
-	Gclean         func()
-	Ginit          func()
-	Gins           func(int, *Node, *Node) *obj.Prog
-	Ginscall       func(*Node, int)
-	Gmove          func(*Node, *Node)
-	Igen           func(*Node, *Node, *Node)
-	Linkarchinit   func()
-	Peep           func(*obj.Prog)
-	Proginfo       func(*obj.Prog) // fills in Prog.Info
-	Regalloc       func(*Node, *Type, *Node)
-	Regfree        func(*Node)
-	Regtyp         func(*obj.Addr) bool
-	Sameaddr       func(*obj.Addr, *obj.Addr) bool
-	Smallindir     func(*obj.Addr, *obj.Addr) bool
-	Stackaddr      func(*obj.Addr) bool
-	Excludedregs   func() uint64
-	RtoB           func(int) uint64
-	FtoB           func(int) uint64
-	BtoR           func(uint64) int
-	BtoF           func(uint64) int
-	Optoas         func(int, *Type) int
-	Doregbits      func(int) uint64
-	Regnames       func(*int) []string
+	Thechar      int
+	Thestring    string
+	Thelinkarch  *obj.LinkArch
+	Typedefs     []Typedef
+	REGSP        int
+	REGCTXT      int
+	REGCALLX     int // BX
+	REGCALLX2    int // AX
+	REGRETURN    int // AX
+	REGMIN       int
+	REGMAX       int
+	FREGMIN      int
+	FREGMAX      int
+	MAXWIDTH     int64
+	ReservedRegs []int
+
+	AddIndex     func(*Node, int64, *Node) bool // optional
+	Betypeinit   func()
+	Bgen_float   func(*Node, int, int, *obj.Prog) // optional
+	Cgen64       func(*Node, *Node)               // only on 32-bit systems
+	Cgenindex    func(*Node, *Node, bool) *obj.Prog
+	Cgen_bmul    func(int, *Node, *Node, *Node) bool
+	Cgen_float   func(*Node, *Node) // optional
+	Cgen_hmul    func(*Node, *Node, *Node)
+	Cgen_shift   func(int, bool, *Node, *Node, *Node)
+	Clearfat     func(*Node)
+	Cmp64        func(*Node, *Node, int, int, *obj.Prog) // only on 32-bit systems
+	Defframe     func(*obj.Prog)
+	Dodiv        func(int, *Node, *Node, *Node)
+	Excise       func(*Flow)
+	Expandchecks func(*obj.Prog)
+	Gins         func(int, *Node, *Node) *obj.Prog
+	Ginscon      func(int, int64, *Node)
+	Ginsnop      func()
+	Gmove        func(*Node, *Node)
+	Igenindex    func(*Node, *Node, bool) *obj.Prog
+	Linkarchinit func()
+	Peep         func(*obj.Prog)
+	Proginfo     func(*obj.Prog) // fills in Prog.Info
+	Regtyp       func(*obj.Addr) bool
+	Sameaddr     func(*obj.Addr, *obj.Addr) bool
+	Smallindir   func(*obj.Addr, *obj.Addr) bool
+	Stackaddr    func(*obj.Addr) bool
+	Stackcopy    func(*Node, *Node, int64, int64, int64)
+	Sudoaddable  func(int, *Node, *obj.Addr) bool
+	Sudoclean    func()
+	Excludedregs func() uint64
+	RtoB         func(int) uint64
+	FtoB         func(int) uint64
+	BtoR         func(uint64) int
+	BtoF         func(uint64) int
+	Optoas       func(int, *Type) int
+	Doregbits    func(int) uint64
+	Regnames     func(*int) []string
 }
 
 var pcloc int32