aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@google.com>2019-02-06 14:12:36 -0800
committerKeith Randall <khr@golang.org>2019-03-18 17:33:38 +0000
commit2c423f063b137781a97a6a56998a2e3abffc4051 (patch)
treea77e1513516b655f90c6a9fb12fbc07c9f1e7af1
parentb48bda9c6f57ca9a940eac95700485b9640a62e9 (diff)
downloadgo-2c423f063b137781a97a6a56998a2e3abffc4051.tar.gz
go-2c423f063b137781a97a6a56998a2e3abffc4051.zip
cmd/compile,runtime: provide index information on bounds check failure
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>
-rw-r--r--src/cmd/compile/internal/amd64/ssa.go14
-rw-r--r--src/cmd/compile/internal/arm/ssa.go12
-rw-r--r--src/cmd/compile/internal/arm64/ssa.go6
-rw-r--r--src/cmd/compile/internal/gc/builtin.go461
-rw-r--r--src/cmd/compile/internal/gc/builtin/runtime.go21
-rw-r--r--src/cmd/compile/internal/gc/go.go5
-rw-r--r--src/cmd/compile/internal/gc/ssa.go282
-rw-r--r--src/cmd/compile/internal/mips/ssa.go12
-rw-r--r--src/cmd/compile/internal/mips64/ssa.go6
-rw-r--r--src/cmd/compile/internal/ppc64/ssa.go7
-rw-r--r--src/cmd/compile/internal/s390x/ssa.go6
-rw-r--r--src/cmd/compile/internal/ssa/func.go12
-rw-r--r--src/cmd/compile/internal/ssa/gen/386.rules8
-rw-r--r--src/cmd/compile/internal/ssa/gen/386Ops.go13
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64.rules12
-rw-r--r--src/cmd/compile/internal/ssa/gen/AMD64Ops.go15
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM.rules8
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64.rules4
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64Ops.go11
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARMOps.go16
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS.rules7
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS64.rules4
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPS64Ops.go11
-rw-r--r--src/cmd/compile/internal/ssa/gen/MIPSOps.go16
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64.rules4
-rw-r--r--src/cmd/compile/internal/ssa/gen/PPC64Ops.go11
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390X.rules4
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390XOps.go10
-rw-r--r--src/cmd/compile/internal/ssa/gen/genericOps.go8
-rw-r--r--src/cmd/compile/internal/ssa/op.go67
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go458
-rw-r--r--src/cmd/compile/internal/ssa/rewrite386.go130
-rw-r--r--src/cmd/compile/internal/ssa/rewriteAMD64.go144
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM.go130
-rw-r--r--src/cmd/compile/internal/ssa/rewriteARM64.go62
-rw-r--r--src/cmd/compile/internal/ssa/rewriteMIPS.go130
-rw-r--r--src/cmd/compile/internal/ssa/rewriteMIPS64.go62
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go62
-rw-r--r--src/cmd/compile/internal/ssa/rewriteS390X.go62
-rw-r--r--src/cmd/compile/internal/x86/ssa.go14
-rw-r--r--src/runtime/asm_386.s152
-rw-r--r--src/runtime/asm_amd64.s70
-rw-r--r--src/runtime/asm_amd64p32.s152
-rw-r--r--src/runtime/asm_arm.s152
-rw-r--r--src/runtime/asm_arm64.s70
-rw-r--r--src/runtime/asm_mips64x.s70
-rw-r--r--src/runtime/asm_mipsx.s152
-rw-r--r--src/runtime/asm_ppc64x.s70
-rw-r--r--src/runtime/asm_s390x.s70
-rw-r--r--src/runtime/error.go108
-rw-r--r--src/runtime/os_plan9.go12
-rw-r--r--src/runtime/panic.go163
-rw-r--r--src/runtime/panic32.go105
-rw-r--r--test/codegen/memcombine.go12
-rw-r--r--test/fixedbugs/issue15002.go12
-rw-r--r--test/fixedbugs/issue30116.go112
-rw-r--r--test/fixedbugs/issue30116.out558
-rw-r--r--test/fixedbugs/issue30116u.go112
-rw-r--r--test/fixedbugs/issue30116u.out340
59 files changed, 4464 insertions, 355 deletions
diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go
index b9fca18d4f..48b4f7d0b5 100644
--- a/src/cmd/compile/internal/amd64/ssa.go
+++ b/src/cmd/compile/internal/amd64/ssa.go
@@ -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:
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 320fe98707..8af6b1e6ed 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -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
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index 0ea3c191ac..75cf1d0bd9 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -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)
diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
index f32fcd675d..8244929f74 100644
--- a/src/cmd/compile/internal/gc/builtin.go
+++ b/src/cmd/compile/internal/gc/builtin.go
@@ -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[:]
}
diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
index 210881a6e9..a8a9b061ec 100644
--- a/src/cmd/compile/internal/gc/builtin/runtime.go
+++ b/src/cmd/compile/internal/gc/builtin/runtime.go
@@ -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)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 007585ef10..5f2c328909 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -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
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 3ccb59e105..031c3c072c 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -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
diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go
index 97a9b20537..d2ea0f46bb 100644
--- a/src/cmd/compile/internal/mips/ssa.go
+++ b/src/cmd/compile/internal/mips/ssa.go
@@ -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)
diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go
index 8a2d2b0f7a..d0c8b06900 100644
--- a/src/cmd/compile/internal/mips64/ssa.go
+++ b/src/cmd/compile/internal/mips64/ssa.go
@@ -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 {
diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index 3b37c797a9..4cccbecbb3 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -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
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index be48e1b23e..d90605bcbd 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -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:
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index fe02dd434a..4f6dbff208 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -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 {
diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules
index 2ee0b2a928..0f20b115f8 100644
--- a/src/cmd/compile/internal/ssa/gen/386.rules
+++ b/src/cmd/compile/internal/ssa/gen/386.rules
@@ -385,6 +385,14 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go
index fa3e7cd375..2851c4321c 100644
--- a/src/cmd/compile/internal/ssa/gen/386Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/386Ops.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 6b2d3f77cf..91bb22f3fe 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -225,7 +225,8 @@
(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)
@@ -561,6 +562,15 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
index a7880430ae..3ce302f514 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
index a3f36d3009..2934a91429 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
@@ -406,6 +406,14 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
index 3adb7895a2..35126835d2 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules
@@ -600,6 +600,10 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
index b6bf10315e..04c4b3f517 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
@@ -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{
diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go
index 86d7e5f8ec..d8bdfeb86e 100644
--- a/src/cmd/compile/internal/ssa/gen/ARMOps.go
+++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules
index bd218b494f..573f1d44c7 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules
@@ -410,6 +410,13 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
index 9c16c35438..52f9c4895d 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
@@ -412,6 +412,10 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
index 5235930ccc..f476c9b6fe 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
@@ -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{
diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
index 2605b60650..729cc05102 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
@@ -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{
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index 8dee5a1cba..b0a249a558 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -655,6 +655,10 @@
// 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.
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
index d6638b1ec7..2404d1afd6 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index 0aeea53561..2803f2ff50 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -419,6 +419,10 @@
// 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
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
index 19cb4be41c..4074243e98 100644
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
index 89e6961bd7..79169c34a1 100644
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/gen/genericOps.go
@@ -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.
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index a3cebce43b..b404533f6c 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -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")
+ }
+}
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index bf9fe7c960..c5e88e853e 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -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
@@ -5589,6 +5627,75 @@ var opcodeTable = [...]opInfo{
},
},
{
+ 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,
reg: regInfo{},
@@ -11114,6 +11221,75 @@ var opcodeTable = [...]opInfo{
},
},
{
+ 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,
reg: regInfo{},
@@ -14848,6 +15024,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,
reg: regInfo{},
@@ -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",
@@ -24011,6 +24391,39 @@ var opcodeTable = [...]opInfo{
},
},
{
+ 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,
reg: regInfo{},
@@ -26872,6 +27285,39 @@ 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: "FlagEQ",
argLen: 0,
reg: regInfo{},
@@ -29694,6 +30140,18 @@ var opcodeTable = [...]opInfo{
generic: true,
},
{
+ name: "PanicBounds",
+ auxType: auxInt64,
+ argLen: 3,
+ generic: true,
+ },
+ {
+ name: "PanicExtend",
+ auxType: auxInt64,
+ argLen: 4,
+ generic: true,
+ },
+ {
name: "ClosureCall",
auxType: auxInt64,
argLen: 3,
diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go
index e2d76ecb85..bb59feab0b 100644
--- a/src/cmd/compile/internal/ssa/rewrite386.go
+++ b/src/cmd/compile/internal/ssa/rewrite386.go
@@ -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:
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index 926c4a599c..708ab9df05 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -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
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index 37a34a9977..11c1bde8d1 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -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:
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index 89f01b4d84..499c5bbbd4 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -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
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go
index 145ee5aa63..d506d77ae3 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go
@@ -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:
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
index 4d1d817033..ca93e04c2c 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
@@ -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:
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 7daed08dab..d1e4482137 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -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
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index 3ee004be99..ddf648ded7 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -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
diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go
index 24ba9649be..b7b0f44529 100644
--- a/src/cmd/compile/internal/x86/ssa.go
+++ b/src/cmd/compile/internal/x86/ssa.go
@@ -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,
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index 51103928b3..8805dbf7d6 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -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)
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 85133bf2df..d3e5c54378 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -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)
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
index 7b57fc78d6..4d0d6c5650 100644
--- a/src/runtime/asm_amd64p32.s
+++ b/src/runtime/asm_amd64p32.s
@@ -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)
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 745aceaaff..c1e915b97c 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -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)
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index bbeb3df0c8..f7cf0d3544 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -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)
diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s
index ef45ab1378..257c13e9af 100644
--- a/src/runtime/asm_mips64x.s
+++ b/src/runtime/asm_mips64x.s
@@ -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)
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s
index 6ef4507ee1..9f38bbc71e 100644
--- a/src/runtime/asm_mipsx.s
+++ b/src/runtime/asm_mipsx.s
@@ -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)
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 9b5da3db99..9ac83e5590 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -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)
diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
index 566c3e9236..5b9e0cd481 100644
--- a/src/runtime/asm_s390x.s
+++ b/src/runtime/asm_s390x.s
@@ -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)
diff --git a/src/runtime/error.go b/src/runtime/error.go
index 9a2beaeb95..0085dfc824 100644
--- a/src/runtime/error.go
+++ b/src/runtime/error.go
@@ -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
}
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 5469114a2b..d7ea1ef841 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -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
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 59916dd5e5..918ab7682a 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -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
index 0000000000..b89ce9d563
--- /dev/null
+++ b/src/runtime/panic32.go
@@ -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)
diff --git a/test/codegen/memcombine.go b/test/codegen/memcombine.go
index 2b4422ebd2..72da47c7e9 100644
--- a/test/codegen/memcombine.go
+++ b/test/codegen/memcombine.go
@@ -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
}
diff --git a/test/fixedbugs/issue15002.go b/test/fixedbugs/issue15002.go
index a27fd92399..936105ed12 100644
--- a/test/fixedbugs/issue15002.go
+++ b/test/fixedbugs/issue15002.go
@@ -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
index 0000000000..452a6e3ae8
--- /dev/null
+++ b/test/fixedbugs/issue30116.go
@@ -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
index 0000000000..bde134d950
--- /dev/null
+++ b/test/fixedbugs/issue30116.out
@@ -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
index 0000000000..7c2aea2cd4
--- /dev/null
+++ b/test/fixedbugs/issue30116u.go
@@ -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
index 0000000000..ee19192aaa
--- /dev/null
+++ b/test/fixedbugs/issue30116u.out
@@ -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