aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/gen
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-03-05 14:24:41 -0500
committerDavid Chase <drchase@google.com>2021-03-12 21:18:15 +0000
commit7240a18adbfcff5cfe750a1fa4af0fd42ade4381 (patch)
treecadceff330a0668aea23d23aad0a6667435e0b8f /src/cmd/compile/internal/ssa/gen
parentcdd08e615a9b92742b21a94443720b6d70452510 (diff)
downloadgo-7240a18adbfcff5cfe750a1fa4af0fd42ade4381.tar.gz
go-7240a18adbfcff5cfe750a1fa4af0fd42ade4381.zip
cmd/compile: test register ABI for method, interface, closure calls
This is enabled with a ridiculous magic name for method, or for last input type passed, that needs to be changed to something inutterable before actual release. Ridiculous method name: MagicMethodNameForTestingRegisterABI Ridiculous last (input) type name: MagicLastTypeNameForTestingRegisterABI RLTN is tested with strings.Contains, so you can have MagicLastTypeNameForTestingRegisterABI1 and MagicLastTypeNameForTestingRegisterABI2 if that is helpful Includes test test/abi/fibish2.go Updates #44816. Change-Id: I592a6edc71ca9bebdd1d00e24edee1ceebb3e43f Reviewed-on: https://go-review.googlesource.com/c/go/+/299410 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/gen')
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64Ops.go8
-rw-r--r--src/cmd/compile/internal/ssa/gen/genericOps.go27
2 files changed, 27 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
index 6bf5be9e47..6c3fe1d192 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
@@ -775,10 +775,10 @@ func init() {
faultOnNilArg0: true,
},
- // With a register ABI, the actual register info for these instructions (i.e., what is used in regalloc) is augmented with per-call-site bindings of additional arguments to specific registers.
- {name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
- {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
- {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+ // With a register ABI, the actual register info for these instructions (i.e., what is used in regalloc) is augmented with per-call-site bindings of additional arguments to specific in and out registers.
+ {name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem
+ {name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
+ {name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem
// arg0 = destination pointer
// arg1 = source pointer
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
index ee85156a42..2a5b77bad0 100644
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/gen/genericOps.go
@@ -264,7 +264,7 @@ var genericOps = []opData{
// ±0 → ±0 (sign preserved)
// x<0 → NaN
// NaN → NaN
- {name: "Sqrt", argLength: 1}, // √arg0 (floating point, double precision)
+ {name: "Sqrt", argLength: 1}, // √arg0 (floating point, double precision)
{name: "Sqrt32", argLength: 1}, // √arg0 (floating point, single precision)
// Round to integer, float64 only.
@@ -396,9 +396,28 @@ var genericOps = []opData{
// TODO(josharian): ClosureCall and InterCall should have Int32 aux
// to match StaticCall's 32 bit arg size limit.
// TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff?
- {name: "ClosureCall", argLength: 3, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2=memory. auxint=arg size. Returns memory.
- {name: "StaticCall", argLength: -1, aux: "CallOff", call: true}, // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory. auxint=arg size. Returns Result of register results, plus memory.
- {name: "InterCall", argLength: 2, aux: "CallOff", call: true}, // interface call. arg0=code pointer, arg1=memory, auxint=arg size. Returns memory.
+
+ // Before lowering, LECalls receive their fixed inputs (first), memory (last),
+ // and a variable number of input values in the middle.
+ // They produce a variable number of result values.
+ // These values are not necessarily "SSA-able"; they can be too large,
+ // but in that case inputs are loaded immediately before with OpDereference,
+ // and outputs are stored immediately with OpStore.
+ //
+ // After call expansion, Calls have the same fixed-middle-memory arrangement of inputs,
+ // with the difference that the "middle" is only the register-resident inputs,
+ // and the non-register inputs are instead stored at ABI-defined offsets from SP
+ // (and the stores thread through the memory that is ultimately an input to the call).
+ // Outputs follow a similar pattern; register-resident outputs are the leading elements
+ // of a Result-typed output, with memory last, and any memory-resident outputs have been
+ // stored to ABI-defined locations. Each non-memory input or output fits in a register.
+ //
+ // Subsequent architecture-specific lowering only changes the opcode.
+
+ {name: "ClosureCall", argLength: -1, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2..argN-1 are register inputs, argN=memory. auxint=arg size. Returns Result of register results, plus memory.
+ {name: "StaticCall", argLength: -1, aux: "CallOff", call: true}, // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory. auxint=arg size. Returns Result of register results, plus memory.
+ {name: "InterCall", argLength: -1, aux: "CallOff", call: true}, // interface call. arg0=code pointer, arg1..argN-1 are register inputs, argN=memory, auxint=arg size. Returns Result of register results, plus memory.
+
{name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr, arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
{name: "StaticLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
{name: "InterLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded interface call. arg0=code pointer, arg1..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.