cmd/compile: intrinsify runtime.getcallersp

Add a compiler intrinsic for getcallersp. So we are able to get
rid of the argument (not done in this CL).

Change-Id: Ic38fda1c694f918328659ab44654198fb116668d
Reviewed-on: https://go-review.googlesource.com/69350
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cherry Zhang 2017-10-09 15:33:29 -04:00
parent ae175f74cb
commit 6f3e5e637c
37 changed files with 296 additions and 11 deletions

View File

@ -804,6 +804,19 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
case ssa.OpAMD64LoweredGetCallerSP:
// caller's SP is the address of the first arg
mov := x86.AMOVQ
if gc.Widthptr == 4 {
mov = x86.AMOVL
}
p := s.Prog(mov)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on amd64, just to be consistent with other architectures
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL, case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL, ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL: ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:

View File

@ -778,6 +778,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARMLoweredGetClosurePtr: case ssa.OpARMLoweredGetClosurePtr:
// Closure pointer is R7 (arm.REGCTXT). // Closure pointer is R7 (arm.REGCTXT).
gc.CheckLoweredGetClosurePtr(v) gc.CheckLoweredGetClosurePtr(v)
case ssa.OpARMLoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(arm.AMOVW)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpARMFlagEQ, case ssa.OpARMFlagEQ,
ssa.OpARMFlagLT_ULT, ssa.OpARMFlagLT_ULT,
ssa.OpARMFlagLT_UGT, ssa.OpARMFlagLT_UGT,

View File

@ -666,6 +666,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpARM64LoweredGetClosurePtr: case ssa.OpARM64LoweredGetClosurePtr:
// Closure pointer is R26 (arm64.REGCTXT). // Closure pointer is R26 (arm64.REGCTXT).
gc.CheckLoweredGetClosurePtr(v) gc.CheckLoweredGetClosurePtr(v)
case ssa.OpARM64LoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(arm64.AMOVD)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpARM64FlagEQ, case ssa.OpARM64FlagEQ,
ssa.OpARM64FlagLT_ULT, ssa.OpARM64FlagLT_ULT,
ssa.OpARM64FlagLT_UGT, ssa.OpARM64FlagLT_UGT,

View File

@ -1081,9 +1081,10 @@ func makefuncsym(s *types.Sym) {
if s.IsBlank() { if s.IsBlank() {
return return
} }
if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc") { if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
// runtime.getg(), getclosureptr(), and getcallerpc() are // runtime.getg(), getclosureptr(), getcallerpc(), and
// not real functions and so do not get funcsyms. // getcallersp() are not real functions and so do not
// get funcsyms.
return return
} }
if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed { if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {

View File

@ -2641,6 +2641,12 @@ func init() {
return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr) return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
}, sys.AMD64, sys.I386) }, sys.AMD64, sys.I386)
add("runtime", "getcallersp",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue0(ssa.OpGetCallerSP, s.f.Config.Types.Uintptr)
},
all...)
/******** runtime/internal/sys ********/ /******** runtime/internal/sys ********/
addF("runtime/internal/sys", "Ctz32", addF("runtime/internal/sys", "Ctz32",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value { func(s *state, n *Node, args []*ssa.Value) *ssa.Value {

View File

@ -755,6 +755,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpMIPSLoweredGetClosurePtr: case ssa.OpMIPSLoweredGetClosurePtr:
// Closure pointer is R22 (mips.REGCTXT). // Closure pointer is R22 (mips.REGCTXT).
gc.CheckLoweredGetClosurePtr(v) gc.CheckLoweredGetClosurePtr(v)
case ssa.OpMIPSLoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(mips.AMOVW)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpClobber: case ssa.OpClobber:
// TODO: implement for clobberdead experiment. Nop is ok for now. // TODO: implement for clobberdead experiment. Nop is ok for now.
default: default:

View File

@ -520,6 +520,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpMIPS64LoweredGetClosurePtr: case ssa.OpMIPS64LoweredGetClosurePtr:
// Closure pointer is R22 (mips.REGCTXT). // Closure pointer is R22 (mips.REGCTXT).
gc.CheckLoweredGetClosurePtr(v) gc.CheckLoweredGetClosurePtr(v)
case ssa.OpMIPS64LoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(mips.AMOVV)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpClobber: case ssa.OpClobber:
// TODO: implement for clobberdead experiment. Nop is ok for now. // TODO: implement for clobberdead experiment. Nop is ok for now.
default: default:

View File

@ -422,6 +422,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
// Closure pointer is R11 (already) // Closure pointer is R11 (already)
gc.CheckLoweredGetClosurePtr(v) gc.CheckLoweredGetClosurePtr(v)
case ssa.OpPPC64LoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(ppc64.AMOVD)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpPPC64LoweredRound32F, ssa.OpPPC64LoweredRound64F: case ssa.OpPPC64LoweredRound32F, ssa.OpPPC64LoweredRound64F:
// input is already rounded // input is already rounded

View File

@ -489,6 +489,14 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.From.Reg = s390x.REGG p.From.Reg = s390x.REGG
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = r
case ssa.OpS390XLoweredGetCallerSP:
// caller's SP is FixedFrameSize below the address of the first arg
p := s.Prog(s390x.AMOVD)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize()
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.OpS390XCALLstatic, ssa.OpS390XCALLclosure, ssa.OpS390XCALLinter: case ssa.OpS390XCALLstatic, ssa.OpS390XCALLclosure, ssa.OpS390XCALLinter:
s.Call(v) s.Call(v)
case ssa.OpS390XFLOGR, ssa.OpS390XNEG, ssa.OpS390XNEGW, case ssa.OpS390XFLOGR, ssa.OpS390XNEG, ssa.OpS390XNEGW,

View File

@ -384,6 +384,7 @@
(GetG mem) -> (LoweredGetG mem) (GetG mem) -> (LoweredGetG mem)
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerPC) -> (LoweredGetCallerPC) (GetCallerPC) -> (LoweredGetCallerPC)
(GetCallerSP) -> (LoweredGetCallerSP)
(Addr {sym} base) -> (LEAL {sym} base) (Addr {sym} base) -> (LEAL {sym} base)
// block rewrites // block rewrites

View File

@ -445,6 +445,8 @@ func init() {
// the result should be the PC within f that g will return to. // the result should be the PC within f that g will return to.
// See runtime/stubs.go for a more detailed discussion. // See runtime/stubs.go for a more detailed discussion.
{name: "LoweredGetCallerPC", reg: gp01}, {name: "LoweredGetCallerPC", reg: gp01},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},

View File

@ -483,6 +483,7 @@
(GetG mem) -> (LoweredGetG mem) (GetG mem) -> (LoweredGetG mem)
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerPC) -> (LoweredGetCallerPC) (GetCallerPC) -> (LoweredGetCallerPC)
(GetCallerSP) -> (LoweredGetCallerSP)
(Addr {sym} base) && config.PtrSize == 8 -> (LEAQ {sym} base) (Addr {sym} base) && config.PtrSize == 8 -> (LEAQ {sym} base)
(Addr {sym} base) && config.PtrSize == 4 -> (LEAL {sym} base) (Addr {sym} base) && config.PtrSize == 4 -> (LEAL {sym} base)

View File

@ -556,6 +556,8 @@ func init() {
// the result should be the PC within f that g will return to. // the result should be the PC within f that g will return to.
// See runtime/stubs.go for a more detailed discussion. // See runtime/stubs.go for a more detailed discussion.
{name: "LoweredGetCallerPC", reg: gp01}, {name: "LoweredGetCallerPC", reg: gp01},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},

View File

@ -398,6 +398,7 @@
// pseudo-ops // pseudo-ops
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(Convert x mem) -> (MOVWconvert x mem) (Convert x mem) -> (MOVWconvert x mem)
// Absorb pseudo-ops into blocks. // Absorb pseudo-ops into blocks.

View File

@ -467,6 +467,7 @@
// pseudo-ops // pseudo-ops
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(Convert x mem) -> (MOVDconvert x mem) (Convert x mem) -> (MOVDconvert x mem)
// Absorb pseudo-ops into blocks. // Absorb pseudo-ops into blocks.

View File

@ -425,6 +425,9 @@ func init() {
// use of R26 (arm64.REGCTXT, the closure pointer) // use of R26 (arm64.REGCTXT, the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
// MOVDconvert converts between pointers and integers. // MOVDconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
// (particularly stack maps). It takes a memory arg so it // (particularly stack maps). It takes a memory arg so it

View File

@ -498,6 +498,9 @@ func init() {
// use of R7 (arm.REGCTXT, the closure pointer) // use of R7 (arm.REGCTXT, the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
// MOVWconvert converts between pointers and integers. // MOVWconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
// (particularly stack maps). It takes a memory arg so it // (particularly stack maps). It takes a memory arg so it

View File

@ -437,6 +437,7 @@
// pseudo-ops // pseudo-ops
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(Convert x mem) -> (MOVWconvert x mem) (Convert x mem) -> (MOVWconvert x mem)
(If cond yes no) -> (NE cond yes no) (If cond yes no) -> (NE cond yes no)

View File

@ -427,6 +427,7 @@
// pseudo-ops // pseudo-ops
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(Convert x mem) -> (MOVVconvert x mem) (Convert x mem) -> (MOVVconvert x mem)
(If cond yes no) -> (NE cond yes no) (If cond yes no) -> (NE cond yes no)

View File

@ -344,6 +344,9 @@ func init() {
// use of R22 (mips.REGCTXT, the closure pointer) // use of R22 (mips.REGCTXT, the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
// MOVDconvert converts between pointers and integers. // MOVDconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
// (particularly stack maps). It takes a memory arg so it // (particularly stack maps). It takes a memory arg so it

View File

@ -376,6 +376,9 @@ func init() {
// use of R22 (mips.REGCTXT, the closure pointer) // use of R22 (mips.REGCTXT, the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
// MOVWconvert converts between pointers and integers. // MOVWconvert converts between pointers and integers.
// We have a special op for this so as to not confuse GC // We have a special op for this so as to not confuse GC
// (particularly stack maps). It takes a memory arg so it // (particularly stack maps). It takes a memory arg so it

View File

@ -643,6 +643,7 @@
// Miscellaneous // Miscellaneous
(Convert <t> x mem) -> (MOVDconvert <t> x mem) (Convert <t> x mem) -> (MOVDconvert <t> x mem)
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr)) (IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr))
(IsInBounds idx len) -> (LessThan (CMPU idx len)) (IsInBounds idx len) -> (LessThan (CMPU idx len))
(IsSliceInBounds idx len) -> (LessEqual (CMPU idx len)) (IsSliceInBounds idx len) -> (LessEqual (CMPU idx len))

View File

@ -315,6 +315,9 @@ func init() {
// use of the closure pointer. // use of the closure pointer.
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}},
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. //arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// Round ops to block fused-multiply-add extraction. // Round ops to block fused-multiply-add extraction.

View File

@ -427,6 +427,7 @@
(NilCheck ptr mem) -> (LoweredNilCheck ptr mem) (NilCheck ptr mem) -> (LoweredNilCheck ptr mem)
(GetG mem) -> (LoweredGetG mem) (GetG mem) -> (LoweredGetG mem)
(GetClosurePtr) -> (LoweredGetClosurePtr) (GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
(Addr {sym} base) -> (MOVDaddr {sym} base) (Addr {sym} base) -> (MOVDaddr {sym} base)
(ITab (Load ptr mem)) -> (MOVDload ptr mem) (ITab (Load ptr mem)) -> (MOVDload ptr mem)

View File

@ -439,6 +439,8 @@ func init() {
// use of R12 (the closure pointer) // use of R12 (the closure pointer)
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}}, {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}},
// arg0=ptr,arg1=mem, returns void. Faults if ptr is nil. // arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true}, {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
// Round ops to block fused-multiply-add extraction. // Round ops to block fused-multiply-add extraction.
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true}, {name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true},

View File

@ -379,6 +379,7 @@ var genericOps = []opData{
{name: "GetG", argLength: 1}, // runtime.getg() (read g pointer). arg0=mem {name: "GetG", argLength: 1}, // runtime.getg() (read g pointer). arg0=mem
{name: "GetClosurePtr"}, // get closure pointer from dedicated register {name: "GetClosurePtr"}, // get closure pointer from dedicated register
{name: "GetCallerPC"}, // for getcallerpc intrinsic {name: "GetCallerPC"}, // for getcallerpc intrinsic
{name: "GetCallerSP"}, // for getcallersp intrinsic
// Indexing operations // Indexing operations
{name: "PtrIndex", argLength: 2}, // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type {name: "PtrIndex", argLength: 2}, // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type

View File

@ -397,6 +397,7 @@ const (
Op386LoweredGetG Op386LoweredGetG
Op386LoweredGetClosurePtr Op386LoweredGetClosurePtr
Op386LoweredGetCallerPC Op386LoweredGetCallerPC
Op386LoweredGetCallerSP
Op386LoweredNilCheck Op386LoweredNilCheck
Op386MOVLconvert Op386MOVLconvert
Op386FlagEQ Op386FlagEQ
@ -665,6 +666,7 @@ const (
OpAMD64LoweredGetG OpAMD64LoweredGetG
OpAMD64LoweredGetClosurePtr OpAMD64LoweredGetClosurePtr
OpAMD64LoweredGetCallerPC OpAMD64LoweredGetCallerPC
OpAMD64LoweredGetCallerSP
OpAMD64LoweredNilCheck OpAMD64LoweredNilCheck
OpAMD64MOVQconvert OpAMD64MOVQconvert
OpAMD64MOVLconvert OpAMD64MOVLconvert
@ -918,6 +920,7 @@ const (
OpARMLoweredZero OpARMLoweredZero
OpARMLoweredMove OpARMLoweredMove
OpARMLoweredGetClosurePtr OpARMLoweredGetClosurePtr
OpARMLoweredGetCallerSP
OpARMMOVWconvert OpARMMOVWconvert
OpARMFlagEQ OpARMFlagEQ
OpARMFlagLT_ULT OpARMFlagLT_ULT
@ -1083,6 +1086,7 @@ const (
OpARM64DUFFCOPY OpARM64DUFFCOPY
OpARM64LoweredMove OpARM64LoweredMove
OpARM64LoweredGetClosurePtr OpARM64LoweredGetClosurePtr
OpARM64LoweredGetCallerSP
OpARM64MOVDconvert OpARM64MOVDconvert
OpARM64FlagEQ OpARM64FlagEQ
OpARM64FlagLT_ULT OpARM64FlagLT_ULT
@ -1202,6 +1206,7 @@ const (
OpMIPSFPFlagTrue OpMIPSFPFlagTrue
OpMIPSFPFlagFalse OpMIPSFPFlagFalse
OpMIPSLoweredGetClosurePtr OpMIPSLoweredGetClosurePtr
OpMIPSLoweredGetCallerSP
OpMIPSMOVWconvert OpMIPSMOVWconvert
OpMIPS64ADDV OpMIPS64ADDV
@ -1298,6 +1303,7 @@ const (
OpMIPS64FPFlagTrue OpMIPS64FPFlagTrue
OpMIPS64FPFlagFalse OpMIPS64FPFlagFalse
OpMIPS64LoweredGetClosurePtr OpMIPS64LoweredGetClosurePtr
OpMIPS64LoweredGetCallerSP
OpMIPS64MOVVconvert OpMIPS64MOVVconvert
OpPPC64ADD OpPPC64ADD
@ -1421,6 +1427,7 @@ const (
OpPPC64GreaterEqual OpPPC64GreaterEqual
OpPPC64FGreaterEqual OpPPC64FGreaterEqual
OpPPC64LoweredGetClosurePtr OpPPC64LoweredGetClosurePtr
OpPPC64LoweredGetCallerSP
OpPPC64LoweredNilCheck OpPPC64LoweredNilCheck
OpPPC64LoweredRound32F OpPPC64LoweredRound32F
OpPPC64LoweredRound64F OpPPC64LoweredRound64F
@ -1624,6 +1631,7 @@ const (
OpS390XInvertFlags OpS390XInvertFlags
OpS390XLoweredGetG OpS390XLoweredGetG
OpS390XLoweredGetClosurePtr OpS390XLoweredGetClosurePtr
OpS390XLoweredGetCallerSP
OpS390XLoweredNilCheck OpS390XLoweredNilCheck
OpS390XLoweredRound32F OpS390XLoweredRound32F
OpS390XLoweredRound64F OpS390XLoweredRound64F
@ -1918,6 +1926,7 @@ const (
OpGetG OpGetG
OpGetClosurePtr OpGetClosurePtr
OpGetCallerPC OpGetCallerPC
OpGetCallerSP
OpPtrIndex OpPtrIndex
OpOffPtr OpOffPtr
OpSliceMake OpSliceMake
@ -4308,6 +4317,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 239}, // AX CX DX BX BP SI DI
},
},
},
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
@ -8075,6 +8094,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
@ -11598,6 +11627,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{ {
name: "MOVWconvert", name: "MOVWconvert",
argLen: 2, argLen: 2,
@ -13743,6 +13782,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
},
},
},
{ {
name: "MOVDconvert", name: "MOVDconvert",
argLen: 2, argLen: 2,
@ -15321,6 +15370,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31
},
},
},
{ {
name: "MOVWconvert", name: "MOVWconvert",
argLen: 2, argLen: 2,
@ -16614,6 +16673,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
},
},
},
{ {
name: "MOVVconvert", name: "MOVVconvert",
argLen: 2, argLen: 2,
@ -18238,6 +18307,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
},
},
},
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
@ -21200,6 +21279,16 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "LoweredGetCallerSP",
argLen: 0,
rematerializeable: true,
reg: regInfo{
outputs: []outputInfo{
{0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
},
},
},
{ {
name: "LoweredNilCheck", name: "LoweredNilCheck",
argLen: 2, argLen: 2,
@ -23000,6 +23089,11 @@ var opcodeTable = [...]opInfo{
argLen: 0, argLen: 0,
generic: true, generic: true,
}, },
{
name: "GetCallerSP",
argLen: 0,
generic: true,
},
{ {
name: "PtrIndex", name: "PtrIndex",
argLen: 2, argLen: 2,

View File

@ -331,6 +331,8 @@ func rewriteValue386(v *Value) bool {
return rewriteValue386_OpGeq8U_0(v) return rewriteValue386_OpGeq8U_0(v)
case OpGetCallerPC: case OpGetCallerPC:
return rewriteValue386_OpGetCallerPC_0(v) return rewriteValue386_OpGetCallerPC_0(v)
case OpGetCallerSP:
return rewriteValue386_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValue386_OpGetClosurePtr_0(v) return rewriteValue386_OpGetClosurePtr_0(v)
case OpGetG: case OpGetG:
@ -15049,6 +15051,15 @@ func rewriteValue386_OpGetCallerPC_0(v *Value) bool {
return true return true
} }
} }
func rewriteValue386_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(Op386LoweredGetCallerSP)
return true
}
}
func rewriteValue386_OpGetClosurePtr_0(v *Value) bool { func rewriteValue386_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -585,6 +585,8 @@ func rewriteValueAMD64(v *Value) bool {
return rewriteValueAMD64_OpGeq8U_0(v) return rewriteValueAMD64_OpGeq8U_0(v)
case OpGetCallerPC: case OpGetCallerPC:
return rewriteValueAMD64_OpGetCallerPC_0(v) return rewriteValueAMD64_OpGetCallerPC_0(v)
case OpGetCallerSP:
return rewriteValueAMD64_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueAMD64_OpGetClosurePtr_0(v) return rewriteValueAMD64_OpGetClosurePtr_0(v)
case OpGetG: case OpGetG:
@ -41967,6 +41969,15 @@ func rewriteValueAMD64_OpGetCallerPC_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueAMD64_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpAMD64LoweredGetCallerSP)
return true
}
}
func rewriteValueAMD64_OpGetClosurePtr_0(v *Value) bool { func rewriteValueAMD64_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -503,6 +503,8 @@ func rewriteValueARM(v *Value) bool {
return rewriteValueARM_OpGeq8_0(v) return rewriteValueARM_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValueARM_OpGeq8U_0(v) return rewriteValueARM_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValueARM_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueARM_OpGetClosurePtr_0(v) return rewriteValueARM_OpGetClosurePtr_0(v)
case OpGreater16: case OpGreater16:
@ -16748,6 +16750,15 @@ func rewriteValueARM_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueARM_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpARMLoweredGetCallerSP)
return true
}
}
func rewriteValueARM_OpGetClosurePtr_0(v *Value) bool { func rewriteValueARM_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -399,6 +399,8 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpGeq8_0(v) return rewriteValueARM64_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValueARM64_OpGeq8U_0(v) return rewriteValueARM64_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValueARM64_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueARM64_OpGetClosurePtr_0(v) return rewriteValueARM64_OpGetClosurePtr_0(v)
case OpGreater16: case OpGreater16:
@ -11846,6 +11848,15 @@ func rewriteValueARM64_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueARM64_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpARM64LoweredGetCallerSP)
return true
}
}
func rewriteValueARM64_OpGetClosurePtr_0(v *Value) bool { func rewriteValueARM64_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -145,6 +145,8 @@ func rewriteValueMIPS(v *Value) bool {
return rewriteValueMIPS_OpGeq8_0(v) return rewriteValueMIPS_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValueMIPS_OpGeq8U_0(v) return rewriteValueMIPS_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValueMIPS_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueMIPS_OpGetClosurePtr_0(v) return rewriteValueMIPS_OpGetClosurePtr_0(v)
case OpGreater16: case OpGreater16:
@ -1759,6 +1761,15 @@ func rewriteValueMIPS_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueMIPS_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpMIPSLoweredGetCallerSP)
return true
}
}
func rewriteValueMIPS_OpGetClosurePtr_0(v *Value) bool { func rewriteValueMIPS_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -147,6 +147,8 @@ func rewriteValueMIPS64(v *Value) bool {
return rewriteValueMIPS64_OpGeq8_0(v) return rewriteValueMIPS64_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValueMIPS64_OpGeq8U_0(v) return rewriteValueMIPS64_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValueMIPS64_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueMIPS64_OpGetClosurePtr_0(v) return rewriteValueMIPS64_OpGetClosurePtr_0(v)
case OpGreater16: case OpGreater16:
@ -1719,6 +1721,15 @@ func rewriteValueMIPS64_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueMIPS64_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpMIPS64LoweredGetCallerSP)
return true
}
}
func rewriteValueMIPS64_OpGetClosurePtr_0(v *Value) bool { func rewriteValueMIPS64_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -185,6 +185,8 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpGeq8_0(v) return rewriteValuePPC64_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValuePPC64_OpGeq8U_0(v) return rewriteValuePPC64_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValuePPC64_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValuePPC64_OpGetClosurePtr_0(v) return rewriteValuePPC64_OpGetClosurePtr_0(v)
case OpGreater16: case OpGreater16:
@ -2051,6 +2053,15 @@ func rewriteValuePPC64_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValuePPC64_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpPPC64LoweredGetCallerSP)
return true
}
}
func rewriteValuePPC64_OpGetClosurePtr_0(v *Value) bool { func rewriteValuePPC64_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -185,6 +185,8 @@ func rewriteValueS390X(v *Value) bool {
return rewriteValueS390X_OpGeq8_0(v) return rewriteValueS390X_OpGeq8_0(v)
case OpGeq8U: case OpGeq8U:
return rewriteValueS390X_OpGeq8U_0(v) return rewriteValueS390X_OpGeq8U_0(v)
case OpGetCallerSP:
return rewriteValueS390X_OpGetCallerSP_0(v)
case OpGetClosurePtr: case OpGetClosurePtr:
return rewriteValueS390X_OpGetClosurePtr_0(v) return rewriteValueS390X_OpGetClosurePtr_0(v)
case OpGetG: case OpGetG:
@ -2219,6 +2221,15 @@ func rewriteValueS390X_OpGeq8U_0(v *Value) bool {
return true return true
} }
} }
func rewriteValueS390X_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
// result: (LoweredGetCallerSP)
for {
v.reset(OpS390XLoweredGetCallerSP)
return true
}
}
func rewriteValueS390X_OpGetClosurePtr_0(v *Value) bool { func rewriteValueS390X_OpGetClosurePtr_0(v *Value) bool {
// match: (GetClosurePtr) // match: (GetClosurePtr)
// cond: // cond:

View File

@ -675,6 +675,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg() p.To.Reg = v.Reg()
case ssa.Op386LoweredGetCallerSP:
// caller's SP is the address of the first arg
p := s.Prog(x86.AMOVL)
p.From.Type = obj.TYPE_ADDR
p.From.Offset = -gc.Ctxt.FixedFrameSize() // 0 on 386, just to be consistent with other architectures
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter: case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
s.Call(v) s.Call(v)
case ssa.Op386NEGL, case ssa.Op386NEGL,

View File

@ -4,10 +4,7 @@
package runtime package runtime
import ( import "unsafe"
"runtime/internal/sys"
"unsafe"
)
// Should be a built-in for unsafe.Pointer? // Should be a built-in for unsafe.Pointer?
//go:nosplit //go:nosplit
@ -229,10 +226,8 @@ func publicationBarrier()
//go:noescape //go:noescape
func getcallerpc() uintptr func getcallerpc() uintptr
//go:nosplit //go:noescape
func getcallersp(argp unsafe.Pointer) uintptr { func getcallersp(argp unsafe.Pointer) uintptr // implemented as an intrinsic on all platforms
return uintptr(argp) - sys.MinFrameSize
}
// getclosureptr returns the pointer to the current closure. // getclosureptr returns the pointer to the current closure.
// getclosureptr can only be used in an assignment statement // getclosureptr can only be used in an assignment statement