cmd/compile: move mips32 over to new bounds check strategy

Change-Id: Ied54ea7bf68c4c943c621ca059aca1048903c041
Reviewed-on: https://go-review.googlesource.com/c/go/+/682497
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Julian Zhu <jz531210@gmail.com>
Reviewed-by: Mark Freeman <mark@golang.org>
This commit is contained in:
Keith Randall 2025-06-18 15:49:52 -07:00
parent 9f9d7b50e8
commit 8330fb48a6
6 changed files with 434 additions and 362 deletions

View file

@ -15,6 +15,7 @@ import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/obj/mips" "cmd/internal/obj/mips"
"internal/abi"
) )
// isFPreg reports whether r is an FP register. // isFPreg reports whether r is an FP register.
@ -486,18 +487,167 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
// AuxInt encodes how many buffer entries we need. // AuxInt encodes how many buffer entries we need.
p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1] p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
case ssa.OpMIPSLoweredPanicBoundsA, ssa.OpMIPSLoweredPanicBoundsB, ssa.OpMIPSLoweredPanicBoundsC:
p := s.Prog(obj.ACALL) case ssa.OpMIPSLoweredPanicBoundsRR, ssa.OpMIPSLoweredPanicBoundsRC, ssa.OpMIPSLoweredPanicBoundsCR, ssa.OpMIPSLoweredPanicBoundsCC,
ssa.OpMIPSLoweredPanicExtendRR, ssa.OpMIPSLoweredPanicExtendRC:
// 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.OpMIPSLoweredPanicBoundsRR:
xIsReg = true
xVal = int(v.Args[0].Reg() - mips.REG_R1)
yIsReg = true
yVal = int(v.Args[1].Reg() - mips.REG_R1)
case ssa.OpMIPSLoweredPanicExtendRR:
extend = true
xIsReg = true
hi := int(v.Args[0].Reg() - mips.REG_R1)
lo := int(v.Args[1].Reg() - mips.REG_R1)
xVal = hi<<2 + lo // encode 2 register numbers
yIsReg = true
yVal = int(v.Args[2].Reg() - mips.REG_R1)
case ssa.OpMIPSLoweredPanicBoundsRC:
xIsReg = true
xVal = int(v.Args[0].Reg() - mips.REG_R1)
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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(yVal)
}
case ssa.OpMIPSLoweredPanicExtendRC:
extend = true
xIsReg = true
hi := int(v.Args[0].Reg() - mips.REG_R1)
lo := int(v.Args[1].Reg() - mips.REG_R1)
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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(yVal)
}
case ssa.OpMIPSLoweredPanicBoundsCR:
yIsReg = true
yVal := int(v.Args[0].Reg() - mips.REG_R1)
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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + 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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c >> 32
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(hi)
p = s.Prog(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(int32(c))
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(lo)
}
case ssa.OpMIPSLoweredPanicBoundsCC:
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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(xVal)
} else {
// Move constant to two registers
extend = true
xIsReg = true
hi := 0
lo := 1
xVal = hi<<2 + lo
p := s.Prog(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c >> 32
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + int16(hi)
p = s.Prog(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(int32(c))
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + 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(mips.AMOVW)
p.From.Type = obj.TYPE_CONST
p.From.Offset = c
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REG_R1 + 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.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt] if extend {
s.UseArgs(8) // space used in callee args area by assembly stubs p.To.Sym = ir.Syms.PanicExtend
case ssa.OpMIPSLoweredPanicExtendA, ssa.OpMIPSLoweredPanicExtendB, ssa.OpMIPSLoweredPanicExtendC: } else {
p := s.Prog(obj.ACALL) p.To.Sym = ir.Syms.PanicBounds
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
case ssa.OpMIPSLoweredAtomicLoad8, case ssa.OpMIPSLoweredAtomicLoad8,
ssa.OpMIPSLoweredAtomicLoad32: ssa.OpMIPSLoweredAtomicLoad32:
s.Prog(mips.ASYNC) s.Prog(mips.ASYNC)

View file

@ -423,13 +423,17 @@
// Publication barrier as intrinsic // Publication barrier as intrinsic
(PubBarrier ...) => (LoweredPubBarrier ...) (PubBarrier ...) => (LoweredPubBarrier ...)
(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)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem) (PanicBounds ...) => (LoweredPanicBoundsRR ...)
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem) (PanicExtend ...) => (LoweredPanicExtendRR ...)
(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 // Optimizations

View file

@ -120,11 +120,8 @@ func init() {
lo = buildReg("LO") lo = buildReg("LO")
hi = buildReg("HI") hi = buildReg("HI")
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
r1 = buildReg("R1") first16 = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16")
r2 = buildReg("R2") first4 = buildReg("R1 R2 R3 R4")
r3 = buildReg("R3")
r4 = buildReg("R4")
r5 = buildReg("R5")
) )
// Common regInfo // Common regInfo
var ( var (
@ -411,16 +408,19 @@ func init() {
// Do data barrier. arg0=memorys // Do data barrier. arg0=memorys
{name: "LoweredPubBarrier", argLength: 1, asm: "SYNC", hasSideEffects: true}, {name: "LoweredPubBarrier", argLength: 1, asm: "SYNC", hasSideEffects: true},
// There are three of these functions so that they can have three different register inputs. // LoweredPanicBoundsRR takes x and y, two values that caused a bounds check to fail.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the // the RC and CR versions are used when one of the arguments is a constant. CC is used
// default registers to match so we don't need to copy registers around unnecessarily. // when both are constant (normally both 0, as prove derives the fact that a [0] bounds
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go). // failure means the length must have also been 0).
{name: "LoweredPanicBoundsB", 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). // AuxInt contains a report code (see PanicBounds in genericOps.go).
{name: "LoweredPanicBoundsC", 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: "LoweredPanicBoundsRR", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{first16, first16}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
// Extend ops are the same as Bounds ops except the indexes are 64-bit. {name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, typ: "Mem", call: true}, // arg0=x, arg1=mem, returns memory.
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r3, r4}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go). {name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, typ: "Mem", call: true}, // arg0=y, arg1=mem, returns memory.
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, 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: "LoweredPanicBoundsCC", argLength: 1, aux: "PanicBoundsCC", reg: regInfo{}, typ: "Mem", call: true}, // arg0=mem, returns memory.
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, 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).
// Same as above, but the x value is 64 bits.
{name: "LoweredPanicExtendRR", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{first4, first4, first16}}, 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{first4, first4}}, typ: "Mem", call: true}, // arg0=x_hi, arg1=x_lo, arg2=mem, returns memory.
} }
blocks := []blockData{ blocks := []blockData{

View file

@ -2080,12 +2080,12 @@ const (
OpMIPSLoweredGetCallerPC OpMIPSLoweredGetCallerPC
OpMIPSLoweredWB OpMIPSLoweredWB
OpMIPSLoweredPubBarrier OpMIPSLoweredPubBarrier
OpMIPSLoweredPanicBoundsA OpMIPSLoweredPanicBoundsRR
OpMIPSLoweredPanicBoundsB OpMIPSLoweredPanicBoundsRC
OpMIPSLoweredPanicBoundsC OpMIPSLoweredPanicBoundsCR
OpMIPSLoweredPanicExtendA OpMIPSLoweredPanicBoundsCC
OpMIPSLoweredPanicExtendB OpMIPSLoweredPanicExtendRR
OpMIPSLoweredPanicExtendC OpMIPSLoweredPanicExtendRC
OpMIPS64ADDV OpMIPS64ADDV
OpMIPS64ADDVconst OpMIPS64ADDVconst
@ -27994,77 +27994,68 @@ var opcodeTable = [...]opInfo{
reg: regInfo{}, reg: regInfo{},
}, },
{ {
name: "LoweredPanicBoundsA", name: "LoweredPanicBoundsRR",
auxType: auxInt64, auxType: auxInt64,
argLen: 3, argLen: 3,
call: true, call: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 8}, // R3 {0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
{1, 16}, // R4 {1, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
}, },
}, },
}, },
{ {
name: "LoweredPanicBoundsB", name: "LoweredPanicBoundsRC",
auxType: auxPanicBoundsC,
argLen: 2,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
},
},
},
{
name: "LoweredPanicBoundsCR",
auxType: auxPanicBoundsC,
argLen: 2,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
},
},
},
{
name: "LoweredPanicBoundsCC",
auxType: auxPanicBoundsCC,
argLen: 1,
call: true,
reg: regInfo{},
},
{
name: "LoweredPanicExtendRR",
auxType: auxInt64, auxType: auxInt64,
argLen: 4,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 30}, // R1 R2 R3 R4
{1, 30}, // R1 R2 R3 R4
{2, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
},
},
},
{
name: "LoweredPanicExtendRC",
auxType: auxPanicBoundsC,
argLen: 3, argLen: 3,
call: true, call: true,
reg: regInfo{ reg: regInfo{
inputs: []inputInfo{ inputs: []inputInfo{
{0, 4}, // R2 {0, 30}, // R1 R2 R3 R4
{1, 8}, // R3 {1, 30}, // R1 R2 R3 R4
},
},
},
{
name: "LoweredPanicBoundsC",
auxType: auxInt64,
argLen: 3,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 2}, // R1
{1, 4}, // R2
},
},
},
{
name: "LoweredPanicExtendA",
auxType: auxInt64,
argLen: 4,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 8}, // R3
{2, 16}, // R4
},
},
},
{
name: "LoweredPanicExtendB",
auxType: auxInt64,
argLen: 4,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 4}, // R2
{2, 8}, // R3
},
},
},
{
name: "LoweredPanicExtendC",
auxType: auxInt64,
argLen: 4,
call: true,
reg: regInfo{
inputs: []inputInfo{
{0, 32}, // R5
{1, 2}, // R1
{2, 4}, // R2
}, },
}, },
}, },

View file

@ -279,6 +279,14 @@ func rewriteValueMIPS(v *Value) bool {
return rewriteValueMIPS_OpMIPSLoweredAtomicAdd(v) return rewriteValueMIPS_OpMIPSLoweredAtomicAdd(v)
case OpMIPSLoweredAtomicStore32: case OpMIPSLoweredAtomicStore32:
return rewriteValueMIPS_OpMIPSLoweredAtomicStore32(v) return rewriteValueMIPS_OpMIPSLoweredAtomicStore32(v)
case OpMIPSLoweredPanicBoundsRC:
return rewriteValueMIPS_OpMIPSLoweredPanicBoundsRC(v)
case OpMIPSLoweredPanicBoundsRR:
return rewriteValueMIPS_OpMIPSLoweredPanicBoundsRR(v)
case OpMIPSLoweredPanicExtendRC:
return rewriteValueMIPS_OpMIPSLoweredPanicExtendRC(v)
case OpMIPSLoweredPanicExtendRR:
return rewriteValueMIPS_OpMIPSLoweredPanicExtendRR(v)
case OpMIPSMOVBUload: case OpMIPSMOVBUload:
return rewriteValueMIPS_OpMIPSMOVBUload(v) return rewriteValueMIPS_OpMIPSMOVBUload(v)
case OpMIPSMOVBUreg: case OpMIPSMOVBUreg:
@ -447,9 +455,11 @@ func rewriteValueMIPS(v *Value) bool {
v.Op = OpMIPSOR v.Op = OpMIPSOR
return true return true
case OpPanicBounds: case OpPanicBounds:
return rewriteValueMIPS_OpPanicBounds(v) v.Op = OpMIPSLoweredPanicBoundsRR
return true
case OpPanicExtend: case OpPanicExtend:
return rewriteValueMIPS_OpPanicExtend(v) v.Op = OpMIPSLoweredPanicExtendRR
return true
case OpPubBarrier: case OpPubBarrier:
v.Op = OpMIPSLoweredPubBarrier v.Op = OpMIPSLoweredPubBarrier
return true return true
@ -2435,6 +2445,135 @@ func rewriteValueMIPS_OpMIPSLoweredAtomicStore32(v *Value) bool {
} }
return false return false
} }
func rewriteValueMIPS_OpMIPSLoweredPanicBoundsRC(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 != OpMIPSMOVWconst {
break
}
c := auxIntToInt32(v_0.AuxInt)
mem := v_1
v.reset(OpMIPSLoweredPanicBoundsCC)
v.AuxInt = int64ToAuxInt(kind)
v.Aux = panicBoundsCCToAux(PanicBoundsCC{Cx: int64(c), Cy: p.C})
v.AddArg(mem)
return true
}
return false
}
func rewriteValueMIPS_OpMIPSLoweredPanicBoundsRR(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 != OpMIPSMOVWconst {
break
}
c := auxIntToInt32(v_1.AuxInt)
mem := v_2
v.reset(OpMIPSLoweredPanicBoundsRC)
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 != OpMIPSMOVWconst {
break
}
c := auxIntToInt32(v_0.AuxInt)
y := v_1
mem := v_2
v.reset(OpMIPSLoweredPanicBoundsCR)
v.AuxInt = int64ToAuxInt(kind)
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(c)})
v.AddArg2(y, mem)
return true
}
return false
}
func rewriteValueMIPS_OpMIPSLoweredPanicExtendRC(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 != OpMIPSMOVWconst {
break
}
hi := auxIntToInt32(v_0.AuxInt)
if v_1.Op != OpMIPSMOVWconst {
break
}
lo := auxIntToInt32(v_1.AuxInt)
mem := v_2
v.reset(OpMIPSLoweredPanicBoundsCC)
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 rewriteValueMIPS_OpMIPSLoweredPanicExtendRR(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 != OpMIPSMOVWconst {
break
}
c := auxIntToInt32(v_2.AuxInt)
mem := v_3
v.reset(OpMIPSLoweredPanicExtendRC)
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 != OpMIPSMOVWconst {
break
}
hi := auxIntToInt32(v_0.AuxInt)
if v_1.Op != OpMIPSMOVWconst {
break
}
lo := auxIntToInt32(v_1.AuxInt)
y := v_2
mem := v_3
v.reset(OpMIPSLoweredPanicBoundsCR)
v.AuxInt = int64ToAuxInt(kind)
v.Aux = panicBoundsCToAux(PanicBoundsC{C: int64(hi)<<32 + int64(uint32(lo))})
v.AddArg2(y, mem)
return true
}
return false
}
func rewriteValueMIPS_OpMIPSMOVBUload(v *Value) bool { func rewriteValueMIPS_OpMIPSMOVBUload(v *Value) bool {
v_1 := v.Args[1] v_1 := v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]
@ -5586,118 +5725,6 @@ func rewriteValueMIPS_OpOffPtr(v *Value) bool {
return true return true
} }
} }
func rewriteValueMIPS_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(OpMIPSLoweredPanicBoundsA)
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(OpMIPSLoweredPanicBoundsB)
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(OpMIPSLoweredPanicBoundsC)
v.AuxInt = int64ToAuxInt(kind)
v.AddArg3(x, y, mem)
return true
}
return false
}
func rewriteValueMIPS_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(OpMIPSLoweredPanicExtendA)
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(OpMIPSLoweredPanicExtendB)
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(OpMIPSLoweredPanicExtendC)
v.AuxInt = int64ToAuxInt(kind)
v.AddArg4(hi, lo, y, mem)
return true
}
return false
}
func rewriteValueMIPS_OpRotateLeft16(v *Value) bool { func rewriteValueMIPS_OpRotateLeft16(v *Value) bool {
v_1 := v.Args[1] v_1 := v.Args[1]
v_0 := v.Args[0] v_0 := v.Args[0]

View file

@ -787,158 +787,58 @@ TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
MOVW $32, R25 MOVW $32, R25
JMP gcWriteBarrier<>(SB) JMP gcWriteBarrier<>(SB)
// Note: these functions use a special calling convention to save generated code space. TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$72-0
// Arguments are passed in registers, but the space for those arguments are allocated NO_LOCAL_POINTERS
// in the caller's stack frame. These stubs write the args into that stack space and // Save all 16 int registers that could have an index in them.
// then tail call to the corresponding runtime handler. // They may be pointers, but if they are they are dead.
// The tail call makes these stubs disappear in backtraces. // Skip R0 aka ZERO.
TEXT runtime·panicIndex(SB),NOSPLIT,$0-8 MOVW R1, 12(R29)
MOVW R1, x+0(FP) MOVW R2, 16(R29)
MOVW R2, y+4(FP) MOVW R3, 20(R29)
JMP runtime·goPanicIndex(SB) MOVW R4, 24(R29)
TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8 MOVW R5, 28(R29)
MOVW R1, x+0(FP) MOVW R6, 32(R29)
MOVW R2, y+4(FP) MOVW R7, 36(R29)
JMP runtime·goPanicIndexU(SB) MOVW R8, 40(R29)
TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8 MOVW R9, 44(R29)
MOVW R2, x+0(FP) MOVW R10, 48(R29)
MOVW R3, y+4(FP) MOVW R11, 52(R29)
JMP runtime·goPanicSliceAlen(SB) MOVW R12, 56(R29)
TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8 MOVW R13, 60(R29)
MOVW R2, x+0(FP) MOVW R14, 64(R29)
MOVW R3, y+4(FP) MOVW R15, 68(R29)
JMP runtime·goPanicSliceAlenU(SB) MOVW R16, 72(R29)
TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAcap(SB)
TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSliceAcapU(SB)
TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceB(SB)
TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSliceBU(SB)
TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3Alen(SB)
TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3AlenU(SB)
TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3Acap(SB)
TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSlice3AcapU(SB)
TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3B(SB)
TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
MOVW R2, x+0(FP)
MOVW R3, y+4(FP)
JMP runtime·goPanicSlice3BU(SB)
TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3C(SB)
TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
MOVW R1, x+0(FP)
MOVW R2, y+4(FP)
JMP runtime·goPanicSlice3CU(SB)
TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
MOVW R3, x+0(FP)
MOVW R4, y+4(FP)
JMP runtime·goPanicSliceConvert(SB)
// Extended versions for 64-bit indexes. MOVW R31, 4(R29) // PC immediately after call to panicBounds
TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12 ADD $12, R29, R1 // pointer to save area
MOVW R5, hi+0(FP) MOVW R1, 8(R29)
MOVW R1, lo+4(FP) CALL runtime·panicBounds32<ABIInternal>(SB)
MOVW R2, y+8(FP) RET
JMP runtime·goPanicExtendIndex(SB)
TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12 TEXT runtime·panicExtend<ABIInternal>(SB),NOSPLIT,$72-0
MOVW R5, hi+0(FP) NO_LOCAL_POINTERS
MOVW R1, lo+4(FP) // Save all 16 int registers that could have an index in them.
MOVW R2, y+8(FP) // They may be pointers, but if they are they are dead.
JMP runtime·goPanicExtendIndexU(SB) // Skip R0 aka ZERO.
TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12 MOVW R1, 12(R29)
MOVW R5, hi+0(FP) MOVW R2, 16(R29)
MOVW R2, lo+4(FP) MOVW R3, 20(R29)
MOVW R3, y+8(FP) MOVW R4, 24(R29)
JMP runtime·goPanicExtendSliceAlen(SB) MOVW R5, 28(R29)
TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12 MOVW R6, 32(R29)
MOVW R5, hi+0(FP) MOVW R7, 36(R29)
MOVW R2, lo+4(FP) MOVW R8, 40(R29)
MOVW R3, y+8(FP) MOVW R9, 44(R29)
JMP runtime·goPanicExtendSliceAlenU(SB) MOVW R10, 48(R29)
TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12 MOVW R11, 52(R29)
MOVW R5, hi+0(FP) MOVW R12, 56(R29)
MOVW R2, lo+4(FP) MOVW R13, 60(R29)
MOVW R3, y+8(FP) MOVW R14, 64(R29)
JMP runtime·goPanicExtendSliceAcap(SB) MOVW R15, 68(R29)
TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12 MOVW R16, 72(R29)
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP) MOVW R31, 4(R29) // PC immediately after call to panicBounds
MOVW R3, y+8(FP) ADD $12, R29, R1 // pointer to save area
JMP runtime·goPanicExtendSliceAcapU(SB) MOVW R1, 8(R29)
TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12 CALL runtime·panicBounds32X<ABIInternal>(SB)
MOVW R5, hi+0(FP) RET
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSliceB(SB)
TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSliceBU(SB)
TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3Alen(SB)
TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3AlenU(SB)
TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3Acap(SB)
TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R3, lo+4(FP)
MOVW R4, y+8(FP)
JMP runtime·goPanicExtendSlice3AcapU(SB)
TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3B(SB)
TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R2, lo+4(FP)
MOVW R3, y+8(FP)
JMP runtime·goPanicExtendSlice3BU(SB)
TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSlice3C(SB)
TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
MOVW R5, hi+0(FP)
MOVW R1, lo+4(FP)
MOVW R2, y+8(FP)
JMP runtime·goPanicExtendSlice3CU(SB)