mirror of
https://github.com/golang/go.git
synced 2026-02-07 02:09:55 +00:00
cmd/compile: move arm32 over to new bounds check strategy
Change-Id: I529edd805875a4833cabcf4692f0c6d4163b07d2 Reviewed-on: https://go-review.googlesource.com/c/go/+/682398 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
d79405a344
commit
7dccd6395c
6 changed files with 430 additions and 358 deletions
|
|
@ -18,6 +18,7 @@ import (
|
|||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/arm"
|
||||
"internal/abi"
|
||||
)
|
||||
|
||||
// loadByType returns the load instruction of the given type.
|
||||
|
|
@ -712,18 +713,167 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
|||
p.To.Name = obj.NAME_EXTERN
|
||||
// AuxInt encodes how many buffer entries we need.
|
||||
p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
|
||||
case ssa.OpARMLoweredPanicBoundsA, ssa.OpARMLoweredPanicBoundsB, ssa.OpARMLoweredPanicBoundsC:
|
||||
p := s.Prog(obj.ACALL)
|
||||
|
||||
case ssa.OpARMLoweredPanicBoundsRR, ssa.OpARMLoweredPanicBoundsRC, ssa.OpARMLoweredPanicBoundsCR, ssa.OpARMLoweredPanicBoundsCC,
|
||||
ssa.OpARMLoweredPanicExtendRR, ssa.OpARMLoweredPanicExtendRC:
|
||||
// Compute the constant we put in the PCData entry for this call.
|
||||
code, signed := ssa.BoundsKind(v.AuxInt).Code()
|
||||
xIsReg := false
|
||||
yIsReg := false
|
||||
xVal := 0
|
||||
yVal := 0
|
||||
extend := false
|
||||
switch v.Op {
|
||||
case ssa.OpARMLoweredPanicBoundsRR:
|
||||
xIsReg = true
|
||||
xVal = int(v.Args[0].Reg() - arm.REG_R0)
|
||||
yIsReg = true
|
||||
yVal = int(v.Args[1].Reg() - arm.REG_R0)
|
||||
case ssa.OpARMLoweredPanicExtendRR:
|
||||
extend = true
|
||||
xIsReg = true
|
||||
hi := int(v.Args[0].Reg() - arm.REG_R0)
|
||||
lo := int(v.Args[1].Reg() - arm.REG_R0)
|
||||
xVal = hi<<2 + lo // encode 2 register numbers
|
||||
yIsReg = true
|
||||
yVal = int(v.Args[2].Reg() - arm.REG_R0)
|
||||
case ssa.OpARMLoweredPanicBoundsRC:
|
||||
xIsReg = true
|
||||
xVal = int(v.Args[0].Reg() - arm.REG_R0)
|
||||
c := v.Aux.(ssa.PanicBoundsC).C
|
||||
if c >= 0 && c <= abi.BoundsMaxConst {
|
||||
yVal = int(c)
|
||||
} else {
|
||||
// Move constant to a register
|
||||
yIsReg = true
|
||||
if yVal == xVal {
|
||||
yVal = 1
|
||||
}
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(yVal)
|
||||
}
|
||||
case ssa.OpARMLoweredPanicExtendRC:
|
||||
extend = true
|
||||
xIsReg = true
|
||||
hi := int(v.Args[0].Reg() - arm.REG_R0)
|
||||
lo := int(v.Args[1].Reg() - arm.REG_R0)
|
||||
xVal = hi<<2 + lo // encode 2 register numbers
|
||||
c := v.Aux.(ssa.PanicBoundsC).C
|
||||
if c >= 0 && c <= abi.BoundsMaxConst {
|
||||
yVal = int(c)
|
||||
} else {
|
||||
// Move constant to a register
|
||||
for yVal == hi || yVal == lo {
|
||||
yVal++
|
||||
}
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(yVal)
|
||||
}
|
||||
case ssa.OpARMLoweredPanicBoundsCR:
|
||||
yIsReg = true
|
||||
yVal := int(v.Args[0].Reg() - arm.REG_R0)
|
||||
c := v.Aux.(ssa.PanicBoundsC).C
|
||||
if c >= 0 && c <= abi.BoundsMaxConst {
|
||||
xVal = int(c)
|
||||
} else if signed && int64(int32(c)) == c || !signed && int64(uint32(c)) == c {
|
||||
// Move constant to a register
|
||||
xIsReg = true
|
||||
if xVal == yVal {
|
||||
xVal = 1
|
||||
}
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(xVal)
|
||||
} else {
|
||||
// Move constant to two registers
|
||||
extend = true
|
||||
xIsReg = true
|
||||
hi := 0
|
||||
lo := 1
|
||||
if hi == yVal {
|
||||
hi = 2
|
||||
}
|
||||
if lo == yVal {
|
||||
lo = 2
|
||||
}
|
||||
xVal = hi<<2 + lo
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c >> 32
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(hi)
|
||||
p = s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(int32(c))
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(lo)
|
||||
}
|
||||
case ssa.OpARMLoweredPanicBoundsCC:
|
||||
c := v.Aux.(ssa.PanicBoundsCC).Cx
|
||||
if c >= 0 && c <= abi.BoundsMaxConst {
|
||||
xVal = int(c)
|
||||
} else if signed && int64(int32(c)) == c || !signed && int64(uint32(c)) == c {
|
||||
// Move constant to a register
|
||||
xIsReg = true
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(xVal)
|
||||
} else {
|
||||
// Move constant to two registers
|
||||
extend = true
|
||||
xIsReg = true
|
||||
hi := 0
|
||||
lo := 1
|
||||
xVal = hi<<2 + lo
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c >> 32
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(hi)
|
||||
p = s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(int32(c))
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(lo)
|
||||
}
|
||||
c = v.Aux.(ssa.PanicBoundsCC).Cy
|
||||
if c >= 0 && c <= abi.BoundsMaxConst {
|
||||
yVal = int(c)
|
||||
} else {
|
||||
// Move constant to a register
|
||||
yIsReg = true
|
||||
yVal = 2
|
||||
p := s.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = c
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = arm.REG_R0 + int16(yVal)
|
||||
}
|
||||
}
|
||||
c := abi.BoundsEncode(code, signed, xIsReg, yIsReg, xVal, yVal)
|
||||
|
||||
p := s.Prog(obj.APCDATA)
|
||||
p.From.SetConst(abi.PCDATA_PanicBounds)
|
||||
p.To.SetConst(int64(c))
|
||||
p = s.Prog(obj.ACALL)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
|
||||
s.UseArgs(8) // space used in callee args area by assembly stubs
|
||||
case ssa.OpARMLoweredPanicExtendA, ssa.OpARMLoweredPanicExtendB, ssa.OpARMLoweredPanicExtendC:
|
||||
p := s.Prog(obj.ACALL)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = ssagen.ExtendCheckFunc[v.AuxInt]
|
||||
s.UseArgs(12) // space used in callee args area by assembly stubs
|
||||
if extend {
|
||||
p.To.Sym = ir.Syms.PanicExtend
|
||||
} else {
|
||||
p.To.Sym = ir.Syms.PanicBounds
|
||||
}
|
||||
|
||||
case ssa.OpARMDUFFZERO:
|
||||
p := s.Prog(obj.ADUFFZERO)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
|
|
|
|||
|
|
@ -395,13 +395,16 @@
|
|||
// Write barrier.
|
||||
(WB ...) => (LoweredWB ...)
|
||||
|
||||
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
|
||||
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
|
||||
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
|
||||
(PanicBounds ...) => (LoweredPanicBoundsRR ...)
|
||||
(PanicExtend ...) => (LoweredPanicExtendRR ...)
|
||||
|
||||
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
|
||||
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
|
||||
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
|
||||
(LoweredPanicBoundsRR [kind] x (MOVWconst [c]) mem) => (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:int64(c)}} mem)
|
||||
(LoweredPanicBoundsRR [kind] (MOVWconst [c]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(c)}} y mem)
|
||||
(LoweredPanicBoundsRC [kind] {p} (MOVWconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(c), Cy:p.C}} mem)
|
||||
|
||||
(LoweredPanicExtendRR [kind] hi lo (MOVWconst [c]) mem) => (LoweredPanicExtendRC [kind] hi lo {PanicBoundsC{C:int64(c)}} mem)
|
||||
(LoweredPanicExtendRR [kind] (MOVWconst [hi]) (MOVWconst [lo]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(hi)<<32 + int64(uint32(lo))}} y mem)
|
||||
(LoweredPanicExtendRC [kind] {p} (MOVWconst [hi]) (MOVWconst [lo]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(hi)<<32+int64(uint32(lo)), Cy:p.C}} mem)
|
||||
|
||||
// Optimizations
|
||||
|
||||
|
|
|
|||
|
|
@ -94,11 +94,11 @@ func init() {
|
|||
gpspsbg = gpspg | buildReg("SB")
|
||||
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
|
||||
callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
|
||||
lr = buildReg("R14")
|
||||
r0 = buildReg("R0")
|
||||
r1 = buildReg("R1")
|
||||
r2 = buildReg("R2")
|
||||
r3 = buildReg("R3")
|
||||
r4 = buildReg("R4")
|
||||
)
|
||||
// Common regInfo
|
||||
var (
|
||||
|
|
@ -540,16 +540,19 @@ func init() {
|
|||
// See runtime/stubs.go for a more detailed discussion.
|
||||
{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
|
||||
|
||||
// There are three of these functions so that they can have three different register inputs.
|
||||
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
|
||||
// default registers to match so we don't need to copy registers around unnecessarily.
|
||||
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
|
||||
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
|
||||
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
|
||||
// Extend ops are the same as Bounds ops except the indexes are 64-bit.
|
||||
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
|
||||
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
|
||||
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r0, r1}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
|
||||
// LoweredPanicBoundsRR takes x and y, two values that caused a bounds check to fail.
|
||||
// the RC and CR versions are used when one of the arguments is a constant. CC is used
|
||||
// when both are constant (normally both 0, as prove derives the fact that a [0] bounds
|
||||
// failure means the length must have also been 0).
|
||||
// AuxInt contains a report code (see PanicBounds in genericOps.go).
|
||||
{name: "LoweredPanicBoundsRR", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{gp &^ lr, gp &^ lr}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
|
||||
{name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{gp &^ lr}}, typ: "Mem", call: true}, // arg0=x, arg1=mem, returns memory.
|
||||
{name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{gp &^ lr}}, typ: "Mem", call: true}, // arg0=y, arg1=mem, returns memory.
|
||||
{name: "LoweredPanicBoundsCC", argLength: 1, aux: "PanicBoundsCC", reg: regInfo{}, typ: "Mem", call: true}, // arg0=mem, returns memory.
|
||||
|
||||
// Same as above, but the x value is 64 bits.
|
||||
{name: "LoweredPanicExtendRR", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r0 | r1 | r2 | r3, r0 | r1 | r2 | r3, gp}}, typ: "Mem", call: true}, // arg0=x_hi, arg1=x_lo, arg2=y, arg3=mem, returns memory.
|
||||
{name: "LoweredPanicExtendRC", argLength: 3, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{r0 | r1 | r2 | r3, r0 | r1 | r2 | r3}}, typ: "Mem", call: true}, // arg0=x_hi, arg1=x_lo, arg2=mem, returns memory.
|
||||
|
||||
// Constant flag value.
|
||||
// Note: there's an "unordered" outcome for floating-point
|
||||
|
|
|
|||
|
|
@ -1422,12 +1422,12 @@ const (
|
|||
OpARMLoweredGetClosurePtr
|
||||
OpARMLoweredGetCallerSP
|
||||
OpARMLoweredGetCallerPC
|
||||
OpARMLoweredPanicBoundsA
|
||||
OpARMLoweredPanicBoundsB
|
||||
OpARMLoweredPanicBoundsC
|
||||
OpARMLoweredPanicExtendA
|
||||
OpARMLoweredPanicExtendB
|
||||
OpARMLoweredPanicExtendC
|
||||
OpARMLoweredPanicBoundsRR
|
||||
OpARMLoweredPanicBoundsRC
|
||||
OpARMLoweredPanicBoundsCR
|
||||
OpARMLoweredPanicBoundsCC
|
||||
OpARMLoweredPanicExtendRR
|
||||
OpARMLoweredPanicExtendRC
|
||||
OpARMFlagConstant
|
||||
OpARMInvertFlags
|
||||
OpARMLoweredWB
|
||||
|
|
@ -19111,77 +19111,68 @@ var opcodeTable = [...]opInfo{
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicBoundsA",
|
||||
name: "LoweredPanicBoundsRR",
|
||||
auxType: auxInt64,
|
||||
argLen: 3,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4}, // R2
|
||||
{1, 8}, // R3
|
||||
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
|
||||
{1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicBoundsB",
|
||||
name: "LoweredPanicBoundsRC",
|
||||
auxType: auxPanicBoundsC,
|
||||
argLen: 2,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicBoundsCR",
|
||||
auxType: auxPanicBoundsC,
|
||||
argLen: 2,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicBoundsCC",
|
||||
auxType: auxPanicBoundsCC,
|
||||
argLen: 1,
|
||||
call: true,
|
||||
reg: regInfo{},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicExtendRR",
|
||||
auxType: auxInt64,
|
||||
argLen: 4,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 15}, // R0 R1 R2 R3
|
||||
{1, 15}, // R0 R1 R2 R3
|
||||
{2, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicExtendRC",
|
||||
auxType: auxPanicBoundsC,
|
||||
argLen: 3,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 2}, // R1
|
||||
{1, 4}, // R2
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicBoundsC",
|
||||
auxType: auxInt64,
|
||||
argLen: 3,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 1}, // R0
|
||||
{1, 2}, // R1
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicExtendA",
|
||||
auxType: auxInt64,
|
||||
argLen: 4,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 16}, // R4
|
||||
{1, 4}, // R2
|
||||
{2, 8}, // R3
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicExtendB",
|
||||
auxType: auxInt64,
|
||||
argLen: 4,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 16}, // R4
|
||||
{1, 2}, // R1
|
||||
{2, 4}, // R2
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "LoweredPanicExtendC",
|
||||
auxType: auxInt64,
|
||||
argLen: 4,
|
||||
call: true,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 16}, // R4
|
||||
{1, 1}, // R0
|
||||
{2, 2}, // R1
|
||||
{0, 15}, // R0 R1 R2 R3
|
||||
{1, 15}, // R0 R1 R2 R3
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -151,6 +151,14 @@ func rewriteValueARM(v *Value) bool {
|
|||
return rewriteValueARM_OpARMLessThan(v)
|
||||
case OpARMLessThanU:
|
||||
return rewriteValueARM_OpARMLessThanU(v)
|
||||
case OpARMLoweredPanicBoundsRC:
|
||||
return rewriteValueARM_OpARMLoweredPanicBoundsRC(v)
|
||||
case OpARMLoweredPanicBoundsRR:
|
||||
return rewriteValueARM_OpARMLoweredPanicBoundsRR(v)
|
||||
case OpARMLoweredPanicExtendRC:
|
||||
return rewriteValueARM_OpARMLoweredPanicExtendRC(v)
|
||||
case OpARMLoweredPanicExtendRR:
|
||||
return rewriteValueARM_OpARMLoweredPanicExtendRR(v)
|
||||
case OpARMMOVBUload:
|
||||
return rewriteValueARM_OpARMMOVBUload(v)
|
||||
case OpARMMOVBUloadidx:
|
||||
|
|
@ -745,9 +753,11 @@ func rewriteValueARM(v *Value) bool {
|
|||
v.Op = OpARMOR
|
||||
return true
|
||||
case OpPanicBounds:
|
||||
return rewriteValueARM_OpPanicBounds(v)
|
||||
v.Op = OpARMLoweredPanicBoundsRR
|
||||
return true
|
||||
case OpPanicExtend:
|
||||
return rewriteValueARM_OpPanicExtend(v)
|
||||
v.Op = OpARMLoweredPanicExtendRR
|
||||
return true
|
||||
case OpRotateLeft16:
|
||||
return rewriteValueARM_OpRotateLeft16(v)
|
||||
case OpRotateLeft32:
|
||||
|
|
@ -4548,6 +4558,135 @@ func rewriteValueARM_OpARMLessThanU(v *Value) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpARMLoweredPanicBoundsRC(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (LoweredPanicBoundsRC [kind] {p} (MOVWconst [c]) mem)
|
||||
// result: (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(c), Cy:p.C}} mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
p := auxToPanicBoundsC(v.Aux)
|
||||
if v_0.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt32(v_0.AuxInt)
|
||||
mem := v_1
|
||||
v.reset(OpARMLoweredPanicBoundsCC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCCToAux(PanicBoundsCC{Cx: int64(c), Cy: p.C})
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpARMLoweredPanicBoundsRR(v *Value) bool {
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (LoweredPanicBoundsRR [kind] x (MOVWconst [c]) mem)
|
||||
// result: (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:int64(c)}} mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
if v_1.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt32(v_1.AuxInt)
|
||||
mem := v_2
|
||||
v.reset(OpARMLoweredPanicBoundsRC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(c)})
|
||||
v.AddArg2(x, mem)
|
||||
return true
|
||||
}
|
||||
// match: (LoweredPanicBoundsRR [kind] (MOVWconst [c]) y mem)
|
||||
// result: (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(c)}} y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt32(v_0.AuxInt)
|
||||
y := v_1
|
||||
mem := v_2
|
||||
v.reset(OpARMLoweredPanicBoundsCR)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(c)})
|
||||
v.AddArg2(y, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpARMLoweredPanicExtendRC(v *Value) bool {
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (LoweredPanicExtendRC [kind] {p} (MOVWconst [hi]) (MOVWconst [lo]) mem)
|
||||
// result: (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(hi)<<32+int64(uint32(lo)), Cy:p.C}} mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
p := auxToPanicBoundsC(v.Aux)
|
||||
if v_0.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
hi := auxIntToInt32(v_0.AuxInt)
|
||||
if v_1.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
lo := auxIntToInt32(v_1.AuxInt)
|
||||
mem := v_2
|
||||
v.reset(OpARMLoweredPanicBoundsCC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCCToAux(PanicBoundsCC{Cx: int64(hi)<<32 + int64(uint32(lo)), Cy: p.C})
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpARMLoweredPanicExtendRR(v *Value) bool {
|
||||
v_3 := v.Args[3]
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (LoweredPanicExtendRR [kind] hi lo (MOVWconst [c]) mem)
|
||||
// result: (LoweredPanicExtendRC [kind] hi lo {PanicBoundsC{C:int64(c)}} mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
hi := v_0
|
||||
lo := v_1
|
||||
if v_2.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
c := auxIntToInt32(v_2.AuxInt)
|
||||
mem := v_3
|
||||
v.reset(OpARMLoweredPanicExtendRC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(c)})
|
||||
v.AddArg3(hi, lo, mem)
|
||||
return true
|
||||
}
|
||||
// match: (LoweredPanicExtendRR [kind] (MOVWconst [hi]) (MOVWconst [lo]) y mem)
|
||||
// result: (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(hi)<<32 + int64(uint32(lo))}} y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
if v_0.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
hi := auxIntToInt32(v_0.AuxInt)
|
||||
if v_1.Op != OpARMMOVWconst {
|
||||
break
|
||||
}
|
||||
lo := auxIntToInt32(v_1.AuxInt)
|
||||
y := v_2
|
||||
mem := v_3
|
||||
v.reset(OpARMLoweredPanicBoundsCR)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(hi)<<32 + int64(uint32(lo))})
|
||||
v.AddArg2(y, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpARMMOVBUload(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
|
@ -14969,118 +15108,6 @@ func rewriteValueARM_OpOffPtr(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValueARM_OpPanicBounds(v *Value) bool {
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (PanicBounds [kind] x y mem)
|
||||
// cond: boundsABI(kind) == 0
|
||||
// result: (LoweredPanicBoundsA [kind] x y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
y := v_1
|
||||
mem := v_2
|
||||
if !(boundsABI(kind) == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicBoundsA)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg3(x, y, mem)
|
||||
return true
|
||||
}
|
||||
// match: (PanicBounds [kind] x y mem)
|
||||
// cond: boundsABI(kind) == 1
|
||||
// result: (LoweredPanicBoundsB [kind] x y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
y := v_1
|
||||
mem := v_2
|
||||
if !(boundsABI(kind) == 1) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicBoundsB)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg3(x, y, mem)
|
||||
return true
|
||||
}
|
||||
// match: (PanicBounds [kind] x y mem)
|
||||
// cond: boundsABI(kind) == 2
|
||||
// result: (LoweredPanicBoundsC [kind] x y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
x := v_0
|
||||
y := v_1
|
||||
mem := v_2
|
||||
if !(boundsABI(kind) == 2) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicBoundsC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg3(x, y, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpPanicExtend(v *Value) bool {
|
||||
v_3 := v.Args[3]
|
||||
v_2 := v.Args[2]
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
// match: (PanicExtend [kind] hi lo y mem)
|
||||
// cond: boundsABI(kind) == 0
|
||||
// result: (LoweredPanicExtendA [kind] hi lo y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
hi := v_0
|
||||
lo := v_1
|
||||
y := v_2
|
||||
mem := v_3
|
||||
if !(boundsABI(kind) == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicExtendA)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg4(hi, lo, y, mem)
|
||||
return true
|
||||
}
|
||||
// match: (PanicExtend [kind] hi lo y mem)
|
||||
// cond: boundsABI(kind) == 1
|
||||
// result: (LoweredPanicExtendB [kind] hi lo y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
hi := v_0
|
||||
lo := v_1
|
||||
y := v_2
|
||||
mem := v_3
|
||||
if !(boundsABI(kind) == 1) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicExtendB)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg4(hi, lo, y, mem)
|
||||
return true
|
||||
}
|
||||
// match: (PanicExtend [kind] hi lo y mem)
|
||||
// cond: boundsABI(kind) == 2
|
||||
// result: (LoweredPanicExtendC [kind] hi lo y mem)
|
||||
for {
|
||||
kind := auxIntToInt64(v.AuxInt)
|
||||
hi := v_0
|
||||
lo := v_1
|
||||
y := v_2
|
||||
mem := v_3
|
||||
if !(boundsABI(kind) == 2) {
|
||||
break
|
||||
}
|
||||
v.reset(OpARMLoweredPanicExtendC)
|
||||
v.AuxInt = int64ToAuxInt(kind)
|
||||
v.AddArg4(hi, lo, y, mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValueARM_OpRotateLeft16(v *Value) bool {
|
||||
v_1 := v.Args[1]
|
||||
v_0 := v.Args[0]
|
||||
|
|
|
|||
|
|
@ -991,158 +991,56 @@ TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
|
|||
MOVW $32, R8
|
||||
JMP gcWriteBarrier<>(SB)
|
||||
|
||||
// Note: these functions use a special calling convention to save generated code space.
|
||||
// Arguments are passed in registers, but the space for those arguments are allocated
|
||||
// in the caller's stack frame. These stubs write the args into that stack space and
|
||||
// then tail call to the corresponding runtime handler.
|
||||
// The tail call makes these stubs disappear in backtraces.
|
||||
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicIndex(SB)
|
||||
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicIndexU(SB)
|
||||
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSliceAlen(SB)
|
||||
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSliceAlenU(SB)
|
||||
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSliceAcap(SB)
|
||||
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSliceAcapU(SB)
|
||||
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicSliceB(SB)
|
||||
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicSliceBU(SB)
|
||||
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
|
||||
MOVW R2, x+0(FP)
|
||||
MOVW R3, y+4(FP)
|
||||
JMP runtime·goPanicSlice3Alen(SB)
|
||||
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
|
||||
MOVW R2, x+0(FP)
|
||||
MOVW R3, y+4(FP)
|
||||
JMP runtime·goPanicSlice3AlenU(SB)
|
||||
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
|
||||
MOVW R2, x+0(FP)
|
||||
MOVW R3, y+4(FP)
|
||||
JMP runtime·goPanicSlice3Acap(SB)
|
||||
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
|
||||
MOVW R2, x+0(FP)
|
||||
MOVW R3, y+4(FP)
|
||||
JMP runtime·goPanicSlice3AcapU(SB)
|
||||
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSlice3B(SB)
|
||||
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
|
||||
MOVW R1, x+0(FP)
|
||||
MOVW R2, y+4(FP)
|
||||
JMP runtime·goPanicSlice3BU(SB)
|
||||
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicSlice3C(SB)
|
||||
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
|
||||
MOVW R0, x+0(FP)
|
||||
MOVW R1, y+4(FP)
|
||||
JMP runtime·goPanicSlice3CU(SB)
|
||||
TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
|
||||
MOVW R2, x+0(FP)
|
||||
MOVW R3, y+4(FP)
|
||||
JMP runtime·goPanicSliceConvert(SB)
|
||||
TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$72-0
|
||||
NO_LOCAL_POINTERS
|
||||
// Save all int registers that could have an index in them.
|
||||
// They may be pointers, but if they are they are dead.
|
||||
MOVW R0, 12(R13)
|
||||
MOVW R1, 16(R13)
|
||||
MOVW R2, 20(R13)
|
||||
MOVW R3, 24(R13)
|
||||
MOVW R4, 28(R13)
|
||||
MOVW R5, 32(R13)
|
||||
MOVW R6, 36(R13)
|
||||
MOVW R7, 40(R13)
|
||||
MOVW R8, 44(R13)
|
||||
MOVW R9, 48(R13)
|
||||
// skip R10 aka G @ 52(R13)
|
||||
// skip R11 aka tmp @ 56(R13)
|
||||
MOVW R12, 60(R13)
|
||||
// skip R13 aka SP @ 64(R13)
|
||||
MOVW R14, 68(R13)
|
||||
// skip R15 aka PC @ 72(R13)
|
||||
|
||||
// Extended versions for 64-bit indexes.
|
||||
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendIndex(SB)
|
||||
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendIndexU(SB)
|
||||
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceAlen(SB)
|
||||
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceAlenU(SB)
|
||||
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceAcap(SB)
|
||||
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceAcapU(SB)
|
||||
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceB(SB)
|
||||
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendSliceBU(SB)
|
||||
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R2, lo+4(FP)
|
||||
MOVW R3, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3Alen(SB)
|
||||
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R2, lo+4(FP)
|
||||
MOVW R3, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3AlenU(SB)
|
||||
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R2, lo+4(FP)
|
||||
MOVW R3, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3Acap(SB)
|
||||
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R2, lo+4(FP)
|
||||
MOVW R3, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3AcapU(SB)
|
||||
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3B(SB)
|
||||
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R1, lo+4(FP)
|
||||
MOVW R2, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3BU(SB)
|
||||
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3C(SB)
|
||||
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
|
||||
MOVW R4, hi+0(FP)
|
||||
MOVW R0, lo+4(FP)
|
||||
MOVW R1, y+8(FP)
|
||||
JMP runtime·goPanicExtendSlice3CU(SB)
|
||||
MOVW R14, 4(R13) // PC immediately after call to panicBounds
|
||||
ADD $12, R13, R0 // pointer to save area
|
||||
MOVW R0, 8(R13)
|
||||
CALL runtime·panicBounds32<ABIInternal>(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·panicExtend<ABIInternal>(SB),NOSPLIT,$72-0
|
||||
NO_LOCAL_POINTERS
|
||||
// Save all int registers that could have an index in them.
|
||||
// They may be pointers, but if they are they are dead.
|
||||
MOVW R0, 12(R13)
|
||||
MOVW R1, 16(R13)
|
||||
MOVW R2, 20(R13)
|
||||
MOVW R3, 24(R13)
|
||||
MOVW R4, 28(R13)
|
||||
MOVW R5, 32(R13)
|
||||
MOVW R6, 36(R13)
|
||||
MOVW R7, 40(R13)
|
||||
MOVW R8, 44(R13)
|
||||
MOVW R9, 48(R13)
|
||||
// skip R10 aka G @ 52(R13)
|
||||
// skip R11 aka tmp @ 56(R13)
|
||||
MOVW R12, 60(R13)
|
||||
// skip R13 aka SP @ 64(R13)
|
||||
// skip R14 aka LR @ 68(R13)
|
||||
// skip R15 aka PC @ 72(R13)
|
||||
|
||||
MOVW R14, 4(R13) // PC immediately after call to panicExtend
|
||||
ADD $12, R13, R0 // pointer to save area
|
||||
MOVW R0, 8(R13)
|
||||
CALL runtime·panicBounds32X<ABIInternal>(SB)
|
||||
RET
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue