Skip to content

Commit 9569381

Browse files
committed
cmd/compile: move riscv64 over to new bounds check strategy
Change-Id: Idd9eaf051aa57f7fef7049c12085926030c35d70 Reviewed-on: https://go-review.googlesource.com/c/go/+/682401 Reviewed-by: Mark Freeman <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Joel Sing <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent d7bd777 commit 9569381

File tree

6 files changed

+238
-159
lines changed

6 files changed

+238
-159
lines changed

src/cmd/compile/internal/riscv64/ssa.go

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"cmd/compile/internal/types"
1515
"cmd/internal/obj"
1616
"cmd/internal/obj/riscv"
17+
"internal/abi"
1718
)
1819

1920
// ssaRegToReg maps ssa register numbers to obj register numbers.
@@ -508,12 +509,91 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
508509
p.To.Name = obj.NAME_EXTERN
509510
// AuxInt encodes how many buffer entries we need.
510511
p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
511-
case ssa.OpRISCV64LoweredPanicBoundsA, ssa.OpRISCV64LoweredPanicBoundsB, ssa.OpRISCV64LoweredPanicBoundsC:
512-
p := s.Prog(obj.ACALL)
512+
513+
case ssa.OpRISCV64LoweredPanicBoundsRR, ssa.OpRISCV64LoweredPanicBoundsRC, ssa.OpRISCV64LoweredPanicBoundsCR, ssa.OpRISCV64LoweredPanicBoundsCC:
514+
// Compute the constant we put in the PCData entry for this call.
515+
code, signed := ssa.BoundsKind(v.AuxInt).Code()
516+
xIsReg := false
517+
yIsReg := false
518+
xVal := 0
519+
yVal := 0
520+
switch v.Op {
521+
case ssa.OpRISCV64LoweredPanicBoundsRR:
522+
xIsReg = true
523+
xVal = int(v.Args[0].Reg() - riscv.REG_X5)
524+
yIsReg = true
525+
yVal = int(v.Args[1].Reg() - riscv.REG_X5)
526+
case ssa.OpRISCV64LoweredPanicBoundsRC:
527+
xIsReg = true
528+
xVal = int(v.Args[0].Reg() - riscv.REG_X5)
529+
c := v.Aux.(ssa.PanicBoundsC).C
530+
if c >= 0 && c <= abi.BoundsMaxConst {
531+
yVal = int(c)
532+
} else {
533+
// Move constant to a register
534+
yIsReg = true
535+
if yVal == xVal {
536+
yVal = 1
537+
}
538+
p := s.Prog(riscv.AMOV)
539+
p.From.Type = obj.TYPE_CONST
540+
p.From.Offset = c
541+
p.To.Type = obj.TYPE_REG
542+
p.To.Reg = riscv.REG_X5 + int16(yVal)
543+
}
544+
case ssa.OpRISCV64LoweredPanicBoundsCR:
545+
yIsReg = true
546+
yVal := int(v.Args[0].Reg() - riscv.REG_X5)
547+
c := v.Aux.(ssa.PanicBoundsC).C
548+
if c >= 0 && c <= abi.BoundsMaxConst {
549+
xVal = int(c)
550+
} else {
551+
// Move constant to a register
552+
if xVal == yVal {
553+
xVal = 1
554+
}
555+
p := s.Prog(riscv.AMOV)
556+
p.From.Type = obj.TYPE_CONST
557+
p.From.Offset = c
558+
p.To.Type = obj.TYPE_REG
559+
p.To.Reg = riscv.REG_X5 + int16(xVal)
560+
}
561+
case ssa.OpRISCV64LoweredPanicBoundsCC:
562+
c := v.Aux.(ssa.PanicBoundsCC).Cx
563+
if c >= 0 && c <= abi.BoundsMaxConst {
564+
xVal = int(c)
565+
} else {
566+
// Move constant to a register
567+
xIsReg = true
568+
p := s.Prog(riscv.AMOV)
569+
p.From.Type = obj.TYPE_CONST
570+
p.From.Offset = c
571+
p.To.Type = obj.TYPE_REG
572+
p.To.Reg = riscv.REG_X5 + int16(xVal)
573+
}
574+
c = v.Aux.(ssa.PanicBoundsCC).Cy
575+
if c >= 0 && c <= abi.BoundsMaxConst {
576+
yVal = int(c)
577+
} else {
578+
// Move constant to a register
579+
yIsReg = true
580+
yVal = 1
581+
p := s.Prog(riscv.AMOV)
582+
p.From.Type = obj.TYPE_CONST
583+
p.From.Offset = c
584+
p.To.Type = obj.TYPE_REG
585+
p.To.Reg = riscv.REG_X5 + int16(yVal)
586+
}
587+
}
588+
c := abi.BoundsEncode(code, signed, xIsReg, yIsReg, xVal, yVal)
589+
590+
p := s.Prog(obj.APCDATA)
591+
p.From.SetConst(abi.PCDATA_PanicBounds)
592+
p.To.SetConst(int64(c))
593+
p = s.Prog(obj.ACALL)
513594
p.To.Type = obj.TYPE_MEM
514595
p.To.Name = obj.NAME_EXTERN
515-
p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
516-
s.UseArgs(16) // space used in callee args area by assembly stubs
596+
p.To.Sym = ir.Syms.PanicBounds
517597

518598
case ssa.OpRISCV64LoweredAtomicLoad8:
519599
s.Prog(riscv.AFENCE)

src/cmd/compile/internal/ssa/_gen/RISCV64.rules

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,11 @@
407407
// Publication barrier as intrinsic
408408
(PubBarrier ...) => (LoweredPubBarrier ...)
409409

410-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
411-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
412-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
410+
(PanicBounds ...) => (LoweredPanicBoundsRR ...)
411+
(LoweredPanicBoundsRR [kind] x (MOVDconst [c]) mem) => (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:c}} mem)
412+
(LoweredPanicBoundsRR [kind] (MOVDconst [c]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:c}} y mem)
413+
(LoweredPanicBoundsRC [kind] {p} (MOVDconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:c, Cy:p.C}} mem)
414+
(LoweredPanicBoundsCR [kind] {p} (MOVDconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:p.C, Cy:c}} mem)
413415

414416
// Small moves
415417
(Move [0] _ _ mem) => mem

src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func riscv64RegName(r int) string {
4949

5050
func init() {
5151
var regNamesRISCV64 []string
52-
var gpMask, fpMask, gpgMask, gpspMask, gpspsbMask, gpspsbgMask regMask
52+
var gpMask, fpMask, gpgMask, gpspMask, gpspsbMask, gpspsbgMask, first16Mask regMask
5353
regNamed := make(map[string]regMask)
5454

5555
// Build the list of register names, creating an appropriately indexed
@@ -93,6 +93,9 @@ func init() {
9393
gpspMask |= mask
9494
gpspsbMask |= mask
9595
gpspsbgMask |= mask
96+
if r >= 5 && r < 5+16 {
97+
first16Mask |= mask
98+
}
9699
}
97100
}
98101

@@ -429,12 +432,15 @@ func init() {
429432
// Do data barrier. arg0=memorys
430433
{name: "LoweredPubBarrier", argLength: 1, asm: "FENCE", hasSideEffects: true},
431434

432-
// There are three of these functions so that they can have three different register inputs.
433-
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
434-
// default registers to match so we don't need to copy registers around unnecessarily.
435-
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X7"], regNamed["X28"]}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
436-
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X6"], regNamed["X7"]}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
437-
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X5"], regNamed["X6"]}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
435+
// LoweredPanicBoundsRR takes x and y, two values that caused a bounds check to fail.
436+
// the RC and CR versions are used when one of the arguments is a constant. CC is used
437+
// when both are constant (normally both 0, as prove derives the fact that a [0] bounds
438+
// failure means the length must have also been 0).
439+
// AuxInt contains a report code (see PanicBounds in genericOps.go).
440+
{name: "LoweredPanicBoundsRR", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{first16Mask, first16Mask}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
441+
{name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16Mask}}, typ: "Mem", call: true}, // arg0=x, arg1=mem, returns memory.
442+
{name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16Mask}}, typ: "Mem", call: true}, // arg0=y, arg1=mem, returns memory.
443+
{name: "LoweredPanicBoundsCC", argLength: 1, aux: "PanicBoundsCC", reg: regInfo{}, typ: "Mem", call: true}, // arg0=mem, returns memory.
438444

439445
// F extension.
440446
{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true, typ: "Float32"}, // arg0 + arg1

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 22 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)