]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: move mips32 over to new bounds check strategy
authorKeith Randall <khr@golang.org>
Wed, 18 Jun 2025 22:49:52 +0000 (15:49 -0700)
committerKeith Randall <khr@golang.org>
Wed, 30 Jul 2025 15:33:08 +0000 (08:33 -0700)
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>
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/ssa/_gen/MIPS.rules
src/cmd/compile/internal/ssa/_gen/MIPSOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteMIPS.go
src/runtime/asm_mipsx.s

index 9762554829c2953bc0854f26375ee90504b50077..7390db29450f78da32cd3db9f10d074d8060e22a 100644 (file)
@@ -15,6 +15,7 @@ import (
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/obj/mips"
+       "internal/abi"
 )
 
 // 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
                // AuxInt encodes how many buffer entries we need.
                p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
-       case ssa.OpMIPSLoweredPanicBoundsA, ssa.OpMIPSLoweredPanicBoundsB, ssa.OpMIPSLoweredPanicBoundsC:
-               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.OpMIPSLoweredPanicExtendA, ssa.OpMIPSLoweredPanicExtendB, ssa.OpMIPSLoweredPanicExtendC:
-               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.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.OpMIPSLoweredAtomicLoad8,
                ssa.OpMIPSLoweredAtomicLoad32:
                s.Prog(mips.ASYNC)
index d417bafa1db08126df44ca9fe2f349a63d25ca60..80bf9017f524281441001418c874d47ce1f77859 100644 (file)
 // Publication barrier as intrinsic
 (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)
-(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)
+(PanicBounds ...) => (LoweredPanicBoundsRR ...)
+(PanicExtend ...) => (LoweredPanicExtendRR ...)
+
+(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
 
index 62c35ed49f2a854538387996e1d544e06ee8951c..a340775c07468e338b65dbdcd8b7095e4af59293 100644 (file)
@@ -120,11 +120,8 @@ func init() {
                lo         = buildReg("LO")
                hi         = buildReg("HI")
                callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-               r1         = buildReg("R1")
-               r2         = buildReg("R2")
-               r3         = buildReg("R3")
-               r4         = buildReg("R4")
-               r5         = buildReg("R5")
+               first16    = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16")
+               first4     = buildReg("R1 R2 R3 R4")
        )
        // Common regInfo
        var (
@@ -411,16 +408,19 @@ func init() {
                // Do data barrier. arg0=memorys
                {name: "LoweredPubBarrier", argLength: 1, asm: "SYNC", hasSideEffects: 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{r3, r4}}, 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{r2, r3}}, 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{r1, r2}}, 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{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: "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: "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).
+               // 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{first16, first16}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
+               {name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, typ: "Mem", call: true},   // arg0=x, arg1=mem, returns memory.
+               {name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, 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{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{
index 81d3946a2118583a89be697a0cfbc90529199db6..e88af66f5fdbd97ea3117e6b71e6376fdc9f1074 100644 (file)
@@ -2080,12 +2080,12 @@ const (
        OpMIPSLoweredGetCallerPC
        OpMIPSLoweredWB
        OpMIPSLoweredPubBarrier
-       OpMIPSLoweredPanicBoundsA
-       OpMIPSLoweredPanicBoundsB
-       OpMIPSLoweredPanicBoundsC
-       OpMIPSLoweredPanicExtendA
-       OpMIPSLoweredPanicExtendB
-       OpMIPSLoweredPanicExtendC
+       OpMIPSLoweredPanicBoundsRR
+       OpMIPSLoweredPanicBoundsRC
+       OpMIPSLoweredPanicBoundsCR
+       OpMIPSLoweredPanicBoundsCC
+       OpMIPSLoweredPanicExtendRR
+       OpMIPSLoweredPanicExtendRC
 
        OpMIPS64ADDV
        OpMIPS64ADDVconst
@@ -27994,77 +27994,68 @@ var opcodeTable = [...]opInfo{
                reg:            regInfo{},
        },
        {
-               name:    "LoweredPanicBoundsA",
+               name:    "LoweredPanicBoundsRR",
                auxType: auxInt64,
                argLen:  3,
                call:    true,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 8},  // R3
-                               {1, 16}, // R4
+                               {0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
+                               {1, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
                        },
                },
        },
        {
-               name:    "LoweredPanicBoundsB",
-               auxType: auxInt64,
-               argLen:  3,
+               name:    "LoweredPanicBoundsRC",
+               auxType: auxPanicBoundsC,
+               argLen:  2,
                call:    true,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 4}, // R2
-                               {1, 8}, // R3
+                               {0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
                        },
                },
        },
        {
-               name:    "LoweredPanicBoundsC",
-               auxType: auxInt64,
-               argLen:  3,
+               name:    "LoweredPanicBoundsCR",
+               auxType: auxPanicBoundsC,
+               argLen:  2,
                call:    true,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 2}, // R1
-                               {1, 4}, // R2
+                               {0, 131070}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16
                        },
                },
        },
        {
-               name:    "LoweredPanicExtendA",
-               auxType: auxInt64,
-               argLen:  4,
+               name:    "LoweredPanicBoundsCC",
+               auxType: auxPanicBoundsCC,
+               argLen:  1,
                call:    true,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 32}, // R5
-                               {1, 8},  // R3
-                               {2, 16}, // R4
-                       },
-               },
+               reg:     regInfo{},
        },
        {
-               name:    "LoweredPanicExtendB",
+               name:    "LoweredPanicExtendRR",
                auxType: auxInt64,
                argLen:  4,
                call:    true,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 32}, // R5
-                               {1, 4},  // R2
-                               {2, 8},  // R3
+                               {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:    "LoweredPanicExtendC",
-               auxType: auxInt64,
-               argLen:  4,
+               name:    "LoweredPanicExtendRC",
+               auxType: auxPanicBoundsC,
+               argLen:  3,
                call:    true,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 32}, // R5
-                               {1, 2},  // R1
-                               {2, 4},  // R2
+                               {0, 30}, // R1 R2 R3 R4
+                               {1, 30}, // R1 R2 R3 R4
                        },
                },
        },
index 97847f082389d8dfadf38f2ff499738c0a67738b..fda02e64d19d7085beee9e88783c5ed8ea5941fa 100644 (file)
@@ -279,6 +279,14 @@ func rewriteValueMIPS(v *Value) bool {
                return rewriteValueMIPS_OpMIPSLoweredAtomicAdd(v)
        case OpMIPSLoweredAtomicStore32:
                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:
                return rewriteValueMIPS_OpMIPSMOVBUload(v)
        case OpMIPSMOVBUreg:
@@ -447,9 +455,11 @@ func rewriteValueMIPS(v *Value) bool {
                v.Op = OpMIPSOR
                return true
        case OpPanicBounds:
-               return rewriteValueMIPS_OpPanicBounds(v)
+               v.Op = OpMIPSLoweredPanicBoundsRR
+               return true
        case OpPanicExtend:
-               return rewriteValueMIPS_OpPanicExtend(v)
+               v.Op = OpMIPSLoweredPanicExtendRR
+               return true
        case OpPubBarrier:
                v.Op = OpMIPSLoweredPubBarrier
                return true
@@ -2435,6 +2445,135 @@ func rewriteValueMIPS_OpMIPSLoweredAtomicStore32(v *Value) bool {
        }
        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 {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
@@ -5586,118 +5725,6 @@ func rewriteValueMIPS_OpOffPtr(v *Value) bool {
                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 {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
index 7245e8ac494d1af30dfee8bdcc1474635ac431a6..ec352f582890722e3b86ca535e7e2aa1a317785a 100644 (file)
@@ -787,158 +787,58 @@ TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
        MOVW    $32, R25
        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    R1, x+0(FP)
-       MOVW    R2, y+4(FP)
-       JMP     runtime·goPanicIndex(SB)
-TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
-       MOVW    R1, x+0(FP)
-       MOVW    R2, y+4(FP)
-       JMP     runtime·goPanicIndexU(SB)
-TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
-       MOVW    R2, x+0(FP)
-       MOVW    R3, y+4(FP)
-       JMP     runtime·goPanicSliceAlen(SB)
-TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
-       MOVW    R2, x+0(FP)
-       MOVW    R3, y+4(FP)
-       JMP     runtime·goPanicSliceAlenU(SB)
-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.
-TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R1, lo+4(FP)
-       MOVW    R2, y+8(FP)
-       JMP     runtime·goPanicExtendIndex(SB)
-TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R1, lo+4(FP)
-       MOVW    R2, y+8(FP)
-       JMP     runtime·goPanicExtendIndexU(SB)
-TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R2, lo+4(FP)
-       MOVW    R3, y+8(FP)
-       JMP     runtime·goPanicExtendSliceAlen(SB)
-TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R2, lo+4(FP)
-       MOVW    R3, y+8(FP)
-       JMP     runtime·goPanicExtendSliceAlenU(SB)
-TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R2, lo+4(FP)
-       MOVW    R3, y+8(FP)
-       JMP     runtime·goPanicExtendSliceAcap(SB)
-TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       MOVW    R2, lo+4(FP)
-       MOVW    R3, y+8(FP)
-       JMP     runtime·goPanicExtendSliceAcapU(SB)
-TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
-       MOVW    R5, hi+0(FP)
-       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)
+TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$72-0
+       NO_LOCAL_POINTERS
+       // Save all 16 int registers that could have an index in them.
+       // They may be pointers, but if they are they are dead.
+       // Skip R0 aka ZERO.
+       MOVW    R1, 12(R29)
+       MOVW    R2, 16(R29)
+       MOVW    R3, 20(R29)
+       MOVW    R4, 24(R29)
+       MOVW    R5, 28(R29)
+       MOVW    R6, 32(R29)
+       MOVW    R7, 36(R29)
+       MOVW    R8, 40(R29)
+       MOVW    R9, 44(R29)
+       MOVW    R10, 48(R29)
+       MOVW    R11, 52(R29)
+       MOVW    R12, 56(R29)
+       MOVW    R13, 60(R29)
+       MOVW    R14, 64(R29)
+       MOVW    R15, 68(R29)
+       MOVW    R16, 72(R29)
+
+       MOVW    R31, 4(R29)     // PC immediately after call to panicBounds
+       ADD     $12, R29, R1    // pointer to save area
+       MOVW    R1, 8(R29)
+       CALL    runtime·panicBounds32<ABIInternal>(SB)
+       RET
+
+TEXT runtime·panicExtend<ABIInternal>(SB),NOSPLIT,$72-0
+       NO_LOCAL_POINTERS
+       // Save all 16 int registers that could have an index in them.
+       // They may be pointers, but if they are they are dead.
+       // Skip R0 aka ZERO.
+       MOVW    R1, 12(R29)
+       MOVW    R2, 16(R29)
+       MOVW    R3, 20(R29)
+       MOVW    R4, 24(R29)
+       MOVW    R5, 28(R29)
+       MOVW    R6, 32(R29)
+       MOVW    R7, 36(R29)
+       MOVW    R8, 40(R29)
+       MOVW    R9, 44(R29)
+       MOVW    R10, 48(R29)
+       MOVW    R11, 52(R29)
+       MOVW    R12, 56(R29)
+       MOVW    R13, 60(R29)
+       MOVW    R14, 64(R29)
+       MOVW    R15, 68(R29)
+       MOVW    R16, 72(R29)
+
+       MOVW    R31, 4(R29)     // PC immediately after call to panicBounds
+       ADD     $12, R29, R1    // pointer to save area
+       MOVW    R1, 8(R29)
+       CALL    runtime·panicBounds32X<ABIInternal>(SB)
+       RET