Add a compiler intrinsic for getcallerpc on arm64 for better code generation.
Change-Id: I897e670a2b8ffa1a8c2fdc638f5b2c44bda26318
Reviewed-on: https://go-review.googlesource.com/109276
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
case 0:
// Nothing to do.
case 1:
- if p.arch.UnaryDst[op] || op == obj.ARET {
+ if p.arch.UnaryDst[op] || op == obj.ARET || op == obj.AGETCALLERPC {
// prog.From is no address.
prog.To = a[0]
} else {
p.From.Name = obj.NAME_PARAM
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
+ case ssa.OpARM64LoweredGetCallerPC:
+ p := s.Prog(obj.AGETCALLERPC)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = v.Reg()
case ssa.OpARM64FlagEQ,
ssa.OpARM64FlagLT_ULT,
ssa.OpARM64FlagLT_UGT,
addF("runtime", "getcallerpc",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
- }, sys.AMD64, sys.I386)
+ }, sys.AMD64, sys.I386, sys.ARM64)
add("runtime", "getcallersp",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
// pseudo-ops
(GetClosurePtr) -> (LoweredGetClosurePtr)
(GetCallerSP) -> (LoweredGetCallerSP)
+(GetCallerPC) -> (LoweredGetCallerPC)
// Absorb pseudo-ops into blocks.
(If (Equal cc) yes no) -> (EQ cc yes no)
// LoweredGetCallerSP returns the SP of the caller of the current function.
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+ // LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+ // I.e., if f calls g "calls" getcallerpc,
+ // the result should be the PC within f that g will return to.
+ // See runtime/stubs.go for a more detailed discussion.
+ {name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
// Constant flag values. For any comparison, there are 5 possible
// outcomes: the three from the signed total order (<,==,>) and the
// three from the unsigned total order. The == cases overlap.
OpARM64LoweredMove
OpARM64LoweredGetClosurePtr
OpARM64LoweredGetCallerSP
+ OpARM64LoweredGetCallerPC
OpARM64FlagEQ
OpARM64FlagLT_ULT
OpARM64FlagLT_UGT
},
},
},
+ {
+ name: "LoweredGetCallerPC",
+ 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: "FlagEQ",
argLen: 0,
return rewriteValueARM64_OpGeq8_0(v)
case OpGeq8U:
return rewriteValueARM64_OpGeq8U_0(v)
+ case OpGetCallerPC:
+ return rewriteValueARM64_OpGetCallerPC_0(v)
case OpGetCallerSP:
return rewriteValueARM64_OpGetCallerSP_0(v)
case OpGetClosurePtr:
return true
}
}
+func rewriteValueARM64_OpGetCallerPC_0(v *Value) bool {
+ // match: (GetCallerPC)
+ // cond:
+ // result: (LoweredGetCallerPC)
+ for {
+ v.reset(OpARM64LoweredGetCallerPC)
+ return true
+ }
+}
func rewriteValueARM64_OpGetCallerSP_0(v *Value) bool {
// match: (GetCallerSP)
// cond:
}
}
break
+
+ case obj.AGETCALLERPC:
+ if cursym.Leaf() {
+ /* MOVD LR, Rd */
+ p.As = AMOVD
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = REGLINK
+ } else {
+ /* MOVD (RSP), Rd */
+ p.As = AMOVD
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = REGSP
+ }
}
}
}
ANOP
APCDATA
ARET
+ AGETCALLERPC
ATEXT
AUNDEF
A_ARCHSPECIFIC
"NOP",
"PCDATA",
"RET",
+ "GETCALLERPC",
"TEXT",
"UNDEF",
}
MOVD savedR27-8(SP), R27
RET
-TEXT runtime·getcallerpc(SB),NOSPLIT|NOFRAME,$0-8
- MOVD 0(RSP), R0 // LR saved by caller
- MOVD R0, ret+0(FP)
- RET
-
TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
MOVD ZR, R0
MOVD (R0), R0