diff options
author | David Chase <drchase@google.com> | 2021-03-05 14:24:41 -0500 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-03-12 21:18:15 +0000 |
commit | 7240a18adbfcff5cfe750a1fa4af0fd42ade4381 (patch) | |
tree | cadceff330a0668aea23d23aad0a6667435e0b8f /src/cmd/compile/internal/ssa/gen | |
parent | cdd08e615a9b92742b21a94443720b6d70452510 (diff) | |
download | go-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.go | 8 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/genericOps.go | 27 |
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. |