]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: intrinsify runtime.getcallerpc on arm64
authorWei Xiao <wei.xiao@arm.com>
Wed, 25 Apr 2018 08:38:09 +0000 (08:38 +0000)
committerCherry Zhang <cherryyz@google.com>
Mon, 30 Apr 2018 13:29:14 +0000 (13:29 +0000)
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>

src/cmd/asm/internal/asm/asm.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/ARM64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/internal/obj/arm64/obj7.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/util.go
src/runtime/asm_arm64.s

index 6261aa843ba903f56d5d4564ee8c2fe3543484e9..b2d5a75ac46df444675e0c464439d655dba2706e 100644 (file)
@@ -486,7 +486,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
        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 {
index 017c5b9398862fd3df485d5d746001e34054af84..4459596e24354019605fe768dc736c7c6068b904 100644 (file)
@@ -835,6 +835,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                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,
index 3ebf41fa0cc805cdaf3e1e9be3ec1974421867ed..f473fa8218011e1925b211d32426483690eefcc1 100644 (file)
@@ -2833,7 +2833,7 @@ func init() {
        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 {
index d713fd8fda853b505294cbe1f5ee6dd72a249aad..b5eeb96468367375d2530bd2421d1b17792dca99 100644 (file)
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
+(GetCallerPC) -> (LoweredGetCallerPC)
 
 // Absorb pseudo-ops into blocks.
 (If (Equal cc) yes no) -> (EQ cc yes no)
index 3f821e1ce9b05d9456a319d2794fd6026899923d..b54de53f59334d8daf3d85ccdc29f333ab62514f 100644 (file)
@@ -527,6 +527,12 @@ func init() {
                // 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.
index d8e6836d95e6ff5609a38a12ce14c83390da1a47..669d3f57683400e122dc5b46e197b05d52eefb2e 100644 (file)
@@ -1253,6 +1253,7 @@ const (
        OpARM64LoweredMove
        OpARM64LoweredGetClosurePtr
        OpARM64LoweredGetCallerSP
+       OpARM64LoweredGetCallerPC
        OpARM64FlagEQ
        OpARM64FlagLT_ULT
        OpARM64FlagLT_UGT
@@ -16394,6 +16395,16 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               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,
index 62cffc1b06adbabc546a044b39ac58c7136d3bce..f5380111983a471c515358cd685ce090eb788327 100644 (file)
@@ -515,6 +515,8 @@ func rewriteValueARM64(v *Value) bool {
                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:
@@ -27239,6 +27241,15 @@ func rewriteValueARM64_OpGeq8U_0(v *Value) bool {
                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:
index fe33b91820af8be6ab79506e02771c24e91c22ee..0ea9af285471d08c748426a9c8f57e1f35f314bb 100644 (file)
@@ -821,6 +821,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                }
                        }
                        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
+                       }
                }
        }
 }
index 16e4e1410d582452d3d89ed68d265184254920f0..ea1129400059e78d1386b3ca1228e827d202e32b 100644 (file)
@@ -343,6 +343,7 @@ const (
        ANOP
        APCDATA
        ARET
+       AGETCALLERPC
        ATEXT
        AUNDEF
        A_ARCHSPECIFIC
index 3b92dfcba37e6fb70de4ff2f077bf7920723cb59..89d481e726b1fd6d19ab4fbb6601dccf8adfa071 100644 (file)
@@ -493,6 +493,7 @@ var Anames = []string{
        "NOP",
        "PCDATA",
        "RET",
+       "GETCALLERPC",
        "TEXT",
        "UNDEF",
 }
index 1e0d71ab3b5f41db79a47d48ed372c7d1a783fe3..2319b82255cd09bbf81295447d121633f33b504a 100644 (file)
@@ -1069,11 +1069,6 @@ TEXT setg_gcc<>(SB),NOSPLIT,$8
        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