]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile,runtime: provide index information on bounds check failure
authorKeith Randall <khr@google.com>
Wed, 6 Feb 2019 22:12:36 +0000 (14:12 -0800)
committerKeith Randall <khr@golang.org>
Mon, 18 Mar 2019 17:33:38 +0000 (17:33 +0000)
A few examples (for accessing a slice of length 3):

   s[-1]    runtime error: index out of range [-1]
   s[3]     runtime error: index out of range [3] with length 3
   s[-1:0]  runtime error: slice bounds out of range [-1:]
   s[3:0]   runtime error: slice bounds out of range [3:0]
   s[3:-1]  runtime error: slice bounds out of range [:-1]
   s[3:4]   runtime error: slice bounds out of range [:4] with capacity 3
   s[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3

Note that in cases where there are multiple things wrong with the
indexes (e.g. s[3:-1]), we report one of those errors kind of
arbitrarily, currently the rightmost one.

An exhaustive set of examples is in issue30116[u].out in the CL.

The message text has the same prefix as the old message text. That
leads to slightly awkward phrasing but hopefully minimizes the chance
that code depending on the error text will break.

Increases the size of the go binary by 0.5% (amd64). The panic functions
take arguments in registers in order to keep the size of the compiled code
as small as possible.

Fixes #30116

Change-Id: Idb99a827b7888822ca34c240eca87b7e44a04fdd
Reviewed-on: https://go-review.googlesource.com/c/go/+/161477
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
59 files changed:
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/builtin/runtime.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/gen/386.rules
src/cmd/compile/internal/ssa/gen/386Ops.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/ARM64Ops.go
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/gen/MIPS.rules
src/cmd/compile/internal/ssa/gen/MIPS64.rules
src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
src/cmd/compile/internal/ssa/gen/MIPSOps.go
src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/gen/PPC64Ops.go
src/cmd/compile/internal/ssa/gen/S390X.rules
src/cmd/compile/internal/ssa/gen/S390XOps.go
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/op.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewriteARM.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/compile/internal/ssa/rewriteMIPS.go
src/cmd/compile/internal/ssa/rewriteMIPS64.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/compile/internal/ssa/rewriteS390X.go
src/cmd/compile/internal/x86/ssa.go
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_amd64p32.s
src/runtime/asm_arm.s
src/runtime/asm_arm64.s
src/runtime/asm_mips64x.s
src/runtime/asm_mipsx.s
src/runtime/asm_ppc64x.s
src/runtime/asm_s390x.s
src/runtime/error.go
src/runtime/os_plan9.go
src/runtime/panic.go
src/runtime/panic32.go [new file with mode: 0644]
test/codegen/memcombine.go
test/fixedbugs/issue15002.go
test/fixedbugs/issue30116.go [new file with mode: 0644]
test/fixedbugs/issue30116.out [new file with mode: 0644]
test/fixedbugs/issue30116u.go [new file with mode: 0644]
test/fixedbugs/issue30116u.out [new file with mode: 0644]

index b9fca18d4f242242a4901ffc7db9b042b64135f5..48b4f7d0b5138b3ebffa8c488017353a31c8ae7d 100644 (file)
@@ -926,6 +926,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
 
+       case ssa.OpAMD64LoweredPanicBoundsA, ssa.OpAMD64LoweredPanicBoundsB, ssa.OpAMD64LoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(int64(2 * gc.Widthptr)) // space used in callee args area by assembly stubs
+
+       case ssa.OpAMD64LoweredPanicExtendA, ssa.OpAMD64LoweredPanicExtendB, ssa.OpAMD64LoweredPanicExtendC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+               s.UseArgs(int64(3 * gc.Widthptr)) // space used in callee args area by assembly stubs
+
        case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
                ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
                ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
index 320fe9870785adbed9f7af5fded1f4280486c3cf..8af6b1e6ed18628816f44dadaa3cbfe0147957e9 100644 (file)
@@ -711,6 +711,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
+       case ssa.OpARMLoweredPanicBoundsA, ssa.OpARMLoweredPanicBoundsB, ssa.OpARMLoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.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 = gc.ExtendCheckFunc[v.AuxInt]
+               s.UseArgs(12) // space used in callee args area by assembly stubs
        case ssa.OpARMDUFFZERO:
                p := s.Prog(obj.ADUFFZERO)
                p.To.Type = obj.TYPE_MEM
index 0ea3c191acdfab3450915a46436ebd9e5a87bd86..75cf1d0bd9ce26d5cc66eff2550940470fc24eb8 100644 (file)
@@ -846,6 +846,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
+       case ssa.OpARM64LoweredPanicBoundsA, ssa.OpARM64LoweredPanicBoundsB, ssa.OpARM64LoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(16) // space used in callee args area by assembly stubs
        case ssa.OpARM64LoweredNilCheck:
                // Issue a load which will fault if arg is nil.
                p := s.Prog(arm64.AMOVB)
index f32fcd675d84cb26a0215318a7f70aff1f8eb970..8244929f744d99a5feb637da0e313260d6580242 100644 (file)
@@ -10,8 +10,6 @@ var runtimeDecls = [...]struct {
        typ  int
 }{
        {"newobject", funcTag, 4},
-       {"panicindex", funcTag, 5},
-       {"panicslice", funcTag, 5},
        {"panicdivide", funcTag, 5},
        {"panicshift", funcTag, 5},
        {"panicmakeslicelen", funcTag, 5},
@@ -20,138 +18,154 @@ var runtimeDecls = [...]struct {
        {"gopanic", funcTag, 7},
        {"gorecover", funcTag, 10},
        {"goschedguarded", funcTag, 5},
-       {"printbool", funcTag, 12},
-       {"printfloat", funcTag, 14},
-       {"printint", funcTag, 16},
-       {"printhex", funcTag, 18},
-       {"printuint", funcTag, 18},
-       {"printcomplex", funcTag, 20},
-       {"printstring", funcTag, 22},
-       {"printpointer", funcTag, 23},
-       {"printiface", funcTag, 23},
-       {"printeface", funcTag, 23},
-       {"printslice", funcTag, 23},
+       {"goPanicIndex", funcTag, 12},
+       {"goPanicIndexU", funcTag, 14},
+       {"goPanicSliceAlen", funcTag, 12},
+       {"goPanicSliceAlenU", funcTag, 14},
+       {"goPanicSliceAcap", funcTag, 12},
+       {"goPanicSliceAcapU", funcTag, 14},
+       {"goPanicSliceB", funcTag, 12},
+       {"goPanicSliceBU", funcTag, 14},
+       {"goPanicSlice3Alen", funcTag, 12},
+       {"goPanicSlice3AlenU", funcTag, 14},
+       {"goPanicSlice3Acap", funcTag, 12},
+       {"goPanicSlice3AcapU", funcTag, 14},
+       {"goPanicSlice3B", funcTag, 12},
+       {"goPanicSlice3BU", funcTag, 14},
+       {"goPanicSlice3C", funcTag, 12},
+       {"goPanicSlice3CU", funcTag, 14},
+       {"printbool", funcTag, 16},
+       {"printfloat", funcTag, 18},
+       {"printint", funcTag, 20},
+       {"printhex", funcTag, 22},
+       {"printuint", funcTag, 22},
+       {"printcomplex", funcTag, 24},
+       {"printstring", funcTag, 26},
+       {"printpointer", funcTag, 27},
+       {"printiface", funcTag, 27},
+       {"printeface", funcTag, 27},
+       {"printslice", funcTag, 27},
        {"printnl", funcTag, 5},
        {"printsp", funcTag, 5},
        {"printlock", funcTag, 5},
        {"printunlock", funcTag, 5},
-       {"concatstring2", funcTag, 26},
-       {"concatstring3", funcTag, 27},
-       {"concatstring4", funcTag, 28},
-       {"concatstring5", funcTag, 29},
-       {"concatstrings", funcTag, 31},
-       {"cmpstring", funcTag, 33},
-       {"intstring", funcTag, 36},
-       {"slicebytetostring", funcTag, 38},
-       {"slicebytetostringtmp", funcTag, 39},
-       {"slicerunetostring", funcTag, 42},
-       {"stringtoslicebyte", funcTag, 43},
-       {"stringtoslicerune", funcTag, 46},
-       {"slicecopy", funcTag, 48},
-       {"slicestringcopy", funcTag, 49},
-       {"decoderune", funcTag, 50},
-       {"countrunes", funcTag, 51},
-       {"convI2I", funcTag, 52},
-       {"convT16", funcTag, 54},
-       {"convT32", funcTag, 54},
-       {"convT64", funcTag, 54},
-       {"convTstring", funcTag, 54},
-       {"convTslice", funcTag, 54},
-       {"convT2E", funcTag, 55},
-       {"convT2Enoptr", funcTag, 55},
-       {"convT2I", funcTag, 55},
-       {"convT2Inoptr", funcTag, 55},
-       {"assertE2I", funcTag, 52},
-       {"assertE2I2", funcTag, 56},
-       {"assertI2I", funcTag, 52},
-       {"assertI2I2", funcTag, 56},
-       {"panicdottypeE", funcTag, 57},
-       {"panicdottypeI", funcTag, 57},
-       {"panicnildottype", funcTag, 58},
-       {"ifaceeq", funcTag, 60},
-       {"efaceeq", funcTag, 60},
-       {"fastrand", funcTag, 62},
-       {"makemap64", funcTag, 64},
-       {"makemap", funcTag, 65},
-       {"makemap_small", funcTag, 66},
-       {"mapaccess1", funcTag, 67},
-       {"mapaccess1_fast32", funcTag, 68},
-       {"mapaccess1_fast64", funcTag, 68},
-       {"mapaccess1_faststr", funcTag, 68},
-       {"mapaccess1_fat", funcTag, 69},
-       {"mapaccess2", funcTag, 70},
-       {"mapaccess2_fast32", funcTag, 71},
-       {"mapaccess2_fast64", funcTag, 71},
-       {"mapaccess2_faststr", funcTag, 71},
-       {"mapaccess2_fat", funcTag, 72},
-       {"mapassign", funcTag, 67},
-       {"mapassign_fast32", funcTag, 68},
-       {"mapassign_fast32ptr", funcTag, 68},
-       {"mapassign_fast64", funcTag, 68},
-       {"mapassign_fast64ptr", funcTag, 68},
-       {"mapassign_faststr", funcTag, 68},
-       {"mapiterinit", funcTag, 73},
-       {"mapdelete", funcTag, 73},
-       {"mapdelete_fast32", funcTag, 74},
-       {"mapdelete_fast64", funcTag, 74},
-       {"mapdelete_faststr", funcTag, 74},
-       {"mapiternext", funcTag, 75},
-       {"mapclear", funcTag, 76},
-       {"makechan64", funcTag, 78},
-       {"makechan", funcTag, 79},
-       {"chanrecv1", funcTag, 81},
-       {"chanrecv2", funcTag, 82},
-       {"chansend1", funcTag, 84},
-       {"closechan", funcTag, 23},
-       {"writeBarrier", varTag, 86},
-       {"typedmemmove", funcTag, 87},
-       {"typedmemclr", funcTag, 88},
-       {"typedslicecopy", funcTag, 89},
-       {"selectnbsend", funcTag, 90},
-       {"selectnbrecv", funcTag, 91},
-       {"selectnbrecv2", funcTag, 93},
-       {"selectsetpc", funcTag, 58},
-       {"selectgo", funcTag, 94},
+       {"concatstring2", funcTag, 30},
+       {"concatstring3", funcTag, 31},
+       {"concatstring4", funcTag, 32},
+       {"concatstring5", funcTag, 33},
+       {"concatstrings", funcTag, 35},
+       {"cmpstring", funcTag, 36},
+       {"intstring", funcTag, 39},
+       {"slicebytetostring", funcTag, 41},
+       {"slicebytetostringtmp", funcTag, 42},
+       {"slicerunetostring", funcTag, 45},
+       {"stringtoslicebyte", funcTag, 46},
+       {"stringtoslicerune", funcTag, 49},
+       {"slicecopy", funcTag, 51},
+       {"slicestringcopy", funcTag, 52},
+       {"decoderune", funcTag, 53},
+       {"countrunes", funcTag, 54},
+       {"convI2I", funcTag, 55},
+       {"convT16", funcTag, 57},
+       {"convT32", funcTag, 57},
+       {"convT64", funcTag, 57},
+       {"convTstring", funcTag, 57},
+       {"convTslice", funcTag, 57},
+       {"convT2E", funcTag, 58},
+       {"convT2Enoptr", funcTag, 58},
+       {"convT2I", funcTag, 58},
+       {"convT2Inoptr", funcTag, 58},
+       {"assertE2I", funcTag, 55},
+       {"assertE2I2", funcTag, 59},
+       {"assertI2I", funcTag, 55},
+       {"assertI2I2", funcTag, 59},
+       {"panicdottypeE", funcTag, 60},
+       {"panicdottypeI", funcTag, 60},
+       {"panicnildottype", funcTag, 61},
+       {"ifaceeq", funcTag, 63},
+       {"efaceeq", funcTag, 63},
+       {"fastrand", funcTag, 65},
+       {"makemap64", funcTag, 67},
+       {"makemap", funcTag, 68},
+       {"makemap_small", funcTag, 69},
+       {"mapaccess1", funcTag, 70},
+       {"mapaccess1_fast32", funcTag, 71},
+       {"mapaccess1_fast64", funcTag, 71},
+       {"mapaccess1_faststr", funcTag, 71},
+       {"mapaccess1_fat", funcTag, 72},
+       {"mapaccess2", funcTag, 73},
+       {"mapaccess2_fast32", funcTag, 74},
+       {"mapaccess2_fast64", funcTag, 74},
+       {"mapaccess2_faststr", funcTag, 74},
+       {"mapaccess2_fat", funcTag, 75},
+       {"mapassign", funcTag, 70},
+       {"mapassign_fast32", funcTag, 71},
+       {"mapassign_fast32ptr", funcTag, 71},
+       {"mapassign_fast64", funcTag, 71},
+       {"mapassign_fast64ptr", funcTag, 71},
+       {"mapassign_faststr", funcTag, 71},
+       {"mapiterinit", funcTag, 76},
+       {"mapdelete", funcTag, 76},
+       {"mapdelete_fast32", funcTag, 77},
+       {"mapdelete_fast64", funcTag, 77},
+       {"mapdelete_faststr", funcTag, 77},
+       {"mapiternext", funcTag, 78},
+       {"mapclear", funcTag, 79},
+       {"makechan64", funcTag, 81},
+       {"makechan", funcTag, 82},
+       {"chanrecv1", funcTag, 84},
+       {"chanrecv2", funcTag, 85},
+       {"chansend1", funcTag, 87},
+       {"closechan", funcTag, 27},
+       {"writeBarrier", varTag, 89},
+       {"typedmemmove", funcTag, 90},
+       {"typedmemclr", funcTag, 91},
+       {"typedslicecopy", funcTag, 92},
+       {"selectnbsend", funcTag, 93},
+       {"selectnbrecv", funcTag, 94},
+       {"selectnbrecv2", funcTag, 96},
+       {"selectsetpc", funcTag, 61},
+       {"selectgo", funcTag, 97},
        {"block", funcTag, 5},
-       {"makeslice", funcTag, 95},
-       {"makeslice64", funcTag, 96},
-       {"growslice", funcTag, 98},
-       {"memmove", funcTag, 99},
-       {"memclrNoHeapPointers", funcTag, 100},
-       {"memclrHasPointers", funcTag, 100},
-       {"memequal", funcTag, 101},
-       {"memequal8", funcTag, 102},
-       {"memequal16", funcTag, 102},
-       {"memequal32", funcTag, 102},
-       {"memequal64", funcTag, 102},
-       {"memequal128", funcTag, 102},
-       {"int64div", funcTag, 103},
-       {"uint64div", funcTag, 104},
-       {"int64mod", funcTag, 103},
-       {"uint64mod", funcTag, 104},
-       {"float64toint64", funcTag, 105},
-       {"float64touint64", funcTag, 106},
-       {"float64touint32", funcTag, 107},
-       {"int64tofloat64", funcTag, 108},
-       {"uint64tofloat64", funcTag, 109},
-       {"uint32tofloat64", funcTag, 110},
-       {"complex128div", funcTag, 111},
-       {"racefuncenter", funcTag, 112},
+       {"makeslice", funcTag, 98},
+       {"makeslice64", funcTag, 99},
+       {"growslice", funcTag, 101},
+       {"memmove", funcTag, 102},
+       {"memclrNoHeapPointers", funcTag, 103},
+       {"memclrHasPointers", funcTag, 103},
+       {"memequal", funcTag, 104},
+       {"memequal8", funcTag, 105},
+       {"memequal16", funcTag, 105},
+       {"memequal32", funcTag, 105},
+       {"memequal64", funcTag, 105},
+       {"memequal128", funcTag, 105},
+       {"int64div", funcTag, 106},
+       {"uint64div", funcTag, 107},
+       {"int64mod", funcTag, 106},
+       {"uint64mod", funcTag, 107},
+       {"float64toint64", funcTag, 108},
+       {"float64touint64", funcTag, 109},
+       {"float64touint32", funcTag, 110},
+       {"int64tofloat64", funcTag, 111},
+       {"uint64tofloat64", funcTag, 112},
+       {"uint32tofloat64", funcTag, 113},
+       {"complex128div", funcTag, 114},
+       {"racefuncenter", funcTag, 115},
        {"racefuncenterfp", funcTag, 5},
        {"racefuncexit", funcTag, 5},
-       {"raceread", funcTag, 112},
-       {"racewrite", funcTag, 112},
-       {"racereadrange", funcTag, 113},
-       {"racewriterange", funcTag, 113},
-       {"msanread", funcTag, 113},
-       {"msanwrite", funcTag, 113},
-       {"x86HasPOPCNT", varTag, 11},
-       {"x86HasSSE41", varTag, 11},
-       {"arm64HasATOMICS", varTag, 11},
+       {"raceread", funcTag, 115},
+       {"racewrite", funcTag, 115},
+       {"racereadrange", funcTag, 116},
+       {"racewriterange", funcTag, 116},
+       {"msanread", funcTag, 116},
+       {"msanwrite", funcTag, 116},
+       {"x86HasPOPCNT", varTag, 15},
+       {"x86HasSSE41", varTag, 15},
+       {"arm64HasATOMICS", varTag, 15},
 }
 
 func runtimeTypes() []*types.Type {
-       var typs [114]*types.Type
+       var typs [117]*types.Type
        typs[0] = types.Bytetype
        typs[1] = types.NewPtr(typs[0])
        typs[2] = types.Types[TANY]
@@ -163,108 +177,111 @@ func runtimeTypes() []*types.Type {
        typs[8] = types.Types[TINT32]
        typs[9] = types.NewPtr(typs[8])
        typs[10] = functype(nil, []*Node{anonfield(typs[9])}, []*Node{anonfield(typs[6])})
-       typs[11] = types.Types[TBOOL]
-       typs[12] = functype(nil, []*Node{anonfield(typs[11])}, nil)
-       typs[13] = types.Types[TFLOAT64]
-       typs[14] = functype(nil, []*Node{anonfield(typs[13])}, nil)
-       typs[15] = types.Types[TINT64]
+       typs[11] = types.Types[TINT]
+       typs[12] = functype(nil, []*Node{anonfield(typs[11]), anonfield(typs[11])}, nil)
+       typs[13] = types.Types[TUINT]
+       typs[14] = functype(nil, []*Node{anonfield(typs[13]), anonfield(typs[11])}, nil)
+       typs[15] = types.Types[TBOOL]
        typs[16] = functype(nil, []*Node{anonfield(typs[15])}, nil)
-       typs[17] = types.Types[TUINT64]
+       typs[17] = types.Types[TFLOAT64]
        typs[18] = functype(nil, []*Node{anonfield(typs[17])}, nil)
-       typs[19] = types.Types[TCOMPLEX128]
+       typs[19] = types.Types[TINT64]
        typs[20] = functype(nil, []*Node{anonfield(typs[19])}, nil)
-       typs[21] = types.Types[TSTRING]
+       typs[21] = types.Types[TUINT64]
        typs[22] = functype(nil, []*Node{anonfield(typs[21])}, nil)
-       typs[23] = functype(nil, []*Node{anonfield(typs[2])}, nil)
-       typs[24] = types.NewArray(typs[0], 32)
-       typs[25] = types.NewPtr(typs[24])
-       typs[26] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
-       typs[27] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
-       typs[28] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
-       typs[29] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
-       typs[30] = types.NewSlice(typs[21])
-       typs[31] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[30])}, []*Node{anonfield(typs[21])})
-       typs[32] = types.Types[TINT]
-       typs[33] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[32])})
-       typs[34] = types.NewArray(typs[0], 4)
-       typs[35] = types.NewPtr(typs[34])
-       typs[36] = functype(nil, []*Node{anonfield(typs[35]), anonfield(typs[15])}, []*Node{anonfield(typs[21])})
-       typs[37] = types.NewSlice(typs[0])
-       typs[38] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[37])}, []*Node{anonfield(typs[21])})
-       typs[39] = functype(nil, []*Node{anonfield(typs[37])}, []*Node{anonfield(typs[21])})
-       typs[40] = types.Runetype
-       typs[41] = types.NewSlice(typs[40])
-       typs[42] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[41])}, []*Node{anonfield(typs[21])})
-       typs[43] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21])}, []*Node{anonfield(typs[37])})
-       typs[44] = types.NewArray(typs[40], 32)
-       typs[45] = types.NewPtr(typs[44])
-       typs[46] = functype(nil, []*Node{anonfield(typs[45]), anonfield(typs[21])}, []*Node{anonfield(typs[41])})
-       typs[47] = types.Types[TUINTPTR]
-       typs[48] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[47])}, []*Node{anonfield(typs[32])})
-       typs[49] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
-       typs[50] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[32])}, []*Node{anonfield(typs[40]), anonfield(typs[32])})
-       typs[51] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[32])})
-       typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
-       typs[53] = types.Types[TUNSAFEPTR]
-       typs[54] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[53])})
-       typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
-       typs[56] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[11])})
-       typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
-       typs[58] = functype(nil, []*Node{anonfield(typs[1])}, nil)
-       typs[59] = types.NewPtr(typs[47])
-       typs[60] = functype(nil, []*Node{anonfield(typs[59]), anonfield(typs[53]), anonfield(typs[53])}, []*Node{anonfield(typs[11])})
-       typs[61] = types.Types[TUINT32]
-       typs[62] = functype(nil, nil, []*Node{anonfield(typs[61])})
-       typs[63] = types.NewMap(typs[2], typs[2])
-       typs[64] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[63])})
-       typs[65] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[3])}, []*Node{anonfield(typs[63])})
-       typs[66] = functype(nil, nil, []*Node{anonfield(typs[63])})
-       typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
-       typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
-       typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-       typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-       typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-       typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[11])})
-       typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[3])}, nil)
-       typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[2])}, nil)
-       typs[75] = functype(nil, []*Node{anonfield(typs[3])}, nil)
-       typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[63])}, nil)
-       typs[77] = types.NewChan(typs[2], types.Cboth)
-       typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[77])})
-       typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[77])})
-       typs[80] = types.NewChan(typs[2], types.Crecv)
-       typs[81] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, nil)
-       typs[82] = functype(nil, []*Node{anonfield(typs[80]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-       typs[83] = types.NewChan(typs[2], types.Csend)
+       typs[23] = types.Types[TCOMPLEX128]
+       typs[24] = functype(nil, []*Node{anonfield(typs[23])}, nil)
+       typs[25] = types.Types[TSTRING]
+       typs[26] = functype(nil, []*Node{anonfield(typs[25])}, nil)
+       typs[27] = functype(nil, []*Node{anonfield(typs[2])}, nil)
+       typs[28] = types.NewArray(typs[0], 32)
+       typs[29] = types.NewPtr(typs[28])
+       typs[30] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
+       typs[31] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
+       typs[32] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
+       typs[33] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[25])})
+       typs[34] = types.NewSlice(typs[25])
+       typs[35] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[34])}, []*Node{anonfield(typs[25])})
+       typs[36] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[25])}, []*Node{anonfield(typs[11])})
+       typs[37] = types.NewArray(typs[0], 4)
+       typs[38] = types.NewPtr(typs[37])
+       typs[39] = functype(nil, []*Node{anonfield(typs[38]), anonfield(typs[19])}, []*Node{anonfield(typs[25])})
+       typs[40] = types.NewSlice(typs[0])
+       typs[41] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[40])}, []*Node{anonfield(typs[25])})
+       typs[42] = functype(nil, []*Node{anonfield(typs[40])}, []*Node{anonfield(typs[25])})
+       typs[43] = types.Runetype
+       typs[44] = types.NewSlice(typs[43])
+       typs[45] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[44])}, []*Node{anonfield(typs[25])})
+       typs[46] = functype(nil, []*Node{anonfield(typs[29]), anonfield(typs[25])}, []*Node{anonfield(typs[40])})
+       typs[47] = types.NewArray(typs[43], 32)
+       typs[48] = types.NewPtr(typs[47])
+       typs[49] = functype(nil, []*Node{anonfield(typs[48]), anonfield(typs[25])}, []*Node{anonfield(typs[44])})
+       typs[50] = types.Types[TUINTPTR]
+       typs[51] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[50])}, []*Node{anonfield(typs[11])})
+       typs[52] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[11])})
+       typs[53] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[11])}, []*Node{anonfield(typs[43]), anonfield(typs[11])})
+       typs[54] = functype(nil, []*Node{anonfield(typs[25])}, []*Node{anonfield(typs[11])})
+       typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
+       typs[56] = types.Types[TUNSAFEPTR]
+       typs[57] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[56])})
+       typs[58] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
+       typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[15])})
+       typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+       typs[61] = functype(nil, []*Node{anonfield(typs[1])}, nil)
+       typs[62] = types.NewPtr(typs[50])
+       typs[63] = functype(nil, []*Node{anonfield(typs[62]), anonfield(typs[56]), anonfield(typs[56])}, []*Node{anonfield(typs[15])})
+       typs[64] = types.Types[TUINT32]
+       typs[65] = functype(nil, nil, []*Node{anonfield(typs[64])})
+       typs[66] = types.NewMap(typs[2], typs[2])
+       typs[67] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
+       typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[3])}, []*Node{anonfield(typs[66])})
+       typs[69] = functype(nil, nil, []*Node{anonfield(typs[66])})
+       typs[70] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
+       typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
+       typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
+       typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
+       typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
+       typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[15])})
+       typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[3])}, nil)
+       typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66]), anonfield(typs[2])}, nil)
+       typs[78] = functype(nil, []*Node{anonfield(typs[3])}, nil)
+       typs[79] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[66])}, nil)
+       typs[80] = types.NewChan(typs[2], types.Cboth)
+       typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19])}, []*Node{anonfield(typs[80])})
+       typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[80])})
+       typs[83] = types.NewChan(typs[2], types.Crecv)
        typs[84] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, nil)
-       typs[85] = types.NewArray(typs[0], 3)
-       typs[86] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[85]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])})
-       typs[87] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
-       typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
-       typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])})
-       typs[90] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-       typs[91] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[80])}, []*Node{anonfield(typs[11])})
-       typs[92] = types.NewPtr(typs[11])
-       typs[93] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[92]), anonfield(typs[80])}, []*Node{anonfield(typs[11])})
-       typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[32])}, []*Node{anonfield(typs[32]), anonfield(typs[11])})
-       typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[53])})
-       typs[96] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[53])})
-       typs[97] = types.NewSlice(typs[2])
-       typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[97]), anonfield(typs[32])}, []*Node{anonfield(typs[97])})
-       typs[99] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[47])}, nil)
-       typs[100] = functype(nil, []*Node{anonfield(typs[53]), anonfield(typs[47])}, nil)
-       typs[101] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[47])}, []*Node{anonfield(typs[11])})
-       typs[102] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[11])})
-       typs[103] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
-       typs[104] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])})
-       typs[105] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])})
-       typs[106] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])})
-       typs[107] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[61])})
-       typs[108] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])})
-       typs[109] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])})
-       typs[110] = functype(nil, []*Node{anonfield(typs[61])}, []*Node{anonfield(typs[13])})
-       typs[111] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
-       typs[112] = functype(nil, []*Node{anonfield(typs[47])}, nil)
-       typs[113] = functype(nil, []*Node{anonfield(typs[47]), anonfield(typs[47])}, nil)
+       typs[85] = functype(nil, []*Node{anonfield(typs[83]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
+       typs[86] = types.NewChan(typs[2], types.Csend)
+       typs[87] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, nil)
+       typs[88] = types.NewArray(typs[0], 3)
+       typs[89] = tostruct([]*Node{namedfield("enabled", typs[15]), namedfield("pad", typs[88]), namedfield("needed", typs[15]), namedfield("cgo", typs[15]), namedfield("alignme", typs[21])})
+       typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+       typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
+       typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[11])})
+       typs[93] = functype(nil, []*Node{anonfield(typs[86]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
+       typs[94] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
+       typs[95] = types.NewPtr(typs[15])
+       typs[96] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[95]), anonfield(typs[83])}, []*Node{anonfield(typs[15])})
+       typs[97] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[11])}, []*Node{anonfield(typs[11]), anonfield(typs[15])})
+       typs[98] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[11]), anonfield(typs[11])}, []*Node{anonfield(typs[56])})
+       typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[56])})
+       typs[100] = types.NewSlice(typs[2])
+       typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[100]), anonfield(typs[11])}, []*Node{anonfield(typs[100])})
+       typs[102] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, nil)
+       typs[103] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, nil)
+       typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[15])})
+       typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
+       typs[106] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
+       typs[107] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
+       typs[108] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[19])})
+       typs[109] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[21])})
+       typs[110] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[64])})
+       typs[111] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[17])})
+       typs[112] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[17])})
+       typs[113] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[17])})
+       typs[114] = functype(nil, []*Node{anonfield(typs[23]), anonfield(typs[23])}, []*Node{anonfield(typs[23])})
+       typs[115] = functype(nil, []*Node{anonfield(typs[50])}, nil)
+       typs[116] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
        return typs[:]
 }
index 210881a6e99011c5c3633d8a587a16f3af7c48f6..a8a9b061ec81908a8d3eb07feae5817c1ad345e9 100644 (file)
@@ -15,8 +15,6 @@ package runtime
 import "unsafe"
 
 func newobject(typ *byte) *any
-func panicindex()
-func panicslice()
 func panicdivide()
 func panicshift()
 func panicmakeslicelen()
@@ -27,6 +25,25 @@ func gopanic(interface{})
 func gorecover(*int32) interface{}
 func goschedguarded()
 
+// Note: these declarations are just for wasm port.
+// Other ports call assembly stubs instead.
+func goPanicIndex(x int, y int)
+func goPanicIndexU(x uint, y int)
+func goPanicSliceAlen(x int, y int)
+func goPanicSliceAlenU(x uint, y int)
+func goPanicSliceAcap(x int, y int)
+func goPanicSliceAcapU(x uint, y int)
+func goPanicSliceB(x int, y int)
+func goPanicSliceBU(x uint, y int)
+func goPanicSlice3Alen(x int, y int)
+func goPanicSlice3AlenU(x uint, y int)
+func goPanicSlice3Acap(x int, y int)
+func goPanicSlice3AcapU(x uint, y int)
+func goPanicSlice3B(x int, y int)
+func goPanicSlice3BU(x uint, y int)
+func goPanicSlice3C(x int, y int)
+func goPanicSlice3CU(x uint, y int)
+
 func printbool(bool)
 func printfloat(float64)
 func printint(int64)
index 007585ef104401e8be323ad7576cd7c1b37b46ac..5f2c3289095434a46d24f25dc1c4424dc2da50c6 100644 (file)
@@ -300,10 +300,8 @@ var (
        panicshift,
        panicdottypeE,
        panicdottypeI,
-       panicindex,
        panicnildottype,
        panicoverflow,
-       panicslice,
        raceread,
        racereadrange,
        racewrite,
@@ -316,6 +314,9 @@ var (
        Udiv,
        writeBarrier *obj.LSym
 
+       BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
+       ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
+
        // GO386=387
        ControlWord64trunc,
        ControlWord32 *obj.LSym
index 3ccb59e105d67425aee9975236d6f6c7caf49129..031c3c072c26e2064a5761c0f7c2f64a7d64f2cd 100644 (file)
@@ -80,10 +80,8 @@ func initssaconfig() {
        panicdivide = sysfunc("panicdivide")
        panicdottypeE = sysfunc("panicdottypeE")
        panicdottypeI = sysfunc("panicdottypeI")
-       panicindex = sysfunc("panicindex")
        panicnildottype = sysfunc("panicnildottype")
        panicoverflow = sysfunc("panicoverflow")
-       panicslice = sysfunc("panicslice")
        panicshift = sysfunc("panicshift")
        raceread = sysfunc("raceread")
        racereadrange = sysfunc("racereadrange")
@@ -96,6 +94,59 @@ func initssaconfig() {
        typedmemmove = sysfunc("typedmemmove")
        Udiv = sysvar("udiv")                 // asm func with special ABI
        writeBarrier = sysvar("writeBarrier") // struct { bool; ... }
+       if thearch.LinkArch.Family == sys.Wasm {
+               BoundsCheckFunc[ssa.BoundsIndex] = sysvar("goPanicIndex")
+               BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("goPanicIndexU")
+               BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("goPanicSliceAlen")
+               BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("goPanicSliceAlenU")
+               BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("goPanicSliceAcap")
+               BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("goPanicSliceAcapU")
+               BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("goPanicSliceB")
+               BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("goPanicSliceBU")
+               BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("goPanicSlice3Alen")
+               BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("goPanicSlice3AlenU")
+               BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("goPanicSlice3Acap")
+               BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("goPanicSlice3AcapU")
+               BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("goPanicSlice3B")
+               BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("goPanicSlice3BU")
+               BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("goPanicSlice3C")
+               BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("goPanicSlice3CU")
+       } else {
+               BoundsCheckFunc[ssa.BoundsIndex] = sysvar("panicIndex")
+               BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("panicIndexU")
+               BoundsCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicSliceAlen")
+               BoundsCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicSliceAlenU")
+               BoundsCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicSliceAcap")
+               BoundsCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicSliceAcapU")
+               BoundsCheckFunc[ssa.BoundsSliceB] = sysvar("panicSliceB")
+               BoundsCheckFunc[ssa.BoundsSliceBU] = sysvar("panicSliceBU")
+               BoundsCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicSlice3Alen")
+               BoundsCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicSlice3AlenU")
+               BoundsCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicSlice3Acap")
+               BoundsCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicSlice3AcapU")
+               BoundsCheckFunc[ssa.BoundsSlice3B] = sysvar("panicSlice3B")
+               BoundsCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicSlice3BU")
+               BoundsCheckFunc[ssa.BoundsSlice3C] = sysvar("panicSlice3C")
+               BoundsCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicSlice3CU")
+       }
+       if thearch.LinkArch.PtrSize == 4 {
+               ExtendCheckFunc[ssa.BoundsIndex] = sysvar("panicExtendIndex")
+               ExtendCheckFunc[ssa.BoundsIndexU] = sysvar("panicExtendIndexU")
+               ExtendCheckFunc[ssa.BoundsSliceAlen] = sysvar("panicExtendSliceAlen")
+               ExtendCheckFunc[ssa.BoundsSliceAlenU] = sysvar("panicExtendSliceAlenU")
+               ExtendCheckFunc[ssa.BoundsSliceAcap] = sysvar("panicExtendSliceAcap")
+               ExtendCheckFunc[ssa.BoundsSliceAcapU] = sysvar("panicExtendSliceAcapU")
+               ExtendCheckFunc[ssa.BoundsSliceB] = sysvar("panicExtendSliceB")
+               ExtendCheckFunc[ssa.BoundsSliceBU] = sysvar("panicExtendSliceBU")
+               ExtendCheckFunc[ssa.BoundsSlice3Alen] = sysvar("panicExtendSlice3Alen")
+               ExtendCheckFunc[ssa.BoundsSlice3AlenU] = sysvar("panicExtendSlice3AlenU")
+               ExtendCheckFunc[ssa.BoundsSlice3Acap] = sysvar("panicExtendSlice3Acap")
+               ExtendCheckFunc[ssa.BoundsSlice3AcapU] = sysvar("panicExtendSlice3AcapU")
+               ExtendCheckFunc[ssa.BoundsSlice3B] = sysvar("panicExtendSlice3B")
+               ExtendCheckFunc[ssa.BoundsSlice3BU] = sysvar("panicExtendSlice3BU")
+               ExtendCheckFunc[ssa.BoundsSlice3C] = sysvar("panicExtendSlice3C")
+               ExtendCheckFunc[ssa.BoundsSlice3CU] = sysvar("panicExtendSlice3CU")
+       }
 
        // GO386=387 runtime definitions
        ControlWord64trunc = sysvar("controlWord64trunc") // uint16
@@ -575,6 +626,11 @@ func (s *state) newValue4(op ssa.Op, t *types.Type, arg0, arg1, arg2, arg3 *ssa.
        return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
 }
 
+// newValue4 adds a new value with four arguments and an auxint value to the current block.
+func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
+       return s.curBlock.NewValue4I(s.peekPos(), op, t, aux, arg0, arg1, arg2, arg3)
+}
+
 // entryNewValue0 adds a new value with no arguments to the entry block.
 func (s *state) entryNewValue0(op ssa.Op, t *types.Type) *ssa.Value {
        return s.f.Entry.NewValue0(src.NoXPos, op, t)
@@ -2262,11 +2318,8 @@ func (s *state) expr(n *Node) *ssa.Value {
                        }
                        a := s.expr(n.Left)
                        i := s.expr(n.Right)
-                       i = s.extendIndex(i, panicindex)
-                       if !n.Bounded() {
-                               len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
-                               s.boundsCheck(i, len)
-                       }
+                       len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
+                       i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        ptrtyp := s.f.Config.Types.BytePtr
                        ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
                        if Isconst(n.Right, CTINT) {
@@ -2288,14 +2341,12 @@ func (s *state) expr(n *Node) *ssa.Value {
                                        // Bounds check will never succeed.  Might as well
                                        // use constants for the bounds check.
                                        z := s.constInt(types.Types[TINT], 0)
-                                       s.boundsCheck(z, z)
+                                       s.boundsCheck(z, z, ssa.BoundsIndex, false)
                                        // The return value won't be live, return junk.
                                        return s.newValue0(ssa.OpUnknown, n.Type)
                                }
-                               i = s.extendIndex(i, panicindex)
-                               if !n.Bounded() {
-                                       s.boundsCheck(i, s.constInt(types.Types[TINT], bound))
-                               }
+                               len := s.constInt(types.Types[TINT], bound)
+                               i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                                return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a)
                        }
                        p := s.addr(n, false)
@@ -2353,13 +2404,13 @@ func (s *state) expr(n *Node) *ssa.Value {
                var i, j, k *ssa.Value
                low, high, max := n.SliceBounds()
                if low != nil {
-                       i = s.extendIndex(s.expr(low), panicslice)
+                       i = s.expr(low)
                }
                if high != nil {
-                       j = s.extendIndex(s.expr(high), panicslice)
+                       j = s.expr(high)
                }
                if max != nil {
-                       k = s.extendIndex(s.expr(max), panicslice)
+                       k = s.expr(max)
                }
                p, l, c := s.slice(n.Left.Type, v, i, j, k, n.Bounded())
                return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
@@ -2369,10 +2420,10 @@ func (s *state) expr(n *Node) *ssa.Value {
                var i, j *ssa.Value
                low, high, _ := n.SliceBounds()
                if low != nil {
-                       i = s.extendIndex(s.expr(low), panicslice)
+                       i = s.expr(low)
                }
                if high != nil {
-                       j = s.extendIndex(s.expr(high), panicslice)
+                       j = s.expr(high)
                }
                p, l, _ := s.slice(n.Left.Type, v, i, j, nil, n.Bounded())
                return s.newValue2(ssa.OpStringMake, n.Type, p, l)
@@ -2680,15 +2731,15 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                                // The bounds check must fail.  Might as well
                                // ignore the actual index and just use zeros.
                                z := s.constInt(types.Types[TINT], 0)
-                               s.boundsCheck(z, z)
+                               s.boundsCheck(z, z, ssa.BoundsIndex, false)
                                return
                        }
                        if n != 1 {
                                s.Fatalf("assigning to non-1-length array")
                        }
                        // Rewrite to a = [1]{v}
-                       i = s.extendIndex(i, panicindex)
-                       s.boundsCheck(i, s.constInt(types.Types[TINT], 1))
+                       len := s.constInt(types.Types[TINT], 1)
+                       i = s.boundsCheck(i, len, ssa.BoundsIndex, false)
                        v := s.newValue1(ssa.OpArrayMake1, t, right)
                        s.assign(left.Left, v, false, 0)
                        return
@@ -3875,21 +3926,15 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
                if n.Left.Type.IsSlice() {
                        a := s.expr(n.Left)
                        i := s.expr(n.Right)
-                       i = s.extendIndex(i, panicindex)
                        len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], a)
-                       if !n.Bounded() {
-                               s.boundsCheck(i, len)
-                       }
+                       i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        p := s.newValue1(ssa.OpSlicePtr, t, a)
                        return s.newValue2(ssa.OpPtrIndex, t, p, i)
                } else { // array
                        a := s.addr(n.Left, bounded)
                        i := s.expr(n.Right)
-                       i = s.extendIndex(i, panicindex)
                        len := s.constInt(types.Types[TINT], n.Left.Type.NumElem())
-                       if !n.Bounded() {
-                               s.boundsCheck(i, len)
-                       }
+                       i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i)
                }
        case ODEREF:
@@ -4028,32 +4073,70 @@ func (s *state) nilCheck(ptr *ssa.Value) {
        s.newValue2(ssa.OpNilCheck, types.TypeVoid, ptr, s.mem())
 }
 
-// boundsCheck generates bounds checking code. Checks if 0 <= idx < len, branches to exit if not.
-// len must be known to be nonnegative.
+// boundsCheck generates bounds checking code. Checks if 0 <= idx <[=] len, branches to exit if not.
 // Starts a new block on return.
-// idx is already converted to full int width.
-func (s *state) boundsCheck(idx, len *ssa.Value) {
-       if Debug['B'] != 0 {
-               return
+// On input, len must be converted to full int width and be nonnegative.
+// Returns idx converted to full int width.
+// If bounded is true then caller guarantees the index is not out of bounds
+// (but boundsCheck will still extend the index to full int width).
+func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
+       idx = s.extendIndex(idx, len, kind, bounded)
+
+       if bounded || Debug['B'] != 0 {
+               // If bounded or bounds checking is flag-disabled, then no check necessary,
+               // just return the extended index.
+               return idx
        }
 
-       // bounds check
-       cmp := s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
-       s.check(cmp, panicindex)
-}
+       bNext := s.f.NewBlock(ssa.BlockPlain)
+       bPanic := s.f.NewBlock(ssa.BlockExit)
+
+       if !idx.Type.IsSigned() {
+               switch kind {
+               case ssa.BoundsIndex:
+                       kind = ssa.BoundsIndexU
+               case ssa.BoundsSliceAlen:
+                       kind = ssa.BoundsSliceAlenU
+               case ssa.BoundsSliceAcap:
+                       kind = ssa.BoundsSliceAcapU
+               case ssa.BoundsSliceB:
+                       kind = ssa.BoundsSliceBU
+               case ssa.BoundsSlice3Alen:
+                       kind = ssa.BoundsSlice3AlenU
+               case ssa.BoundsSlice3Acap:
+                       kind = ssa.BoundsSlice3AcapU
+               case ssa.BoundsSlice3B:
+                       kind = ssa.BoundsSlice3BU
+               case ssa.BoundsSlice3C:
+                       kind = ssa.BoundsSlice3CU
+               }
+       }
+
+       var cmp *ssa.Value
+       if kind == ssa.BoundsIndex || kind == ssa.BoundsIndexU {
+               cmp = s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
+       } else {
+               cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
+       }
+       b := s.endBlock()
+       b.Kind = ssa.BlockIf
+       b.SetControl(cmp)
+       b.Likely = ssa.BranchLikely
+       b.AddEdgeTo(bNext)
+       b.AddEdgeTo(bPanic)
 
-// sliceBoundsCheck generates slice bounds checking code. Checks if 0 <= idx <= len, branches to exit if not.
-// len must be known to be nonnegative.
-// Starts a new block on return.
-// idx and len are already converted to full int width.
-func (s *state) sliceBoundsCheck(idx, len *ssa.Value) {
-       if Debug['B'] != 0 {
-               return
+       s.startBlock(bPanic)
+       if thearch.LinkArch.Family == sys.Wasm {
+               // TODO(khr): figure out how to do "register" based calling convention for bounds checks.
+               // Should be similar to gcWriteBarrier, but I can't make it work.
+               s.rtcall(BoundsCheckFunc[kind], false, nil, idx, len)
+       } else {
+               mem := s.newValue3I(ssa.OpPanicBounds, types.TypeMem, int64(kind), idx, len, s.mem())
+               s.endBlock().SetControl(mem)
        }
+       s.startBlock(bNext)
 
-       // bounds check
-       cmp := s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
-       s.check(cmp, panicslice)
+       return idx
 }
 
 // If cmp (a bool) is false, panic using the given function.
@@ -4307,21 +4390,36 @@ func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value, bounded bool) (p, l,
        if j == nil {
                j = len
        }
+       three := true
        if k == nil {
+               three = false
                k = cap
        }
 
-       if !bounded {
-               // Panic if slice indices are not in bounds.
-               // Make sure we check these in reverse order so that we're always
-               // comparing against a value known to be nonnegative. See issue 28797.
+       // Panic if slice indices are not in bounds.
+       // Make sure we check these in reverse order so that we're always
+       // comparing against a value known to be nonnegative. See issue 28797.
+       if three {
                if k != cap {
-                       s.sliceBoundsCheck(k, cap)
+                       kind := ssa.BoundsSlice3Alen
+                       if t.IsSlice() {
+                               kind = ssa.BoundsSlice3Acap
+                       }
+                       k = s.boundsCheck(k, cap, kind, bounded)
+               }
+               if j != k {
+                       j = s.boundsCheck(j, k, ssa.BoundsSlice3B, bounded)
                }
+               i = s.boundsCheck(i, j, ssa.BoundsSlice3C, bounded)
+       } else {
                if j != k {
-                       s.sliceBoundsCheck(j, k)
+                       kind := ssa.BoundsSliceAlen
+                       if t.IsSlice() {
+                               kind = ssa.BoundsSliceAcap
+                       }
+                       j = s.boundsCheck(j, k, kind, bounded)
                }
-               s.sliceBoundsCheck(i, j)
+               i = s.boundsCheck(i, j, ssa.BoundsSliceB, bounded)
        }
 
        // Generate the following code assuming that indexes are in bounds.
@@ -5432,26 +5530,66 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
 }
 
 // extendIndex extends v to a full int width.
-// panic using the given function if v does not fit in an int (only on 32-bit archs).
-func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
-       size := v.Type.Size()
+// panic with the given kind if v does not fit in an int (only on 32-bit archs).
+func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bool) *ssa.Value {
+       size := idx.Type.Size()
        if size == s.config.PtrSize {
-               return v
+               return idx
        }
        if size > s.config.PtrSize {
                // truncate 64-bit indexes on 32-bit pointer archs. Test the
                // high word and branch to out-of-bounds failure if it is not 0.
-               if Debug['B'] == 0 {
-                       hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], v)
-                       cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
-                       s.check(cmp, panicfn)
+               var lo *ssa.Value
+               if idx.Type.IsSigned() {
+                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[TINT], idx)
+               } else {
+                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
+               }
+               if bounded || Debug['B'] != 0 {
+                       return lo
+               }
+               bNext := s.f.NewBlock(ssa.BlockPlain)
+               bPanic := s.f.NewBlock(ssa.BlockExit)
+               hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], idx)
+               cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
+               if !idx.Type.IsSigned() {
+                       switch kind {
+                       case ssa.BoundsIndex:
+                               kind = ssa.BoundsIndexU
+                       case ssa.BoundsSliceAlen:
+                               kind = ssa.BoundsSliceAlenU
+                       case ssa.BoundsSliceAcap:
+                               kind = ssa.BoundsSliceAcapU
+                       case ssa.BoundsSliceB:
+                               kind = ssa.BoundsSliceBU
+                       case ssa.BoundsSlice3Alen:
+                               kind = ssa.BoundsSlice3AlenU
+                       case ssa.BoundsSlice3Acap:
+                               kind = ssa.BoundsSlice3AcapU
+                       case ssa.BoundsSlice3B:
+                               kind = ssa.BoundsSlice3BU
+                       case ssa.BoundsSlice3C:
+                               kind = ssa.BoundsSlice3CU
+                       }
                }
-               return s.newValue1(ssa.OpTrunc64to32, types.Types[TINT], v)
+               b := s.endBlock()
+               b.Kind = ssa.BlockIf
+               b.SetControl(cmp)
+               b.Likely = ssa.BranchLikely
+               b.AddEdgeTo(bNext)
+               b.AddEdgeTo(bPanic)
+
+               s.startBlock(bPanic)
+               mem := s.newValue4I(ssa.OpPanicExtend, types.TypeMem, int64(kind), hi, lo, len, s.mem())
+               s.endBlock().SetControl(mem)
+               s.startBlock(bNext)
+
+               return lo
        }
 
        // Extend value to the required size
        var op ssa.Op
-       if v.Type.IsSigned() {
+       if idx.Type.IsSigned() {
                switch 10*size + s.config.PtrSize {
                case 14:
                        op = ssa.OpSignExt8to32
@@ -5464,7 +5602,7 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
                case 48:
                        op = ssa.OpSignExt32to64
                default:
-                       s.Fatalf("bad signed index extension %s", v.Type)
+                       s.Fatalf("bad signed index extension %s", idx.Type)
                }
        } else {
                switch 10*size + s.config.PtrSize {
@@ -5479,10 +5617,10 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
                case 48:
                        op = ssa.OpZeroExt32to64
                default:
-                       s.Fatalf("bad unsigned index extension %s", v.Type)
+                       s.Fatalf("bad unsigned index extension %s", idx.Type)
                }
        }
-       return s.newValue1(op, types.Types[TINT], v)
+       return s.newValue1(op, types.Types[TINT], idx)
 }
 
 // CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values.
@@ -5612,6 +5750,14 @@ func (s *SSAGenState) PrepareCall(v *ssa.Value) {
        }
 }
 
+// UseArgs records the fact that an instruction needs a certain amount of
+// callee args space for its use.
+func (s *SSAGenState) UseArgs(n int64) {
+       if s.maxarg < n {
+               s.maxarg = n
+       }
+}
+
 // fieldIdx finds the index of the field referred to by the ODOT node n.
 func fieldIdx(n *Node) int {
        t := n.Left.Type
index 97a9b20537de33cb262301879ed5347d4fdd2bc0..d2ea0f46bb97bd4edbc627856ef5a9547cb71cbe 100644 (file)
@@ -485,6 +485,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
+       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 = gc.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)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+               s.UseArgs(12) // space used in callee args area by assembly stubs
        case ssa.OpMIPSLoweredAtomicLoad:
                s.Prog(mips.ASYNC)
 
index 8a2d2b0f7a4518e4bccf6555b5af1b50543d6e49..d0c8b069005a3a0954b8c40eca5ab2283d1b5898 100644 (file)
@@ -489,6 +489,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
+       case ssa.OpMIPS64LoweredPanicBoundsA, ssa.OpMIPS64LoweredPanicBoundsB, ssa.OpMIPS64LoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(16) // space used in callee args area by assembly stubs
        case ssa.OpMIPS64LoweredAtomicLoad32, ssa.OpMIPS64LoweredAtomicLoad64:
                as := mips.AMOVV
                if v.Op == ssa.OpMIPS64LoweredAtomicLoad32 {
index 3b37c797a99d55737ac599bb067e0de103994cad..4cccbecbb371780fc91a49e63969e8d2154567ff 100644 (file)
@@ -1183,6 +1183,13 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
 
+       case ssa.OpPPC64LoweredPanicBoundsA, ssa.OpPPC64LoweredPanicBoundsB, ssa.OpPPC64LoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(16) // space used in callee args area by assembly stubs
+
        case ssa.OpPPC64LoweredNilCheck:
                if objabi.GOOS == "aix" {
                        // CMP Rarg0, R0
index be48e1b23efe5ff553d14412b0371cda14593cb8..d90605bcbd0a6f97da940b90f2f084b2510fae83 100644 (file)
@@ -514,6 +514,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
+       case ssa.OpS390XLoweredPanicBoundsA, ssa.OpS390XLoweredPanicBoundsB, ssa.OpS390XLoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(16) // space used in callee args area by assembly stubs
        case ssa.OpS390XFLOGR, ssa.OpS390XPOPCNT,
                ssa.OpS390XNEG, ssa.OpS390XNEGW,
                ssa.OpS390XMOVWBR, ssa.OpS390XMOVDBR:
index fe02dd434af5d324629d18247b4ca2907667d991..4f6dbff20838fa1ea0c5ad8a7961e5f38d073677 100644 (file)
@@ -512,6 +512,18 @@ func (b *Block) NewValue4(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2,
        return v
 }
 
+// NewValue4I returns a new value in the block with four arguments and and auxint value.
+func (b *Block) NewValue4I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2, arg3 *Value) *Value {
+       v := b.Func.newValue(op, t, b, pos)
+       v.AuxInt = auxint
+       v.Args = []*Value{arg0, arg1, arg2, arg3}
+       arg0.Uses++
+       arg1.Uses++
+       arg2.Uses++
+       arg3.Uses++
+       return v
+}
+
 // constVal returns a constant value for c.
 func (f *Func) constVal(op Op, t *types.Type, c int64, setAuxInt bool) *Value {
        if f.constants == nil {
index 2ee0b2a928889e448a8982dca81bf85caeb0fcb6..0f20b115f836c68333a05f52a74a2a6b65bd505b 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // ***************************
 // Above: lowering rules
 // Below: optimizations
index fa3e7cd3758a068bb193781344a3aadb0b66e983..2851c4321ca17c932316c55cb5a0ac31a47c9cab 100644 (file)
@@ -86,6 +86,8 @@ func init() {
                ax         = buildReg("AX")
                cx         = buildReg("CX")
                dx         = buildReg("DX")
+               bx         = buildReg("BX")
+               si         = buildReg("SI")
                gp         = buildReg("AX CX DX BX BP SI DI")
                fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7")
                gpsp       = gp | buildReg("SP")
@@ -524,6 +526,17 @@ func init() {
                // It saves all GP registers if necessary, but may clobber others.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
+               // 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{dx, bx}}, typ: "Mem"}, // 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{cx, dx}}, typ: "Mem"}, // 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{ax, cx}}, typ: "Mem"}, // 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{si, dx, bx}}, typ: "Mem"}, // 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{si, cx, dx}}, typ: "Mem"}, // 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{si, ax, cx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index 6b2d3f77cfb717844b4090143ea6528cc0e6f4e4..91bb22f3fe0313d8b8c5ce862b59cd732746ce45 100644 (file)
 (NeqPtr x y) && config.PtrSize == 4 -> (SETNE (CMPL x y))
 (Neq(32|64)F x y) -> (SETNEF (UCOMIS(S|D) x y))
 
-(Int64Hi x) -> (SHRQconst [32] x) // needed for amd64p32
+(Int64Hi x) -> (SHRQconst [32] x)         // needed for amd64p32
+(Int64Lo x) -> x
 
 // Lowering loads
 (Load <t> ptr mem) && (is64BitInt(t) || isPtr(t) && config.PtrSize == 8) -> (MOVQload ptr mem)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
+// For amd64p32
+(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)
+
 // ***************************
 // Above: lowering rules
 // Below: optimizations
index a7880430ae61e78f3071ceba050d96ec8e524398..3ce302f5148a282d138f13cfea777bf7158cc982 100644 (file)
@@ -93,6 +93,8 @@ func init() {
                ax         = buildReg("AX")
                cx         = buildReg("CX")
                dx         = buildReg("DX")
+               bx         = buildReg("BX")
+               si         = buildReg("SI")
                gp         = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15")
                fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15")
                gpsp       = gp | buildReg("SP")
@@ -709,6 +711,19 @@ func init() {
                // It saves all GP registers if necessary, but may clobber others.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
+               // 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{dx, bx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+
+               // amd64p32 only: PanicBounds ops take 32-bit indexes.
+               // The Extend ops are the same as the Bounds ops except the indexes are 64-bit.
+               {name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, dx, bx}}, typ: "Mem"}, // 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{si, cx, dx}}, typ: "Mem"}, // 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{si, ax, cx}}, typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index a3f36d3009ac41b4fe59bb640d484cbf81ff04c3..2934a914295f93db8552892f7edfbefde4d80666 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // Optimizations
 
 // fold offset into address
index 3adb7895a2c7ea001150fffc34153de52ba97f0a..35126835d2eac78115bc6b849e4fcd61ac5fca14 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // Optimizations
 
 // Absorb boolean tests into block
index b6bf10315e0c66e9bfd6da9994ced9b1a126ad95..04c4b3f517eff4a277e97401a8ce60a243fa0bab 100644 (file)
@@ -130,6 +130,10 @@ func init() {
                gpspsbg    = gpspg | buildReg("SB")
                fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
                callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+               r0         = buildReg("R0")
+               r1         = buildReg("R1")
+               r2         = buildReg("R2")
+               r3         = buildReg("R3")
        )
        // Common regInfo
        var (
@@ -650,6 +654,13 @@ func init() {
                // It saves all GP registers if necessary,
                // but clobbers R30 (LR) because it's a call.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+               // 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"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
        }
 
        blocks := []blockData{
index 86d7e5f8ec989d2c734fcc7077c2007353b4b41f..d8bdfeb86ec3ca8c24434ce28fc011ea05a410ed 100644 (file)
@@ -94,6 +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
+               r0         = buildReg("R0")
+               r1         = buildReg("R1")
+               r2         = buildReg("R2")
+               r3         = buildReg("R3")
+               r4         = buildReg("R4")
        )
        // Common regInfo
        var (
@@ -526,6 +531,17 @@ 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"}, // 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"}, // 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"}, // 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"}, // 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"}, // 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"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index bd218b494f3fbbd86273b0affe61026397980a2b..573f1d44c7191d29539c8d4c24e004afe919e0dc 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
 
 // Optimizations
 
index 9c16c3543847feed48a33aa8e008137595bc5234..52f9c4895d9d003c313a36301bc9781952dca25b 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // Optimizations
 
 // Absorb boolean tests into block
index 5235930ccc5858df28c3749433667df8b332a03e..f476c9b6fe9491e54b279cfe419ce131cfa091e6 100644 (file)
@@ -136,6 +136,10 @@ 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")
        )
        // Common regInfo
        var (
@@ -420,6 +424,13 @@ func init() {
                // but clobbers R31 (LR) because it's a call
                // and R23 (REGTMP).
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+               // 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"}, // 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"}, // 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"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
        }
 
        blocks := []blockData{
index 2605b60650bdb689bcf9f104129e9d4a6dc56668..729cc051027ed479b5915edf70fc62616b6ccae8 100644 (file)
@@ -120,6 +120,11 @@ 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")
        )
        // Common regInfo
        var (
@@ -390,6 +395,17 @@ func init() {
                // but clobbers R31 (LR) because it's a call
                // and R23 (REGTMP).
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+               // 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"}, // 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"}, // 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"}, // 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"}, // 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"}, // 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"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
        }
 
        blocks := []blockData{
index 8dee5a1cbad2ea6d12f3096e1622646843405c29..b0a249a558a8ef959ac06d3618ad49d46f411d8d 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // Optimizations
 // Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms,
 // so ORconst, XORconst easily expand into a pair.
index d6638b1ec72e644ba5eaec5b48e4e9e2d7611974..2404d1afd663998f7a29f33b7ac3c41185b94e69 100644 (file)
@@ -158,6 +158,10 @@ func init() {
                fpstore     = regInfo{inputs: []regMask{gp | sp | sb, fp}}
                fpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
                callerSave  = regMask(gp | fp | gr)
+               r3          = buildReg("R3")
+               r4          = buildReg("R4")
+               r5          = buildReg("R5")
+               r6          = buildReg("R6")
        )
        ops := []opData{
                {name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},     // arg0 + arg1
@@ -537,6 +541,13 @@ func init() {
                // but may clobber anything else, including R31 (REGTMP).
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R20 R21 g")) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
+               // 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{r5, r6}}, typ: "Mem"}, // 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{r4, r5}}, typ: "Mem"}, // 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{r3, r4}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+
                // (InvertFlags (CMP a b)) == (CMP b a)
                // So if we want (LessThan (CMP a b)) but we can't do that because a is a constant,
                // then we do (LessThan (InvertFlags (CMP b a))) instead.
index 0aeea535616833db1c7cafece7e221ef35823a0d..2803f2ff501a4e4e6f73782640bae3da6fc224bd 100644 (file)
 // Write barrier.
 (WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)
 
+(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)
+
 // ***************************
 // Above: lowering rules
 // Below: optimizations
index 19cb4be41c067c96469902e378c494efdb8be610..4074243e988abf7a327b439a77ee70c9244063cb 100644 (file)
@@ -127,6 +127,9 @@ func init() {
 
                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
+               r1         = buildReg("R1")
+               r2         = buildReg("R2")
+               r3         = buildReg("R3")
        )
        // Common slices of register masks
        var (
@@ -463,6 +466,13 @@ func init() {
                // but clobbers R14 (LR) because it's a call.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
+               // 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"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+               {name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index 89e6961bd79a556a3045683ced9c35c3e23bca80..79169c34a1d42455266dec6c570382db2b12b664 100644 (file)
@@ -369,6 +369,14 @@ var genericOps = []opData{
        // arch-dependent), and is not a safe-point.
        {name: "WB", argLength: 3, typ: "Mem", aux: "Sym", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
 
+       // PanicBounds and PanicExtend generate a runtime panic.
+       // Their arguments provide index values to use in panic messages.
+       // Both PanicBounds and PanicExtend have an AuxInt value from the BoundsKind type (in ../op.go).
+       // PanicBounds' index is int sized.
+       // PanicExtend's index is int64 sized. (PanicExtend is only used on 32-bit archs.)
+       {name: "PanicBounds", argLength: 3, aux: "Int64", typ: "Mem"}, // arg0=idx, arg1=len, arg2=mem, returns memory.
+       {name: "PanicExtend", argLength: 4, aux: "Int64", typ: "Mem"}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory.
+
        // Function calls. Arguments to the call have already been written to the stack.
        // Return values appear on the stack. The method receiver, if any, is treated
        // as a phantom first argument.
index a3cebce43bf21262324bca657e14f80e5b4063e2..b404533f6c1dd29e4ef4f84bf05e5ae9aa4439a2 100644 (file)
@@ -165,3 +165,70 @@ func (x ValAndOff) add(off int64) int64 {
        }
        return makeValAndOff(x.Val(), x.Off()+off)
 }
+
+type BoundsKind uint8
+
+const (
+       BoundsIndex       BoundsKind = iota // indexing operation, 0 <= idx < len failed
+       BoundsIndexU                        // ... with unsigned idx
+       BoundsSliceAlen                     // 2-arg slicing operation, 0 <= high <= len failed
+       BoundsSliceAlenU                    // ... with unsigned high
+       BoundsSliceAcap                     // 2-arg slicing operation, 0 <= high <= cap failed
+       BoundsSliceAcapU                    // ... with unsigned high
+       BoundsSliceB                        // 2-arg slicing operation, 0 <= low <= high failed
+       BoundsSliceBU                       // ... with unsigned low
+       BoundsSlice3Alen                    // 3-arg slicing operation, 0 <= max <= len failed
+       BoundsSlice3AlenU                   // ... with unsigned max
+       BoundsSlice3Acap                    // 3-arg slicing operation, 0 <= max <= cap failed
+       BoundsSlice3AcapU                   // ... with unsigned max
+       BoundsSlice3B                       // 3-arg slicing operation, 0 <= high <= max failed
+       BoundsSlice3BU                      // ... with unsigned high
+       BoundsSlice3C                       // 3-arg slicing operation, 0 <= low <= high failed
+       BoundsSlice3CU                      // ... with unsigned low
+       BoundsKindCount
+)
+
+// boundsAPI determines which register arguments a bounds check call should use. For an [a:b:c] slice, we do:
+//   CMPQ c, cap
+//   JA   fail1
+//   CMPQ b, c
+//   JA   fail2
+//   CMPQ a, b
+//   JA   fail3
+//
+// fail1: CALL panicSlice3Acap (c, cap)
+// fail2: CALL panicSlice3B (b, c)
+// fail3: CALL panicSlice3C (a, b)
+//
+// When we register allocate that code, we want the same register to be used for
+// the first arg of panicSlice3Acap and the second arg to panicSlice3B. That way,
+// initializing that register once will satisfy both calls.
+// That desire ends up dividing the set of bounds check calls into 3 sets. This function
+// determines which set to use for a given panic call.
+// The first arg for set 0 should be the second arg for set 1.
+// The first arg for set 1 should be the second arg for set 2.
+func boundsABI(b int64) int {
+       switch BoundsKind(b) {
+       case BoundsSlice3Alen,
+               BoundsSlice3AlenU,
+               BoundsSlice3Acap,
+               BoundsSlice3AcapU:
+               return 0
+       case BoundsSliceAlen,
+               BoundsSliceAlenU,
+               BoundsSliceAcap,
+               BoundsSliceAcapU,
+               BoundsSlice3B,
+               BoundsSlice3BU:
+               return 1
+       case BoundsIndex,
+               BoundsIndexU,
+               BoundsSliceB,
+               BoundsSliceBU,
+               BoundsSlice3C,
+               BoundsSlice3CU:
+               return 2
+       default:
+               panic("bad BoundsKind")
+       }
+}
index bf9fe7c9603169fa584668a7ead0b68313e8b01c..c5e88e853e9ad6a4020d891876afd7e09061862a 100644 (file)
@@ -463,6 +463,12 @@ const (
        Op386LoweredGetCallerSP
        Op386LoweredNilCheck
        Op386LoweredWB
+       Op386LoweredPanicBoundsA
+       Op386LoweredPanicBoundsB
+       Op386LoweredPanicBoundsC
+       Op386LoweredPanicExtendA
+       Op386LoweredPanicExtendB
+       Op386LoweredPanicExtendC
        Op386FlagEQ
        Op386FlagLT_ULT
        Op386FlagLT_UGT
@@ -844,6 +850,12 @@ const (
        OpAMD64LoweredGetCallerSP
        OpAMD64LoweredNilCheck
        OpAMD64LoweredWB
+       OpAMD64LoweredPanicBoundsA
+       OpAMD64LoweredPanicBoundsB
+       OpAMD64LoweredPanicBoundsC
+       OpAMD64LoweredPanicExtendA
+       OpAMD64LoweredPanicExtendB
+       OpAMD64LoweredPanicExtendC
        OpAMD64FlagEQ
        OpAMD64FlagLT_ULT
        OpAMD64FlagLT_UGT
@@ -1115,6 +1127,12 @@ const (
        OpARMLoweredGetClosurePtr
        OpARMLoweredGetCallerSP
        OpARMLoweredGetCallerPC
+       OpARMLoweredPanicBoundsA
+       OpARMLoweredPanicBoundsB
+       OpARMLoweredPanicBoundsC
+       OpARMLoweredPanicExtendA
+       OpARMLoweredPanicExtendB
+       OpARMLoweredPanicExtendC
        OpARMFlagEQ
        OpARMFlagLT_ULT
        OpARMFlagLT_UGT
@@ -1403,6 +1421,9 @@ const (
        OpARM64LoweredAtomicAnd8
        OpARM64LoweredAtomicOr8
        OpARM64LoweredWB
+       OpARM64LoweredPanicBoundsA
+       OpARM64LoweredPanicBoundsB
+       OpARM64LoweredPanicBoundsC
 
        OpMIPSADD
        OpMIPSADDconst
@@ -1506,6 +1527,12 @@ const (
        OpMIPSLoweredGetCallerSP
        OpMIPSLoweredGetCallerPC
        OpMIPSLoweredWB
+       OpMIPSLoweredPanicBoundsA
+       OpMIPSLoweredPanicBoundsB
+       OpMIPSLoweredPanicBoundsC
+       OpMIPSLoweredPanicExtendA
+       OpMIPSLoweredPanicExtendB
+       OpMIPSLoweredPanicExtendC
 
        OpMIPS64ADDV
        OpMIPS64ADDVconst
@@ -1619,6 +1646,9 @@ const (
        OpMIPS64LoweredGetCallerSP
        OpMIPS64LoweredGetCallerPC
        OpMIPS64LoweredWB
+       OpMIPS64LoweredPanicBoundsA
+       OpMIPS64LoweredPanicBoundsB
+       OpMIPS64LoweredPanicBoundsC
 
        OpPPC64ADD
        OpPPC64ADDconst
@@ -1799,6 +1829,9 @@ const (
        OpPPC64LoweredAtomicAnd8
        OpPPC64LoweredAtomicOr8
        OpPPC64LoweredWB
+       OpPPC64LoweredPanicBoundsA
+       OpPPC64LoweredPanicBoundsB
+       OpPPC64LoweredPanicBoundsC
        OpPPC64InvertFlags
        OpPPC64FlagEQ
        OpPPC64FlagLT
@@ -1994,6 +2027,9 @@ const (
        OpS390XLoweredRound32F
        OpS390XLoweredRound64F
        OpS390XLoweredWB
+       OpS390XLoweredPanicBoundsA
+       OpS390XLoweredPanicBoundsB
+       OpS390XLoweredPanicBoundsC
        OpS390XFlagEQ
        OpS390XFlagLT
        OpS390XFlagGT
@@ -2351,6 +2387,8 @@ const (
        OpMoveWB
        OpZeroWB
        OpWB
+       OpPanicBounds
+       OpPanicExtend
        OpClosureCall
        OpStaticCall
        OpInterCall
@@ -5588,6 +5626,75 @@ var opcodeTable = [...]opInfo{
                        clobbers: 65280, // X0 X1 X2 X3 X4 X5 X6 X7
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // DX
+                               {1, 8}, // BX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // CX
+                               {1, 4}, // DX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1}, // AX
+                               {1, 2}, // CX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendA",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 4},  // DX
+                               {2, 8},  // BX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendB",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 2},  // CX
+                               {2, 4},  // DX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendC",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 1},  // AX
+                               {2, 2},  // CX
+                       },
+               },
+       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -11113,6 +11220,75 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4294901760, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // DX
+                               {1, 8}, // BX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // CX
+                               {1, 4}, // DX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1}, // AX
+                               {1, 2}, // CX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendA",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 4},  // DX
+                               {2, 8},  // BX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendB",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 2},  // CX
+                               {2, 4},  // DX
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendC",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 64}, // SI
+                               {1, 1},  // AX
+                               {2, 2},  // CX
+                       },
+               },
+       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -14847,6 +15023,75 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // R2
+                               {1, 8}, // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // R1
+                               {1, 4}, // R2
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1}, // R0
+                               {1, 2}, // R1
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendA",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 16}, // R4
+                               {1, 4},  // R2
+                               {2, 8},  // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendB",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 16}, // R4
+                               {1, 2},  // R1
+                               {2, 4},  // R2
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendC",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 16}, // R4
+                               {1, 1},  // R0
+                               {2, 2},  // R1
+                       },
+               },
+       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -18610,6 +18855,39 @@ var opcodeTable = [...]opInfo{
                        clobbers: 9223372035244163072, // R30 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // R2
+                               {1, 8}, // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // R1
+                               {1, 4}, // R2
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1}, // R0
+                               {1, 2}, // R1
+                       },
+               },
+       },
 
        {
                name:        "ADD",
@@ -20000,6 +20278,75 @@ var opcodeTable = [...]opInfo{
                        clobbers: 140737219919872, // R31 F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30 HI LO
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8},  // R3
+                               {1, 16}, // R4
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // R2
+                               {1, 8}, // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // R1
+                               {1, 4}, // R2
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendA",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 32}, // R5
+                               {1, 8},  // R3
+                               {2, 16}, // R4
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendB",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 32}, // R5
+                               {1, 4},  // R2
+                               {2, 8},  // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicExtendC",
+               auxType: auxInt64,
+               argLen:  4,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 32}, // R5
+                               {1, 2},  // R1
+                               {2, 4},  // R2
+                       },
+               },
+       },
 
        {
                name:        "ADDV",
@@ -21530,6 +21877,39 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4611686018293170176, // R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 HI LO
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8},  // R3
+                               {1, 16}, // R4
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // R2
+                               {1, 8}, // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // R1
+                               {1, 4}, // R2
+                       },
+               },
+       },
 
        {
                name:        "ADD",
@@ -24010,6 +24390,39 @@ var opcodeTable = [...]opInfo{
                        clobbers: 576460746931503104, // R16 R17 R18 R19 R22 R23 R24 R25 R26 R27 R28 R29 R31 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 32}, // R5
+                               {1, 64}, // R6
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 16}, // R4
+                               {1, 32}, // R5
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8},  // R3
+                               {1, 16}, // R4
+                       },
+               },
+       },
        {
                name:   "InvertFlags",
                argLen: 1,
@@ -26871,6 +27284,39 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4294918144, // R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
                },
        },
+       {
+               name:    "LoweredPanicBoundsA",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4}, // R2
+                               {1, 8}, // R3
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsB",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 2}, // R1
+                               {1, 4}, // R2
+                       },
+               },
+       },
+       {
+               name:    "LoweredPanicBoundsC",
+               auxType: auxInt64,
+               argLen:  3,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1}, // R0
+                               {1, 2}, // R1
+                       },
+               },
+       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -29693,6 +30139,18 @@ var opcodeTable = [...]opInfo{
                symEffect: SymNone,
                generic:   true,
        },
+       {
+               name:    "PanicBounds",
+               auxType: auxInt64,
+               argLen:  3,
+               generic: true,
+       },
+       {
+               name:    "PanicExtend",
+               auxType: auxInt64,
+               argLen:  4,
+               generic: true,
+       },
        {
                name:    "ClosureCall",
                auxType: auxInt64,
index e2d76ecb85a448a536af86b42162d74b36ec9070..bb59feab0bb1a004f73c8f120e415601423a4774 100644 (file)
@@ -587,6 +587,10 @@ func rewriteValue386(v *Value) bool {
                return rewriteValue386_OpOr8_0(v)
        case OpOrB:
                return rewriteValue386_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValue386_OpPanicBounds_0(v)
+       case OpPanicExtend:
+               return rewriteValue386_OpPanicExtend_0(v)
        case OpRound32F:
                return rewriteValue386_OpRound32F_0(v)
        case OpRound64F:
@@ -22897,6 +22901,132 @@ func rewriteValue386_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValue386_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(Op386LoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(Op386LoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(Op386LoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValue386_OpPanicExtend_0(v *Value) bool {
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicExtendA [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(Op386LoweredPanicExtendA)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicExtendB [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(Op386LoweredPanicExtendB)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicExtendC [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(Op386LoweredPanicExtendC)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValue386_OpRound32F_0(v *Value) bool {
        // match: (Round32F x)
        // cond:
index 926c4a599cbcc11341e572bb6619b6460ba7a96d..708ab9df0564c978c2d1f7705df0b0e853063010 100644 (file)
@@ -831,6 +831,8 @@ func rewriteValueAMD64(v *Value) bool {
                return rewriteValueAMD64_OpHmul64u_0(v)
        case OpInt64Hi:
                return rewriteValueAMD64_OpInt64Hi_0(v)
+       case OpInt64Lo:
+               return rewriteValueAMD64_OpInt64Lo_0(v)
        case OpInterCall:
                return rewriteValueAMD64_OpInterCall_0(v)
        case OpIsInBounds:
@@ -991,6 +993,10 @@ func rewriteValueAMD64(v *Value) bool {
                return rewriteValueAMD64_OpOr8_0(v)
        case OpOrB:
                return rewriteValueAMD64_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueAMD64_OpPanicBounds_0(v)
+       case OpPanicExtend:
+               return rewriteValueAMD64_OpPanicExtend_0(v)
        case OpPopCount16:
                return rewriteValueAMD64_OpPopCount16_0(v)
        case OpPopCount32:
@@ -59244,6 +59250,18 @@ func rewriteValueAMD64_OpInt64Hi_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueAMD64_OpInt64Lo_0(v *Value) bool {
+       // match: (Int64Lo x)
+       // cond:
+       // result: x
+       for {
+               x := v.Args[0]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueAMD64_OpInterCall_0(v *Value) bool {
        // match: (InterCall [argwid] entry mem)
        // cond:
@@ -61695,6 +61713,132 @@ func rewriteValueAMD64_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueAMD64_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueAMD64_OpPanicExtend_0(v *Value) bool {
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicExtendA [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicExtendA)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicExtendB [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicExtendB)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicExtendC [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpAMD64LoweredPanicExtendC)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueAMD64_OpPopCount16_0(v *Value) bool {
        b := v.Block
        typ := &b.Func.Config.Types
index 37a34a9977295906140a64809b15dce5020affe7..11c1bde8d156000fb8605d22592dd80f1488e244 100644 (file)
@@ -719,6 +719,10 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpOr8_0(v)
        case OpOrB:
                return rewriteValueARM_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueARM_OpPanicBounds_0(v)
+       case OpPanicExtend:
+               return rewriteValueARM_OpPanicExtend_0(v)
        case OpRound32F:
                return rewriteValueARM_OpRound32F_0(v)
        case OpRound64F:
@@ -20075,6 +20079,132 @@ func rewriteValueARM_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpPanicExtend_0(v *Value) bool {
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicExtendA [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicExtendA)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicExtendB [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicExtendB)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicExtendC [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpARMLoweredPanicExtendC)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueARM_OpRound32F_0(v *Value) bool {
        // match: (Round32F x)
        // cond:
index 89f01b4d84a0514a08a9f397d696efcfa8a689e0..499c5bbbd48460cad8815fb554f47a26c40547b7 100644 (file)
@@ -789,6 +789,8 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpOr8_0(v)
        case OpOrB:
                return rewriteValueARM64_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueARM64_OpPanicBounds_0(v)
        case OpPopCount16:
                return rewriteValueARM64_OpPopCount16_0(v)
        case OpPopCount32:
@@ -35631,6 +35633,66 @@ func rewriteValueARM64_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueARM64_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpARM64LoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpARM64LoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpARM64LoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpPopCount16_0(v *Value) bool {
        b := v.Block
        typ := &b.Func.Config.Types
index 145ee5aa632877bd6f3d62a546cf44c6312eae71..d506d77ae3ab549d2ece7e3a3e20057ab5ee1120 100644 (file)
@@ -405,6 +405,10 @@ func rewriteValueMIPS(v *Value) bool {
                return rewriteValueMIPS_OpOr8_0(v)
        case OpOrB:
                return rewriteValueMIPS_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueMIPS_OpPanicBounds_0(v)
+       case OpPanicExtend:
+               return rewriteValueMIPS_OpPanicExtend_0(v)
        case OpRound32F:
                return rewriteValueMIPS_OpRound32F_0(v)
        case OpRound64F:
@@ -6975,6 +6979,132 @@ func rewriteValueMIPS_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueMIPS_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueMIPS_OpPanicExtend_0(v *Value) bool {
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicExtendA [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicExtendA)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicExtendB [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicExtendB)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicExtend [kind] hi lo y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicExtendC [kind] hi lo y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[3]
+               hi := v.Args[0]
+               lo := v.Args[1]
+               y := v.Args[2]
+               mem := v.Args[3]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpMIPSLoweredPanicExtendC)
+               v.AuxInt = kind
+               v.AddArg(hi)
+               v.AddArg(lo)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueMIPS_OpRound32F_0(v *Value) bool {
        // match: (Round32F x)
        // cond:
index 4d1d8170338ff8c4ab4d89e318812d86603108f5..ca93e04c2ca6032ae4db494efedf0748e35ba35e 100644 (file)
@@ -469,6 +469,8 @@ func rewriteValueMIPS64(v *Value) bool {
                return rewriteValueMIPS64_OpOr8_0(v)
        case OpOrB:
                return rewriteValueMIPS64_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueMIPS64_OpPanicBounds_0(v)
        case OpRound32F:
                return rewriteValueMIPS64_OpRound32F_0(v)
        case OpRound64F:
@@ -7412,6 +7414,66 @@ func rewriteValueMIPS64_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueMIPS64_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpMIPS64LoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpMIPS64LoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpMIPS64LoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueMIPS64_OpRound32F_0(v *Value) bool {
        // match: (Round32F x)
        // cond:
index 7daed08dabbe6c932b95dc7add87048b16e38b1a..d1e4482137ffb34aff6cbd3bdef9b4481102a062 100644 (file)
@@ -547,6 +547,8 @@ func rewriteValuePPC64(v *Value) bool {
                return rewriteValuePPC64_OpPPC64XOR_0(v) || rewriteValuePPC64_OpPPC64XOR_10(v)
        case OpPPC64XORconst:
                return rewriteValuePPC64_OpPPC64XORconst_0(v)
+       case OpPanicBounds:
+               return rewriteValuePPC64_OpPanicBounds_0(v)
        case OpPopCount16:
                return rewriteValuePPC64_OpPopCount16_0(v)
        case OpPopCount32:
@@ -26076,6 +26078,66 @@ func rewriteValuePPC64_OpPPC64XORconst_0(v *Value) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpPPC64LoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpPPC64LoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpPPC64LoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPopCount16_0(v *Value) bool {
        b := v.Block
        typ := &b.Func.Config.Types
index 3ee004be9972eed63332bb383056613ab86833ec..ddf648ded7b95209f6b08b56707c8abad9cc8072 100644 (file)
@@ -385,6 +385,8 @@ func rewriteValueS390X(v *Value) bool {
                return rewriteValueS390X_OpOr8_0(v)
        case OpOrB:
                return rewriteValueS390X_OpOrB_0(v)
+       case OpPanicBounds:
+               return rewriteValueS390X_OpPanicBounds_0(v)
        case OpPopCount16:
                return rewriteValueS390X_OpPopCount16_0(v)
        case OpPopCount32:
@@ -4965,6 +4967,66 @@ func rewriteValueS390X_OpOrB_0(v *Value) bool {
                return true
        }
 }
+func rewriteValueS390X_OpPanicBounds_0(v *Value) bool {
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 0
+       // result: (LoweredPanicBoundsA [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 0) {
+                       break
+               }
+               v.reset(OpS390XLoweredPanicBoundsA)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 1
+       // result: (LoweredPanicBoundsB [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 1) {
+                       break
+               }
+               v.reset(OpS390XLoweredPanicBoundsB)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (PanicBounds [kind] x y mem)
+       // cond: boundsABI(kind) == 2
+       // result: (LoweredPanicBoundsC [kind] x y mem)
+       for {
+               kind := v.AuxInt
+               _ = v.Args[2]
+               x := v.Args[0]
+               y := v.Args[1]
+               mem := v.Args[2]
+               if !(boundsABI(kind) == 2) {
+                       break
+               }
+               v.reset(OpS390XLoweredPanicBoundsC)
+               v.AuxInt = kind
+               v.AddArg(x)
+               v.AddArg(y)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueS390X_OpPopCount16_0(v *Value) bool {
        b := v.Block
        typ := &b.Func.Config.Types
index 24ba9649beff02275ae0758552fb6431aef5d2a5..b7b0f445299ccdb0fc5fa1655f0361b769928d1f 100644 (file)
@@ -758,6 +758,20 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Name = obj.NAME_EXTERN
                p.To.Sym = v.Aux.(*obj.LSym)
 
+       case ssa.Op386LoweredPanicBoundsA, ssa.Op386LoweredPanicBoundsB, ssa.Op386LoweredPanicBoundsC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
+               s.UseArgs(8) // space used in callee args area by assembly stubs
+
+       case ssa.Op386LoweredPanicExtendA, ssa.Op386LoweredPanicExtendB, ssa.Op386LoweredPanicExtendC:
+               p := s.Prog(obj.ACALL)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
+               s.UseArgs(12) // space used in callee args area by assembly stubs
+
        case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
                s.Call(v)
        case ssa.Op386NEGL,
index 51103928b3533c33a64fdbd7ca3758bff8b63b53..8805dbf7d692b3b21500edee969d455f8bc79aa7 100644 (file)
@@ -1401,3 +1401,155 @@ flush:
        MOVL    12(SP), BP
        MOVL    16(SP), SI
        JMP     ret
+
+// 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
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
+
+// Extended versions for 64-bit indexes.
+TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendIndex(SB)
+TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendIndexU(SB)
+TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAlen(SB)
+TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAlenU(SB)
+TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAcap(SB)
+TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAcapU(SB)
+TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceB(SB)
+TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceBU(SB)
+TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3Alen(SB)
+TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3AlenU(SB)
+TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3Acap(SB)
+TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3AcapU(SB)
+TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3B(SB)
+TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3BU(SB)
+TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3C(SB)
+TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3CU(SB)
index 85133bf2dfc6ea815d8872b02f8f7dd18e0cfb3c..d3e5c5437890307480010a677d769defea968a97 100644 (file)
@@ -1628,3 +1628,73 @@ TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
        MOVQ    $2, AX
        BYTE    $0xcc
        RET
+
+// 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-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
+       MOVQ    DX, x+0(FP)
+       MOVQ    BX, y+8(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
+       MOVQ    DX, x+0(FP)
+       MOVQ    BX, y+8(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
+       MOVQ    DX, x+0(FP)
+       MOVQ    BX, y+8(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
+       MOVQ    DX, x+0(FP)
+       MOVQ    BX, y+8(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
+       MOVQ    CX, x+0(FP)
+       MOVQ    DX, y+8(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
+       MOVQ    AX, x+0(FP)
+       MOVQ    CX, y+8(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
index 7b57fc78d6b8ed124d4f463a5f643d7370dff045..4d0d6c565004ea86e6464e4534b3ee17191817f0 100644 (file)
@@ -607,3 +607,155 @@ flush:
        MOVQ    56(SP), R11
        MOVQ    64(SP), R12
        JMP     ret
+
+// 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
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
+       MOVL    DX, x+0(FP)
+       MOVL    BX, y+4(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
+       MOVL    CX, x+0(FP)
+       MOVL    DX, y+4(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
+       MOVL    AX, x+0(FP)
+       MOVL    CX, y+4(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
+
+// Extended versions for 64-bit indexes.
+TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendIndex(SB)
+TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendIndexU(SB)
+TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAlen(SB)
+TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAlenU(SB)
+TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAcap(SB)
+TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceAcapU(SB)
+TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceB(SB)
+TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSliceBU(SB)
+TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3Alen(SB)
+TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3AlenU(SB)
+TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3Acap(SB)
+TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    DX, lo+4(FP)
+       MOVL    BX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3AcapU(SB)
+TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3B(SB)
+TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    CX, lo+4(FP)
+       MOVL    DX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3BU(SB)
+TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3C(SB)
+TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
+       MOVL    SI, hi+0(FP)
+       MOVL    AX, lo+4(FP)
+       MOVL    CX, y+8(FP)
+       JMP     runtime·goPanicExtendSlice3CU(SB)
index 745aceaaff6c32f17dd0488161bb349e1c59f653..c1e915b97ccb5bb266a6acfa6a28fba452c4e21e 100644 (file)
@@ -969,3 +969,155 @@ flush:
        MOVM.IA.W       (R13), [R14]
        MOVM.IA.W       (R13), [R2-R9,R12]
        JMP     ret
+
+// 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)
+
+// 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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    R3, 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)
index bbeb3df0c85f5737b47ead40d519ac6236b9bf7e..f7cf0d354462b608562c2e12f842ca9da220da5a 100644 (file)
@@ -1245,3 +1245,73 @@ flush:
        MOVD    184(RSP), R25
        MOVD    192(RSP), R26
        JMP     ret
+
+// 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-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
index ef45ab137880e6949e94f7cf70603cc35eac9363..257c13e9af7cf52ac2871901d8bd3c346c65285b 100644 (file)
@@ -750,3 +750,73 @@ flush:
        MOVV    168(R29), R24
        MOVV    176(R29), R25
        JMP     ret
+
+// 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-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
+       MOVV    R3, x+0(FP)
+       MOVV    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
+       MOVV    R3, x+0(FP)
+       MOVV    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
+       MOVV    R3, x+0(FP)
+       MOVV    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
+       MOVV    R3, x+0(FP)
+       MOVV    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
+       MOVV    R2, x+0(FP)
+       MOVV    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
+       MOVV    R1, x+0(FP)
+       MOVV    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
index 6ef4507ee1168aa54a1d33a93e85fbfaa4642c00..9f38bbc71ee079c0b1daedd1ded81a193727ff4d 100644 (file)
@@ -764,3 +764,155 @@ flush:
        MOVW    92(R29), R25
        MOVW    96(R29), R28
        JMP     ret
+
+// 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)
+
+// 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)
index 9b5da3db992e0e500277ae762a7c9dd1f443cca8..9ac83e55903f968de497264bb35cade505392e6f 100644 (file)
@@ -976,3 +976,73 @@ flush:
        MOVD    (FIXED_FRAME+96)(R1), R14
        MOVD    (FIXED_FRAME+104)(R1), R15
        JMP     ret
+
+// 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-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
+       MOVD    R5, x+0(FP)
+       MOVD    R6, y+8(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
+       MOVD    R5, x+0(FP)
+       MOVD    R6, y+8(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
+       MOVD    R5, x+0(FP)
+       MOVD    R6, y+8(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
+       MOVD    R5, x+0(FP)
+       MOVD    R6, y+8(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
+       MOVD    R4, x+0(FP)
+       MOVD    R5, y+8(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
+       MOVD    R3, x+0(FP)
+       MOVD    R4, y+8(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
index 566c3e923645dc2118573b4598540108ec66529f..5b9e0cd4813881038d0f576cabb3f65fdb0e501d 100644 (file)
@@ -863,3 +863,73 @@ flush:
        MOVD    24(R15), R0      // restore R0
        LMG     32(R15), R5, R12 // restore R5 - R12
        JMP     ret
+
+// 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-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicIndex(SB)
+TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicIndexU(SB)
+TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAlen(SB)
+TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAlenU(SB)
+TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAcap(SB)
+TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSliceAcapU(SB)
+TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSliceB(SB)
+TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSliceBU(SB)
+TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3Alen(SB)
+TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3AlenU(SB)
+TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3Acap(SB)
+TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
+       MOVD    R2, x+0(FP)
+       MOVD    R3, y+8(FP)
+       JMP     runtime·goPanicSlice3AcapU(SB)
+TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3B(SB)
+TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
+       MOVD    R1, x+0(FP)
+       MOVD    R2, y+8(FP)
+       JMP     runtime·goPanicSlice3BU(SB)
+TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSlice3C(SB)
+TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
+       MOVD    R0, x+0(FP)
+       MOVD    R1, y+8(FP)
+       JMP     runtime·goPanicSlice3CU(SB)
index 9a2beaeb9536f4fe4ebdd240926d3ff9b59c8fc7..0085dfc824a43cb2de4cfb5500d9a9795493334d 100644 (file)
@@ -53,6 +53,21 @@ func (e *TypeAssertionError) Error() string {
                ": missing method " + e.missingMethod
 }
 
+//go:nosplit
+// itoa converts val to a decimal representation. The result is
+// written somewhere within buf and the location of the result is returned.
+// buf must be at least 20 bytes.
+func itoa(buf []byte, val uint64) []byte {
+       i := len(buf) - 1
+       for val >= 10 {
+               buf[i] = byte(val%10 + '0')
+               i--
+               val /= 10
+       }
+       buf[i] = byte(val + '0')
+       return buf[i:]
+}
+
 // An errorString represents a runtime error described by a single string.
 type errorString string
 
@@ -73,6 +88,99 @@ func (e plainError) Error() string {
        return string(e)
 }
 
+// An boundsError represents a an indexing or slicing operation gone wrong.
+type boundsError struct {
+       x int64
+       y int
+       // Values in an index or slice expression can be signed or unsigned.
+       // That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1.
+       // Instead, we keep track of whether x should be interpreted as signed or unsigned.
+       // y is known to be nonnegative and to fit in an int.
+       signed bool
+       code   boundsErrorCode
+}
+
+type boundsErrorCode uint8
+
+const (
+       boundsIndex boundsErrorCode = iota // s[x], 0 <= x < len(s) failed
+
+       boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
+       boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
+       boundsSliceB    // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
+
+       boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
+       boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
+       boundsSlice3B    // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
+       boundsSlice3C    // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
+
+       // Note: in the above, len(s) and cap(s) are stored in y
+)
+
+// boundsErrorFmts provide error text for various out-of-bounds panics.
+// Note: if you change these strings, you should adjust the size of the buffer
+// in boundsError.Error below as well.
+var boundsErrorFmts = [...]string{
+       boundsIndex:      "index out of range [%x] with length %y",
+       boundsSliceAlen:  "slice bounds out of range [:%x] with length %y",
+       boundsSliceAcap:  "slice bounds out of range [:%x] with capacity %y",
+       boundsSliceB:     "slice bounds out of range [%x:%y]",
+       boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
+       boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
+       boundsSlice3B:    "slice bounds out of range [:%x:%y]",
+       boundsSlice3C:    "slice bounds out of range [%x:%y:]",
+}
+
+// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
+var boundsNegErrorFmts = [...]string{
+       boundsIndex:      "index out of range [%x]",
+       boundsSliceAlen:  "slice bounds out of range [:%x]",
+       boundsSliceAcap:  "slice bounds out of range [:%x]",
+       boundsSliceB:     "slice bounds out of range [%x:]",
+       boundsSlice3Alen: "slice bounds out of range [::%x]",
+       boundsSlice3Acap: "slice bounds out of range [::%x]",
+       boundsSlice3B:    "slice bounds out of range [:%x:]",
+       boundsSlice3C:    "slice bounds out of range [%x::]",
+}
+
+func (e boundsError) RuntimeError() {}
+
+func appendIntStr(b []byte, v int64, signed bool) []byte {
+       if signed && v < 0 {
+               b = append(b, '-')
+               v = -v
+       }
+       var buf [20]byte
+       b = append(b, itoa(buf[:], uint64(v))...)
+       return b
+}
+
+func (e boundsError) Error() string {
+       fmt := boundsErrorFmts[e.code]
+       if e.signed && e.x < 0 {
+               fmt = boundsNegErrorFmts[e.code]
+       }
+       // max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y"
+       // x can be at most 20 characters. y can be at most 19.
+       b := make([]byte, 0, 100)
+       b = append(b, "runtime error: "...)
+       for i := 0; i < len(fmt); i++ {
+               c := fmt[i]
+               if c != '%' {
+                       b = append(b, c)
+                       continue
+               }
+               i++
+               switch fmt[i] {
+               case 'x':
+                       b = appendIntStr(b, e.x, e.signed)
+               case 'y':
+                       b = appendIntStr(b, int64(e.y), true)
+               }
+       }
+       return string(b)
+}
+
 type stringer interface {
        String() string
 }
index 5469114a2b7dbfaa76a899d32967848ea08cfcca..d7ea1ef84190646e076fcb25171c9bf743bc32b5 100644 (file)
@@ -338,18 +338,6 @@ func nanotime() int64 {
        return ns
 }
 
-//go:nosplit
-func itoa(buf []byte, val uint64) []byte {
-       i := len(buf) - 1
-       for val >= 10 {
-               buf[i] = byte(val%10 + '0')
-               i--
-               val /= 10
-       }
-       buf[i] = byte(val + '0')
-       return buf[i:]
-}
-
 var goexits = []byte("go: exit ")
 var emptystatus = []byte("\x00")
 var exiting uint32
index 59916dd5e5c15a1167ae433c949d8c33be1cdb92..918ab7682a5d5bc43a1157fe455a347c2bda4ff1 100644 (file)
@@ -10,85 +10,176 @@ import (
        "unsafe"
 )
 
-// Calling panic with one of the errors below will call errorString.Error
-// which will call mallocgc to concatenate strings. That will fail if
-// malloc is locked, causing a confusing error message. Throw a better
-// error message instead.
-func panicCheckMalloc(err error) {
+// Check to make sure we can really generate a panic. If the panic
+// was generated from the runtime, or from inside malloc, then convert
+// to a throw of msg.
+// pc should be the program counter of the compiler-generated code that
+// triggered this panic.
+func panicCheck1(pc uintptr, msg string) {
+       if sys.GoarchWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") {
+               // Note: wasm can't tail call, so we can't get the original caller's pc.
+               throw(msg)
+       }
+       // TODO: is this redundant? How could we be in malloc
+       // but not in the runtime? runtime/internal/*, maybe?
        gp := getg()
        if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
-               throw(string(err.(errorString)))
+               throw(msg)
        }
 }
 
-var indexError = error(errorString("index out of range"))
+// Same as above, but calling from the runtime is allowed.
+func panicCheck2(err string) {
+       gp := getg()
+       if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
+               throw(err)
+       }
+}
 
-// The panic{index,slice,divide,shift} functions are called by
+// The panic{Index,Slice,divide,shift} functions are called by
 // code generated by the compiler for out of bounds index expressions,
 // out of bounds slice expressions, division by zero, and shift by negative.
 // The panicdivide (again), panicoverflow, panicfloat, and panicmem
 // functions are called by the signal handler when a signal occurs
 // indicating the respective problem.
 //
-// Since panic{index,slice,shift} are never called directly, and
+// Since panic{Index,Slice,shift} are never called directly, and
 // since the runtime package should never have an out of bounds slice
 // or array reference or negative shift, if we see those functions called from the
 // runtime package we turn the panic into a throw. That will dump the
 // entire runtime stack for easier debugging.
+//
+// The panic{Index,Slice} functions are implemented in assembly and tail call
+// to the goPanic{Index,Slice} functions below. This is done so we can use
+// a space-minimal register calling convention.
 
-func panicindex() {
-       if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
-               throw(string(indexError.(errorString)))
-       }
-       panicCheckMalloc(indexError)
-       panic(indexError)
+// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
+func goPanicIndex(x int, y int) {
+       panicCheck1(getcallerpc(), "index out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
+}
+func goPanicIndexU(x uint, y int) {
+       panicCheck1(getcallerpc(), "index out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
 }
 
-var sliceError = error(errorString("slice bounds out of range"))
+// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
+func goPanicSliceAlen(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
+}
+func goPanicSliceAlenU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
+}
+func goPanicSliceAcap(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
+}
+func goPanicSliceAcapU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
+}
 
-func panicslice() {
-       if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
-               throw(string(sliceError.(errorString)))
-       }
-       panicCheckMalloc(sliceError)
-       panic(sliceError)
+// failures in the comparisons for s[x:y], 0 <= x <= y
+func goPanicSliceB(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
+}
+func goPanicSliceBU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
+}
+
+// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
+func goPanicSlice3Alen(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
+}
+func goPanicSlice3AlenU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
+}
+func goPanicSlice3Acap(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
+}
+func goPanicSlice3AcapU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
+}
+
+// failures in the comparisons for s[:x:y], 0 <= x <= y
+func goPanicSlice3B(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
+}
+func goPanicSlice3BU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
+}
+
+// failures in the comparisons for s[x:y:], 0 <= x <= y
+func goPanicSlice3C(x int, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
+}
+func goPanicSlice3CU(x uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
+}
+
+// Implemented in assembly, as they take arguments in registers.
+// Declared here to mark them as ABIInternal.
+func panicIndex(x int, y int)
+func panicIndexU(x uint, y int)
+func panicSliceAlen(x int, y int)
+func panicSliceAlenU(x uint, y int)
+func panicSliceAcap(x int, y int)
+func panicSliceAcapU(x uint, y int)
+func panicSliceB(x int, y int)
+func panicSliceBU(x uint, y int)
+func panicSlice3Alen(x int, y int)
+func panicSlice3AlenU(x uint, y int)
+func panicSlice3Acap(x int, y int)
+func panicSlice3AcapU(x uint, y int)
+func panicSlice3B(x int, y int)
+func panicSlice3BU(x uint, y int)
+func panicSlice3C(x int, y int)
+func panicSlice3CU(x uint, y int)
+
+var shiftError = error(errorString("negative shift amount"))
+
+func panicshift() {
+       panicCheck1(getcallerpc(), "negative shift amount")
+       panic(shiftError)
 }
 
 var divideError = error(errorString("integer divide by zero"))
 
 func panicdivide() {
-       panicCheckMalloc(divideError)
+       panicCheck2("integer divide by zero")
        panic(divideError)
 }
 
 var overflowError = error(errorString("integer overflow"))
 
 func panicoverflow() {
-       panicCheckMalloc(overflowError)
+       panicCheck2("integer overflow")
        panic(overflowError)
 }
 
-var shiftError = error(errorString("negative shift amount"))
-
-func panicshift() {
-       if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
-               throw(string(shiftError.(errorString)))
-       }
-       panicCheckMalloc(shiftError)
-       panic(shiftError)
-}
-
 var floatError = error(errorString("floating point error"))
 
 func panicfloat() {
-       panicCheckMalloc(floatError)
+       panicCheck2("floating point error")
        panic(floatError)
 }
 
 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
 
 func panicmem() {
-       panicCheckMalloc(memoryError)
+       panicCheck2("invalid memory address or nil pointer dereference")
        panic(memoryError)
 }
 
diff --git a/src/runtime/panic32.go b/src/runtime/panic32.go
new file mode 100644 (file)
index 0000000..b89ce9d
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 amd64p32 arm mips mipsle
+
+package runtime
+
+// Additional index/slice error paths for 32-bit platforms.
+// Used when the high word of a 64-bit index is not zero.
+
+// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
+func goPanicExtendIndex(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "index out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsIndex})
+}
+func goPanicExtendIndexU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "index out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsIndex})
+}
+
+// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
+func goPanicExtendSliceAlen(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAlen})
+}
+func goPanicExtendSliceAlenU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAlen})
+}
+func goPanicExtendSliceAcap(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAcap})
+}
+func goPanicExtendSliceAcapU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAcap})
+}
+
+// failures in the comparisons for s[x:y], 0 <= x <= y
+func goPanicExtendSliceB(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceB})
+}
+func goPanicExtendSliceBU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceB})
+}
+
+// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
+func goPanicExtendSlice3Alen(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Alen})
+}
+func goPanicExtendSlice3AlenU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Alen})
+}
+func goPanicExtendSlice3Acap(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Acap})
+}
+func goPanicExtendSlice3AcapU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Acap})
+}
+
+// failures in the comparisons for s[:x:y], 0 <= x <= y
+func goPanicExtendSlice3B(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3B})
+}
+func goPanicExtendSlice3BU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3B})
+}
+
+// failures in the comparisons for s[x:y:], 0 <= x <= y
+func goPanicExtendSlice3C(hi int, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3C})
+}
+func goPanicExtendSlice3CU(hi uint, lo uint, y int) {
+       panicCheck1(getcallerpc(), "slice bounds out of range")
+       panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3C})
+}
+
+// Implemented in assembly, as they take arguments in registers.
+// Declared here to mark them as ABIInternal.
+func panicExtendIndex(hi int, lo uint, y int)
+func panicExtendIndexU(hi uint, lo uint, y int)
+func panicExtendSliceAlen(hi int, lo uint, y int)
+func panicExtendSliceAlenU(hi uint, lo uint, y int)
+func panicExtendSliceAcap(hi int, lo uint, y int)
+func panicExtendSliceAcapU(hi uint, lo uint, y int)
+func panicExtendSliceB(hi int, lo uint, y int)
+func panicExtendSliceBU(hi uint, lo uint, y int)
+func panicExtendSlice3Alen(hi int, lo uint, y int)
+func panicExtendSlice3AlenU(hi uint, lo uint, y int)
+func panicExtendSlice3Acap(hi int, lo uint, y int)
+func panicExtendSlice3AcapU(hi uint, lo uint, y int)
+func panicExtendSlice3B(hi int, lo uint, y int)
+func panicExtendSlice3BU(hi uint, lo uint, y int)
+func panicExtendSlice3C(hi int, lo uint, y int)
+func panicExtendSlice3CU(hi uint, lo uint, y int)
index 2b4422ebd279a1bae09002e9316bbf2b378087f6..72da47c7e98505f73e7e2695d31059306411d1eb 100644 (file)
@@ -20,7 +20,7 @@ var sink16 uint16
 // ------------- //
 
 func load_le64(b []byte) {
-       // amd64:`MOVQ\s\(.*\),`,-`MOV[BWL]`,-`OR`
+       // amd64:`MOVQ\s\(.*\),`,-`MOV[BWL]\t[^$]`,-`OR`
        // s390x:`MOVDBR\s\(.*\),`
        // arm64:`MOVD\s\(R[0-9]+\),`,-`MOV[BHW]`
        // ppc64le:`MOVD\s`,-`MOV[BHW]Z`
@@ -28,7 +28,7 @@ func load_le64(b []byte) {
 }
 
 func load_le64_idx(b []byte, idx int) {
-       // amd64:`MOVQ\s\(.*\)\(.*\*1\),`,-`MOV[BWL]`,-`OR`
+       // amd64:`MOVQ\s\(.*\)\(.*\*1\),`,-`MOV[BWL]\t[^$]`,-`OR`
        // s390x:`MOVDBR\s\(.*\)\(.*\*1\),`
        // arm64:`MOVD\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[BHW]`
        // ppc64le:`MOVD\s`,-`MOV[BHW]Z\s`
@@ -68,7 +68,7 @@ func load_le16_idx(b []byte, idx int) {
 }
 
 func load_be64(b []byte) {
-       // amd64:`BSWAPQ`,-`MOV[BWL]`,-`OR`
+       // amd64:`BSWAPQ`,-`MOV[BWL]\t[^$]`,-`OR`
        // s390x:`MOVD\s\(.*\),`
        // arm64:`REV`,`MOVD\s\(R[0-9]+\),`,-`MOV[BHW]`,-`REVW`,-`REV16W`
        // ppc64le:`MOVDBR`
@@ -76,7 +76,7 @@ func load_be64(b []byte) {
 }
 
 func load_be64_idx(b []byte, idx int) {
-       // amd64:`BSWAPQ`,-`MOV[BWL]`,-`OR`
+       // amd64:`BSWAPQ`,-`MOV[BWL]\t[^$]`,-`OR`
        // s390x:`MOVD\s\(.*\)\(.*\*1\),`
        // arm64:`REV`,`MOVD\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[WHB]`,-`REVW`,-`REV16W`
        // ppc64le:`MOVDBR`
@@ -141,7 +141,7 @@ func load_le_byte4_uint32_inv(s []byte) uint32 {
 
 func load_le_byte8_uint64(s []byte) uint64 {
        // arm64:`MOVD\t\(R[0-9]+\)`,-`ORR`,-`MOV[BHW]`
-       // amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]`,-`OR`
+       // amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]\t[^$]`,-`OR`
        return uint64(s[0]) | uint64(s[1])<<8 | uint64(s[2])<<16 | uint64(s[3])<<24 | uint64(s[4])<<32 | uint64(s[5])<<40 | uint64(s[6])<<48 | uint64(s[7])<<56
 }
 
@@ -180,7 +180,7 @@ func load_be_byte8_uint64(s []byte) uint64 {
 
 func load_be_byte8_uint64_inv(s []byte) uint64 {
        // arm64:`MOVD\t\(R[0-9]+\)`,`REV`,-`ORR`,-`REVW`,-`REV16W`,-`MOV[BHW]`
-       // amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]`,-`OR`
+       // amd64:`MOVQ\s\([A-Z]+\),\s[A-Z]+`,-`MOV[BWL]\t[^$]`,-`OR`
        return uint64(s[7]) | uint64(s[6])<<8 | uint64(s[5])<<16 | uint64(s[4])<<24 | uint64(s[3])<<32 | uint64(s[2])<<40 | uint64(s[1])<<48 | uint64(s[0])<<56
 }
 
index a27fd92399db5e6417a32f2c30dbb6fbc013cf38..936105ed126bd38e1128ce7e9721784c7f7b1e20 100644 (file)
@@ -48,7 +48,7 @@ func test16(x []byte) uint16 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
@@ -66,7 +66,7 @@ func test16i(x []byte, i int) uint16 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
@@ -80,7 +80,7 @@ func test32(x []byte) uint32 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
@@ -94,7 +94,7 @@ func test32i(x []byte, i int) uint32 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
@@ -108,7 +108,7 @@ func test64(x []byte) uint64 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
@@ -123,7 +123,7 @@ func test64i(x []byte, i int) uint64 {
                        panic("no fault or bounds check failure happened")
                }
                s := fmt.Sprintf("%s", r)
-               if s != "runtime error: index out of range" {
+               if s != "runtime error: index out of range [1] with length 1" {
                        panic("bad panic: " + s)
                }
        }()
diff --git a/test/fixedbugs/issue30116.go b/test/fixedbugs/issue30116.go
new file mode 100644 (file)
index 0000000..452a6e3
--- /dev/null
@@ -0,0 +1,112 @@
+// run
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This test makes sure the text output for bounds check failures is as expected.
+
+package main
+
+import (
+       "fmt"
+       "os"
+       "runtime"
+       "text/tabwriter"
+)
+
+// Testing with length 3 slices, arrays, and strings.
+// Large (>1<<32) values are included to test 32-bit platforms.
+var indexes = []int64{-9876543210, -1, 0, 2, 3, 9876543210}
+var slices = []int64{-9876543210, -1, 0, 3, 4, 9876543210}
+
+var w *tabwriter.Writer
+
+func main() {
+       w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
+       defer w.Flush()
+       doIndex()
+       doSlice()
+       doSlice3()
+}
+func doIndex() {
+       a := []int{1, 2, 3}
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("slice[%d]", i), func() {
+                       _ = a[i]
+               })
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("array[%d]", i), func() {
+                       _ = b[i]
+               })
+       }
+       c := "123"
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("string[%d]", i), func() {
+                       _ = c[i]
+               })
+       }
+}
+
+func doSlice() {
+       a := []int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
+                               _ = a[i:j]
+                       })
+               }
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
+                               _ = b[i:j]
+                       })
+               }
+       }
+       c := "123"
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
+                               _ = c[i:j]
+                       })
+               }
+       }
+}
+
+func doSlice3() {
+       a := []int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       for _, k := range slices {
+                               printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
+                                       _ = a[i:j:k]
+                               })
+                       }
+               }
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       for _, k := range slices {
+                               printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
+                                       _ = b[i:j:k]
+                               })
+                       }
+               }
+       }
+}
+
+func printPanic(msg string, f func()) {
+       defer func() {
+               res := "no panic"
+               if e := recover(); e != nil {
+                       res = e.(runtime.Error).Error()
+               }
+               fmt.Fprintf(w, "%s\t %s\n", msg, res)
+       }()
+       f()
+}
diff --git a/test/fixedbugs/issue30116.out b/test/fixedbugs/issue30116.out
new file mode 100644 (file)
index 0000000..bde134d
--- /dev/null
@@ -0,0 +1,558 @@
+                         slice[-9876543210] runtime error: index out of range [-9876543210]
+                                  slice[-1] runtime error: index out of range [-1]
+                                   slice[0] no panic
+                                   slice[2] no panic
+                                   slice[3] runtime error: index out of range [3] with length 3
+                          slice[9876543210] runtime error: index out of range [9876543210] with length 3
+                         array[-9876543210] runtime error: index out of range [-9876543210]
+                                  array[-1] runtime error: index out of range [-1]
+                                   array[0] no panic
+                                   array[2] no panic
+                                   array[3] runtime error: index out of range [3] with length 3
+                          array[9876543210] runtime error: index out of range [9876543210] with length 3
+                        string[-9876543210] runtime error: index out of range [-9876543210]
+                                 string[-1] runtime error: index out of range [-1]
+                                  string[0] no panic
+                                  string[2] no panic
+                                  string[3] runtime error: index out of range [3] with length 3
+                         string[9876543210] runtime error: index out of range [9876543210] with length 3
+             slice[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                      slice[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+                       slice[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+                       slice[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+                       slice[-9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
+              slice[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+                      slice[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                               slice[-1:-1] runtime error: slice bounds out of range [:-1]
+                                slice[-1:0] runtime error: slice bounds out of range [-1:]
+                                slice[-1:3] runtime error: slice bounds out of range [-1:]
+                                slice[-1:4] runtime error: slice bounds out of range [:4] with capacity 3
+                       slice[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+                       slice[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                slice[0:-1] runtime error: slice bounds out of range [:-1]
+                                 slice[0:0] no panic
+                                 slice[0:3] no panic
+                                 slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
+                        slice[0:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+                       slice[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                slice[3:-1] runtime error: slice bounds out of range [:-1]
+                                 slice[3:0] runtime error: slice bounds out of range [3:0]
+                                 slice[3:3] no panic
+                                 slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
+                        slice[3:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+                       slice[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                slice[4:-1] runtime error: slice bounds out of range [:-1]
+                                 slice[4:0] runtime error: slice bounds out of range [4:0]
+                                 slice[4:3] runtime error: slice bounds out of range [4:3]
+                                 slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
+                        slice[4:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+              slice[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                       slice[9876543210:-1] runtime error: slice bounds out of range [:-1]
+                        slice[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+                        slice[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+                        slice[9876543210:4] runtime error: slice bounds out of range [:4] with capacity 3
+               slice[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with capacity 3
+             array[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                      array[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+                       array[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+                       array[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+                       array[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+              array[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                      array[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                               array[-1:-1] runtime error: slice bounds out of range [:-1]
+                                array[-1:0] runtime error: slice bounds out of range [-1:]
+                                array[-1:3] runtime error: slice bounds out of range [-1:]
+                                array[-1:4] runtime error: slice bounds out of range [:4] with length 3
+                       array[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                       array[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                array[0:-1] runtime error: slice bounds out of range [:-1]
+                                 array[0:0] no panic
+                                 array[0:3] no panic
+                                 array[0:4] runtime error: slice bounds out of range [:4] with length 3
+                        array[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                       array[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                array[3:-1] runtime error: slice bounds out of range [:-1]
+                                 array[3:0] runtime error: slice bounds out of range [3:0]
+                                 array[3:3] no panic
+                                 array[3:4] runtime error: slice bounds out of range [:4] with length 3
+                        array[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                       array[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                                array[4:-1] runtime error: slice bounds out of range [:-1]
+                                 array[4:0] runtime error: slice bounds out of range [4:0]
+                                 array[4:3] runtime error: slice bounds out of range [4:3]
+                                 array[4:4] runtime error: slice bounds out of range [:4] with length 3
+                        array[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+              array[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                       array[9876543210:-1] runtime error: slice bounds out of range [:-1]
+                        array[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+                        array[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+                        array[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+               array[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+            string[-9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                     string[-9876543210:-1] runtime error: slice bounds out of range [:-1]
+                      string[-9876543210:0] runtime error: slice bounds out of range [-9876543210:]
+                      string[-9876543210:3] runtime error: slice bounds out of range [-9876543210:]
+                      string[-9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+             string[-9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                     string[-1:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                              string[-1:-1] runtime error: slice bounds out of range [:-1]
+                               string[-1:0] runtime error: slice bounds out of range [-1:]
+                               string[-1:3] runtime error: slice bounds out of range [-1:]
+                               string[-1:4] runtime error: slice bounds out of range [:4] with length 3
+                      string[-1:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                      string[0:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                               string[0:-1] runtime error: slice bounds out of range [:-1]
+                                string[0:0] no panic
+                                string[0:3] no panic
+                                string[0:4] runtime error: slice bounds out of range [:4] with length 3
+                       string[0:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                      string[3:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                               string[3:-1] runtime error: slice bounds out of range [:-1]
+                                string[3:0] runtime error: slice bounds out of range [3:0]
+                                string[3:3] no panic
+                                string[3:4] runtime error: slice bounds out of range [:4] with length 3
+                       string[3:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+                      string[4:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                               string[4:-1] runtime error: slice bounds out of range [:-1]
+                                string[4:0] runtime error: slice bounds out of range [4:0]
+                                string[4:3] runtime error: slice bounds out of range [4:3]
+                                string[4:4] runtime error: slice bounds out of range [:4] with length 3
+                       string[4:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+             string[9876543210:-9876543210] runtime error: slice bounds out of range [:-9876543210]
+                      string[9876543210:-1] runtime error: slice bounds out of range [:-1]
+                       string[9876543210:0] runtime error: slice bounds out of range [9876543210:0]
+                       string[9876543210:3] runtime error: slice bounds out of range [9876543210:3]
+                       string[9876543210:4] runtime error: slice bounds out of range [:4] with length 3
+              string[9876543210:9876543210] runtime error: slice bounds out of range [:9876543210] with length 3
+ slice[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+          slice[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+           slice[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+           slice[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+           slice[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+  slice[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+          slice[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                   slice[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+                    slice[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+                    slice[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+                    slice[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+           slice[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+                     slice[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
+                     slice[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
+                     slice[-9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+                     slice[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+                     slice[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
+                     slice[-9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+                     slice[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+                     slice[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+                     slice[-9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+  slice[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+           slice[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+            slice[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+            slice[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+            slice[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+   slice[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+          slice[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                   slice[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                    slice[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                    slice[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                    slice[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+           slice[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                   slice[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                            slice[-1:-1:-1] runtime error: slice bounds out of range [::-1]
+                             slice[-1:-1:0] runtime error: slice bounds out of range [:-1:]
+                             slice[-1:-1:3] runtime error: slice bounds out of range [:-1:]
+                             slice[-1:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+                    slice[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[-1:0:-1] runtime error: slice bounds out of range [::-1]
+                              slice[-1:0:0] runtime error: slice bounds out of range [-1::]
+                              slice[-1:0:3] runtime error: slice bounds out of range [-1::]
+                              slice[-1:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[-1:3:-1] runtime error: slice bounds out of range [::-1]
+                              slice[-1:3:0] runtime error: slice bounds out of range [:3:0]
+                              slice[-1:3:3] runtime error: slice bounds out of range [-1::]
+                              slice[-1:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[-1:4:-1] runtime error: slice bounds out of range [::-1]
+                              slice[-1:4:0] runtime error: slice bounds out of range [:4:0]
+                              slice[-1:4:3] runtime error: slice bounds out of range [:4:3]
+                              slice[-1:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     slice[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                     slice[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                     slice[-1:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     slice[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[0:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[0:-1:-1] runtime error: slice bounds out of range [::-1]
+                              slice[0:-1:0] runtime error: slice bounds out of range [:-1:]
+                              slice[0:-1:3] runtime error: slice bounds out of range [:-1:]
+                              slice[0:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[0:0:-1] runtime error: slice bounds out of range [::-1]
+                               slice[0:0:0] no panic
+                               slice[0:0:3] no panic
+                               slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[0:3:-1] runtime error: slice bounds out of range [::-1]
+                               slice[0:3:0] runtime error: slice bounds out of range [:3:0]
+                               slice[0:3:3] no panic
+                               slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[0:4:-1] runtime error: slice bounds out of range [::-1]
+                               slice[0:4:0] runtime error: slice bounds out of range [:4:0]
+                               slice[0:4:3] runtime error: slice bounds out of range [:4:3]
+                               slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      slice[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      slice[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      slice[0:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     slice[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[3:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[3:-1:-1] runtime error: slice bounds out of range [::-1]
+                              slice[3:-1:0] runtime error: slice bounds out of range [:-1:]
+                              slice[3:-1:3] runtime error: slice bounds out of range [:-1:]
+                              slice[3:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[3:0:-1] runtime error: slice bounds out of range [::-1]
+                               slice[3:0:0] runtime error: slice bounds out of range [3:0:]
+                               slice[3:0:3] runtime error: slice bounds out of range [3:0:]
+                               slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[3:3:-1] runtime error: slice bounds out of range [::-1]
+                               slice[3:3:0] runtime error: slice bounds out of range [:3:0]
+                               slice[3:3:3] no panic
+                               slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[3:4:-1] runtime error: slice bounds out of range [::-1]
+                               slice[3:4:0] runtime error: slice bounds out of range [:4:0]
+                               slice[3:4:3] runtime error: slice bounds out of range [:4:3]
+                               slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      slice[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      slice[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      slice[3:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     slice[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     slice[4:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                    slice[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             slice[4:-1:-1] runtime error: slice bounds out of range [::-1]
+                              slice[4:-1:0] runtime error: slice bounds out of range [:-1:]
+                              slice[4:-1:3] runtime error: slice bounds out of range [:-1:]
+                              slice[4:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[4:0:-1] runtime error: slice bounds out of range [::-1]
+                               slice[4:0:0] runtime error: slice bounds out of range [4:0:]
+                               slice[4:0:3] runtime error: slice bounds out of range [4:0:]
+                               slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[4:3:-1] runtime error: slice bounds out of range [::-1]
+                               slice[4:3:0] runtime error: slice bounds out of range [:3:0]
+                               slice[4:3:3] runtime error: slice bounds out of range [4:3:]
+                               slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+                     slice[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              slice[4:4:-1] runtime error: slice bounds out of range [::-1]
+                               slice[4:4:0] runtime error: slice bounds out of range [:4:0]
+                               slice[4:4:3] runtime error: slice bounds out of range [:4:3]
+                               slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                      slice[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      slice[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      slice[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      slice[4:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+  slice[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+           slice[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+            slice[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+            slice[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+            slice[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+   slice[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+           slice[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    slice[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+                     slice[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+                     slice[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+                     slice[9876543210:-1:4] runtime error: slice bounds out of range [::4] with capacity 3
+            slice[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+                      slice[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
+                      slice[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
+                      slice[9876543210:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+                      slice[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+                      slice[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
+                      slice[9876543210:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+            slice[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     slice[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+                      slice[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+                      slice[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+                      slice[9876543210:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+             slice[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+   slice[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+            slice[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+             slice[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+             slice[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+             slice[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with capacity 3
+    slice[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with capacity 3
+ array[-9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+          array[-9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+           array[-9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+           array[-9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+           array[-9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+  array[-9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+          array[-9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                   array[-9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+                    array[-9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+                    array[-9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+                    array[-9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
+           array[-9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[-9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[-9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+                     array[-9876543210:0:0] runtime error: slice bounds out of range [-9876543210::]
+                     array[-9876543210:0:3] runtime error: slice bounds out of range [-9876543210::]
+                     array[-9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
+            array[-9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[-9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[-9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+                     array[-9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+                     array[-9876543210:3:3] runtime error: slice bounds out of range [-9876543210::]
+                     array[-9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
+            array[-9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[-9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[-9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+                     array[-9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+                     array[-9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+                     array[-9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
+            array[-9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+  array[-9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+           array[-9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+            array[-9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+            array[-9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+            array[-9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+   array[-9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+          array[-1:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                   array[-1:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                    array[-1:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                    array[-1:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                    array[-1:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+           array[-1:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                   array[-1:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                            array[-1:-1:-1] runtime error: slice bounds out of range [::-1]
+                             array[-1:-1:0] runtime error: slice bounds out of range [:-1:]
+                             array[-1:-1:3] runtime error: slice bounds out of range [:-1:]
+                             array[-1:-1:4] runtime error: slice bounds out of range [::4] with length 3
+                    array[-1:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[-1:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[-1:0:-1] runtime error: slice bounds out of range [::-1]
+                              array[-1:0:0] runtime error: slice bounds out of range [-1::]
+                              array[-1:0:3] runtime error: slice bounds out of range [-1::]
+                              array[-1:0:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[-1:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[-1:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[-1:3:-1] runtime error: slice bounds out of range [::-1]
+                              array[-1:3:0] runtime error: slice bounds out of range [:3:0]
+                              array[-1:3:3] runtime error: slice bounds out of range [-1::]
+                              array[-1:3:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[-1:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[-1:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[-1:4:-1] runtime error: slice bounds out of range [::-1]
+                              array[-1:4:0] runtime error: slice bounds out of range [:4:0]
+                              array[-1:4:3] runtime error: slice bounds out of range [:4:3]
+                              array[-1:4:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[-1:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[-1:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[-1:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     array[-1:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                     array[-1:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                     array[-1:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+            array[-1:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[0:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[0:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     array[0:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     array[0:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     array[0:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+            array[0:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[0:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[0:-1:-1] runtime error: slice bounds out of range [::-1]
+                              array[0:-1:0] runtime error: slice bounds out of range [:-1:]
+                              array[0:-1:3] runtime error: slice bounds out of range [:-1:]
+                              array[0:-1:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[0:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[0:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[0:0:-1] runtime error: slice bounds out of range [::-1]
+                               array[0:0:0] no panic
+                               array[0:0:3] no panic
+                               array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[0:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[0:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[0:3:-1] runtime error: slice bounds out of range [::-1]
+                               array[0:3:0] runtime error: slice bounds out of range [:3:0]
+                               array[0:3:3] no panic
+                               array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[0:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[0:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[0:4:-1] runtime error: slice bounds out of range [::-1]
+                               array[0:4:0] runtime error: slice bounds out of range [:4:0]
+                               array[0:4:3] runtime error: slice bounds out of range [:4:3]
+                               array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[0:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[0:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[0:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      array[0:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      array[0:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      array[0:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+             array[0:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[3:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[3:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     array[3:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     array[3:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     array[3:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+            array[3:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[3:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[3:-1:-1] runtime error: slice bounds out of range [::-1]
+                              array[3:-1:0] runtime error: slice bounds out of range [:-1:]
+                              array[3:-1:3] runtime error: slice bounds out of range [:-1:]
+                              array[3:-1:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[3:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[3:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[3:0:-1] runtime error: slice bounds out of range [::-1]
+                               array[3:0:0] runtime error: slice bounds out of range [3:0:]
+                               array[3:0:3] runtime error: slice bounds out of range [3:0:]
+                               array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[3:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[3:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[3:3:-1] runtime error: slice bounds out of range [::-1]
+                               array[3:3:0] runtime error: slice bounds out of range [:3:0]
+                               array[3:3:3] no panic
+                               array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[3:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[3:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[3:4:-1] runtime error: slice bounds out of range [::-1]
+                               array[3:4:0] runtime error: slice bounds out of range [:4:0]
+                               array[3:4:3] runtime error: slice bounds out of range [:4:3]
+                               array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[3:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[3:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[3:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      array[3:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      array[3:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      array[3:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+             array[3:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[4:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[4:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+                     array[4:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+                     array[4:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+                     array[4:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+            array[4:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                    array[4:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                             array[4:-1:-1] runtime error: slice bounds out of range [::-1]
+                              array[4:-1:0] runtime error: slice bounds out of range [:-1:]
+                              array[4:-1:3] runtime error: slice bounds out of range [:-1:]
+                              array[4:-1:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[4:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[4:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[4:0:-1] runtime error: slice bounds out of range [::-1]
+                               array[4:0:0] runtime error: slice bounds out of range [4:0:]
+                               array[4:0:3] runtime error: slice bounds out of range [4:0:]
+                               array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[4:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[4:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[4:3:-1] runtime error: slice bounds out of range [::-1]
+                               array[4:3:0] runtime error: slice bounds out of range [:3:0]
+                               array[4:3:3] runtime error: slice bounds out of range [4:3:]
+                               array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[4:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+                     array[4:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                              array[4:4:-1] runtime error: slice bounds out of range [::-1]
+                               array[4:4:0] runtime error: slice bounds out of range [:4:0]
+                               array[4:4:3] runtime error: slice bounds out of range [:4:3]
+                               array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
+                      array[4:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[4:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[4:9876543210:-1] runtime error: slice bounds out of range [::-1]
+                      array[4:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+                      array[4:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+                      array[4:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+             array[4:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+  array[9876543210:-9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+           array[9876543210:-9876543210:-1] runtime error: slice bounds out of range [::-1]
+            array[9876543210:-9876543210:0] runtime error: slice bounds out of range [:-9876543210:]
+            array[9876543210:-9876543210:3] runtime error: slice bounds out of range [:-9876543210:]
+            array[9876543210:-9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+   array[9876543210:-9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+           array[9876543210:-1:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                    array[9876543210:-1:-1] runtime error: slice bounds out of range [::-1]
+                     array[9876543210:-1:0] runtime error: slice bounds out of range [:-1:]
+                     array[9876543210:-1:3] runtime error: slice bounds out of range [:-1:]
+                     array[9876543210:-1:4] runtime error: slice bounds out of range [::4] with length 3
+            array[9876543210:-1:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[9876543210:0:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[9876543210:0:-1] runtime error: slice bounds out of range [::-1]
+                      array[9876543210:0:0] runtime error: slice bounds out of range [9876543210:0:]
+                      array[9876543210:0:3] runtime error: slice bounds out of range [9876543210:0:]
+                      array[9876543210:0:4] runtime error: slice bounds out of range [::4] with length 3
+             array[9876543210:0:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[9876543210:3:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[9876543210:3:-1] runtime error: slice bounds out of range [::-1]
+                      array[9876543210:3:0] runtime error: slice bounds out of range [:3:0]
+                      array[9876543210:3:3] runtime error: slice bounds out of range [9876543210:3:]
+                      array[9876543210:3:4] runtime error: slice bounds out of range [::4] with length 3
+             array[9876543210:3:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+            array[9876543210:4:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+                     array[9876543210:4:-1] runtime error: slice bounds out of range [::-1]
+                      array[9876543210:4:0] runtime error: slice bounds out of range [:4:0]
+                      array[9876543210:4:3] runtime error: slice bounds out of range [:4:3]
+                      array[9876543210:4:4] runtime error: slice bounds out of range [::4] with length 3
+             array[9876543210:4:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
+   array[9876543210:9876543210:-9876543210] runtime error: slice bounds out of range [::-9876543210]
+            array[9876543210:9876543210:-1] runtime error: slice bounds out of range [::-1]
+             array[9876543210:9876543210:0] runtime error: slice bounds out of range [:9876543210:0]
+             array[9876543210:9876543210:3] runtime error: slice bounds out of range [:9876543210:3]
+             array[9876543210:9876543210:4] runtime error: slice bounds out of range [::4] with length 3
+    array[9876543210:9876543210:9876543210] runtime error: slice bounds out of range [::9876543210] with length 3
diff --git a/test/fixedbugs/issue30116u.go b/test/fixedbugs/issue30116u.go
new file mode 100644 (file)
index 0000000..7c2aea2
--- /dev/null
@@ -0,0 +1,112 @@
+// run
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This test makes sure the text output for bounds check failures is as expected.
+
+package main
+
+import (
+       "fmt"
+       "os"
+       "runtime"
+       "text/tabwriter"
+)
+
+// Testing with length 3 slices, arrays, and strings.
+// A large (>1<<32) value is included to test 32-bit platforms.
+var indexes = []uint64{0, 2, 3, 1<<32 - 1, 1<<64 - 1}
+var slices = []uint64{0, 3, 4, 1<<32 - 1, 1<<64 - 1}
+
+var w *tabwriter.Writer
+
+func main() {
+       w = tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.AlignRight)
+       defer w.Flush()
+       doIndex()
+       doSlice()
+       doSlice3()
+}
+func doIndex() {
+       a := []int{1, 2, 3}
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("slice[%d]", i), func() {
+                       _ = a[i]
+               })
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("array[%d]", i), func() {
+                       _ = b[i]
+               })
+       }
+       c := "123"
+       for _, i := range indexes {
+               printPanic(fmt.Sprintf("string[%d]", i), func() {
+                       _ = c[i]
+               })
+       }
+}
+
+func doSlice() {
+       a := []int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("slice[%d:%d]", i, j), func() {
+                               _ = a[i:j]
+                       })
+               }
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("array[%d:%d]", i, j), func() {
+                               _ = b[i:j]
+                       })
+               }
+       }
+       c := "123"
+       for _, i := range slices {
+               for _, j := range slices {
+                       printPanic(fmt.Sprintf("string[%d:%d]", i, j), func() {
+                               _ = c[i:j]
+                       })
+               }
+       }
+}
+
+func doSlice3() {
+       a := []int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       for _, k := range slices {
+                               printPanic(fmt.Sprintf("slice[%d:%d:%d]", i, j, k), func() {
+                                       _ = a[i:j:k]
+                               })
+                       }
+               }
+       }
+       b := [3]int{1, 2, 3}
+       for _, i := range slices {
+               for _, j := range slices {
+                       for _, k := range slices {
+                               printPanic(fmt.Sprintf("array[%d:%d:%d]", i, j, k), func() {
+                                       _ = b[i:j:k]
+                               })
+                       }
+               }
+       }
+}
+
+func printPanic(msg string, f func()) {
+       defer func() {
+               res := "no panic"
+               if e := recover(); e != nil {
+                       res = e.(runtime.Error).Error()
+               }
+               fmt.Fprintf(w, "%s\t %s\n", msg, res)
+       }()
+       f()
+}
diff --git a/test/fixedbugs/issue30116u.out b/test/fixedbugs/issue30116u.out
new file mode 100644 (file)
index 0000000..ee19192
--- /dev/null
@@ -0,0 +1,340 @@
+                                                              slice[0] no panic
+                                                              slice[2] no panic
+                                                              slice[3] runtime error: index out of range [3] with length 3
+                                                     slice[4294967295] runtime error: index out of range [4294967295] with length 3
+                                           slice[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+                                                              array[0] no panic
+                                                              array[2] no panic
+                                                              array[3] runtime error: index out of range [3] with length 3
+                                                     array[4294967295] runtime error: index out of range [4294967295] with length 3
+                                           array[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+                                                             string[0] no panic
+                                                             string[2] no panic
+                                                             string[3] runtime error: index out of range [3] with length 3
+                                                    string[4294967295] runtime error: index out of range [4294967295] with length 3
+                                          string[18446744073709551615] runtime error: index out of range [18446744073709551615] with length 3
+                                                            slice[0:0] no panic
+                                                            slice[0:3] no panic
+                                                            slice[0:4] runtime error: slice bounds out of range [:4] with capacity 3
+                                                   slice[0:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+                                         slice[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+                                                            slice[3:0] runtime error: slice bounds out of range [3:0]
+                                                            slice[3:3] no panic
+                                                            slice[3:4] runtime error: slice bounds out of range [:4] with capacity 3
+                                                   slice[3:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+                                         slice[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+                                                            slice[4:0] runtime error: slice bounds out of range [4:0]
+                                                            slice[4:3] runtime error: slice bounds out of range [4:3]
+                                                            slice[4:4] runtime error: slice bounds out of range [:4] with capacity 3
+                                                   slice[4:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+                                         slice[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+                                                   slice[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+                                                   slice[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+                                                   slice[4294967295:4] runtime error: slice bounds out of range [:4] with capacity 3
+                                          slice[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+                                slice[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+                                         slice[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+                                         slice[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+                                         slice[18446744073709551615:4] runtime error: slice bounds out of range [:4] with capacity 3
+                                slice[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with capacity 3
+                      slice[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with capacity 3
+                                                            array[0:0] no panic
+                                                            array[0:3] no panic
+                                                            array[0:4] runtime error: slice bounds out of range [:4] with length 3
+                                                   array[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                         array[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                            array[3:0] runtime error: slice bounds out of range [3:0]
+                                                            array[3:3] no panic
+                                                            array[3:4] runtime error: slice bounds out of range [:4] with length 3
+                                                   array[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                         array[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                            array[4:0] runtime error: slice bounds out of range [4:0]
+                                                            array[4:3] runtime error: slice bounds out of range [4:3]
+                                                            array[4:4] runtime error: slice bounds out of range [:4] with length 3
+                                                   array[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                         array[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                   array[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+                                                   array[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+                                                   array[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
+                                          array[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                array[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                         array[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+                                         array[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+                                         array[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
+                                array[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                      array[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                           string[0:0] no panic
+                                                           string[0:3] no panic
+                                                           string[0:4] runtime error: slice bounds out of range [:4] with length 3
+                                                  string[0:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                        string[0:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                           string[3:0] runtime error: slice bounds out of range [3:0]
+                                                           string[3:3] no panic
+                                                           string[3:4] runtime error: slice bounds out of range [:4] with length 3
+                                                  string[3:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                        string[3:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                           string[4:0] runtime error: slice bounds out of range [4:0]
+                                                           string[4:3] runtime error: slice bounds out of range [4:3]
+                                                           string[4:4] runtime error: slice bounds out of range [:4] with length 3
+                                                  string[4:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                                        string[4:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                  string[4294967295:0] runtime error: slice bounds out of range [4294967295:0]
+                                                  string[4294967295:3] runtime error: slice bounds out of range [4294967295:3]
+                                                  string[4294967295:4] runtime error: slice bounds out of range [:4] with length 3
+                                         string[4294967295:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                               string[4294967295:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                        string[18446744073709551615:0] runtime error: slice bounds out of range [18446744073709551615:0]
+                                        string[18446744073709551615:3] runtime error: slice bounds out of range [18446744073709551615:3]
+                                        string[18446744073709551615:4] runtime error: slice bounds out of range [:4] with length 3
+                               string[18446744073709551615:4294967295] runtime error: slice bounds out of range [:4294967295] with length 3
+                     string[18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [:18446744073709551615] with length 3
+                                                          slice[0:0:0] no panic
+                                                          slice[0:0:3] no panic
+                                                          slice[0:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[0:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          slice[0:3:3] no panic
+                                                          slice[0:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[0:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          slice[0:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          slice[0:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 slice[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 slice[0:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       slice[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       slice[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[3:0:0] runtime error: slice bounds out of range [3:0:]
+                                                          slice[3:0:3] runtime error: slice bounds out of range [3:0:]
+                                                          slice[3:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[3:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          slice[3:3:3] no panic
+                                                          slice[3:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[3:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          slice[3:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          slice[3:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 slice[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 slice[3:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       slice[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       slice[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[4:0:0] runtime error: slice bounds out of range [4:0:]
+                                                          slice[4:0:3] runtime error: slice bounds out of range [4:0:]
+                                                          slice[4:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[4:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          slice[4:3:3] runtime error: slice bounds out of range [4:3:]
+                                                          slice[4:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          slice[4:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          slice[4:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          slice[4:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                                 slice[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                                       slice[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 slice[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 slice[4:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       slice[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       slice[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
+                                                 slice[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
+                                                 slice[4294967295:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
+                                                 slice[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
+                                                 slice[4294967295:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                 slice[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
+                                                 slice[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
+                                                 slice[4294967295:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                                        slice[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                              slice[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                        slice[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                        slice[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                        slice[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+                               slice[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                     slice[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                              slice[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                              slice[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                              slice[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+           slice[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
+                                       slice[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
+                                       slice[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
+                                       slice[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
+                                       slice[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                       slice[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
+                                       slice[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
+                                       slice[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with capacity 3
+                              slice[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+                    slice[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                              slice[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                              slice[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                              slice[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with capacity 3
+                     slice[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+           slice[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                    slice[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                    slice[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                    slice[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with capacity 3
+           slice[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with capacity 3
+ slice[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with capacity 3
+                                                          array[0:0:0] no panic
+                                                          array[0:0:3] no panic
+                                                          array[0:0:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[0:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[0:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[0:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          array[0:3:3] no panic
+                                                          array[0:3:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[0:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[0:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[0:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          array[0:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          array[0:4:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[0:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[0:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[0:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 array[0:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 array[0:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[0:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[0:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[0:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       array[0:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       array[0:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[0:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[0:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[3:0:0] runtime error: slice bounds out of range [3:0:]
+                                                          array[3:0:3] runtime error: slice bounds out of range [3:0:]
+                                                          array[3:0:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[3:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[3:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[3:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          array[3:3:3] no panic
+                                                          array[3:3:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[3:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[3:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[3:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          array[3:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          array[3:4:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[3:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[3:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[3:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 array[3:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 array[3:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[3:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[3:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[3:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       array[3:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       array[3:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[3:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[3:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[4:0:0] runtime error: slice bounds out of range [4:0:]
+                                                          array[4:0:3] runtime error: slice bounds out of range [4:0:]
+                                                          array[4:0:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[4:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[4:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[4:3:0] runtime error: slice bounds out of range [:3:0]
+                                                          array[4:3:3] runtime error: slice bounds out of range [4:3:]
+                                                          array[4:3:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[4:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[4:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                          array[4:4:0] runtime error: slice bounds out of range [:4:0]
+                                                          array[4:4:3] runtime error: slice bounds out of range [:4:3]
+                                                          array[4:4:4] runtime error: slice bounds out of range [::4] with length 3
+                                                 array[4:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                                       array[4:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[4:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                                 array[4:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                                 array[4:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[4:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[4:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[4:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                                       array[4:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                                       array[4:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[4:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[4:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[4294967295:0:0] runtime error: slice bounds out of range [4294967295:0:]
+                                                 array[4294967295:0:3] runtime error: slice bounds out of range [4294967295:0:]
+                                                 array[4294967295:0:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[4294967295:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[4294967295:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[4294967295:3:0] runtime error: slice bounds out of range [:3:0]
+                                                 array[4294967295:3:3] runtime error: slice bounds out of range [4294967295:3:]
+                                                 array[4294967295:3:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[4294967295:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[4294967295:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                                 array[4294967295:4:0] runtime error: slice bounds out of range [:4:0]
+                                                 array[4294967295:4:3] runtime error: slice bounds out of range [:4:3]
+                                                 array[4294967295:4:4] runtime error: slice bounds out of range [::4] with length 3
+                                        array[4294967295:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                              array[4294967295:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                        array[4294967295:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                                        array[4294967295:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                                        array[4294967295:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+                               array[4294967295:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                     array[4294967295:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                              array[4294967295:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                              array[4294967295:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                              array[4294967295:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[4294967295:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+           array[4294967295:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[18446744073709551615:0:0] runtime error: slice bounds out of range [18446744073709551615:0:]
+                                       array[18446744073709551615:0:3] runtime error: slice bounds out of range [18446744073709551615:0:]
+                                       array[18446744073709551615:0:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[18446744073709551615:0:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[18446744073709551615:0:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[18446744073709551615:3:0] runtime error: slice bounds out of range [:3:0]
+                                       array[18446744073709551615:3:3] runtime error: slice bounds out of range [18446744073709551615:3:]
+                                       array[18446744073709551615:3:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[18446744073709551615:3:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[18446744073709551615:3:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                                       array[18446744073709551615:4:0] runtime error: slice bounds out of range [:4:0]
+                                       array[18446744073709551615:4:3] runtime error: slice bounds out of range [:4:3]
+                                       array[18446744073709551615:4:4] runtime error: slice bounds out of range [::4] with length 3
+                              array[18446744073709551615:4:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+                    array[18446744073709551615:4:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                              array[18446744073709551615:4294967295:0] runtime error: slice bounds out of range [:4294967295:0]
+                              array[18446744073709551615:4294967295:3] runtime error: slice bounds out of range [:4294967295:3]
+                              array[18446744073709551615:4294967295:4] runtime error: slice bounds out of range [::4] with length 3
+                     array[18446744073709551615:4294967295:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+           array[18446744073709551615:4294967295:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3
+                    array[18446744073709551615:18446744073709551615:0] runtime error: slice bounds out of range [:18446744073709551615:0]
+                    array[18446744073709551615:18446744073709551615:3] runtime error: slice bounds out of range [:18446744073709551615:3]
+                    array[18446744073709551615:18446744073709551615:4] runtime error: slice bounds out of range [::4] with length 3
+           array[18446744073709551615:18446744073709551615:4294967295] runtime error: slice bounds out of range [::4294967295] with length 3
+ array[18446744073709551615:18446744073709551615:18446744073709551615] runtime error: slice bounds out of range [::18446744073709551615] with length 3