Skip to content

Commit 8330fb4

Browse files
committed
cmd/compile: move mips32 over to new bounds check strategy
Change-Id: Ied54ea7bf68c4c943c621ca059aca1048903c041 Reviewed-on: https://go-review.googlesource.com/c/go/+/682497 Reviewed-by: Keith Randall <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Julian Zhu <[email protected]> Reviewed-by: Mark Freeman <[email protected]>
1 parent 9f9d7b5 commit 8330fb4

File tree

6 files changed

+411
-339
lines changed

6 files changed

+411
-339
lines changed

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

Lines changed: 160 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"cmd/compile/internal/types"
1616
"cmd/internal/obj"
1717
"cmd/internal/obj/mips"
18+
"internal/abi"
1819
)
1920

2021
// isFPreg reports whether r is an FP register.
@@ -486,18 +487,167 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
486487
p.To.Name = obj.NAME_EXTERN
487488
// AuxInt encodes how many buffer entries we need.
488489
p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
489-
case ssa.OpMIPSLoweredPanicBoundsA, ssa.OpMIPSLoweredPanicBoundsB, ssa.OpMIPSLoweredPanicBoundsC:
490-
p := s.Prog(obj.ACALL)
491-
p.To.Type = obj.TYPE_MEM
492-
p.To.Name = obj.NAME_EXTERN
493-
p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
494-
s.UseArgs(8) // space used in callee args area by assembly stubs
495-
case ssa.OpMIPSLoweredPanicExtendA, ssa.OpMIPSLoweredPanicExtendB, ssa.OpMIPSLoweredPanicExtendC:
496-
p := s.Prog(obj.ACALL)
490+
491+
case ssa.OpMIPSLoweredPanicBoundsRR, ssa.OpMIPSLoweredPanicBoundsRC, ssa.OpMIPSLoweredPanicBoundsCR, ssa.OpMIPSLoweredPanicBoundsCC,
492+
ssa.OpMIPSLoweredPanicExtendRR, ssa.OpMIPSLoweredPanicExtendRC:
493+
// Compute the constant we put in the PCData entry for this call.
494+
code, signed := ssa.BoundsKind(v.AuxInt).Code()
495+
xIsReg := false
496+
yIsReg := false
497+
xVal := 0
498+
yVal := 0
499+
extend := false
500+
switch v.Op {
501+
case ssa.OpMIPSLoweredPanicBoundsRR:
502+
xIsReg = true
503+
xVal = int(v.Args[0].Reg() - mips.REG_R1)
504+
yIsReg = true
505+
yVal = int(v.Args[1].Reg() - mips.REG_R1)
506+
case ssa.OpMIPSLoweredPanicExtendRR:
507+
extend = true
508+
xIsReg = true
509+
hi := int(v.Args[0].Reg() - mips.REG_R1)
510+
lo := int(v.Args[1].Reg() - mips.REG_R1)
511+
xVal = hi<<2 + lo // encode 2 register numbers
512+
yIsReg = true
513+
yVal = int(v.Args[2].Reg() - mips.REG_R1)
514+
case ssa.OpMIPSLoweredPanicBoundsRC:
515+
xIsReg = true
516+
xVal = int(v.Args[0].Reg() - mips.REG_R1)
517+
c := v.Aux.(ssa.PanicBoundsC).C
518+
if c >= 0 && c <= abi.BoundsMaxConst {
519+
yVal = int(c)
520+
} else {
521+
// Move constant to a register
522+
yIsReg = true
523+
if yVal == xVal {
524+
yVal = 1
525+
}
526+
p := s.Prog(mips.AMOVW)
527+
p.From.Type = obj.TYPE_CONST
528+
p.From.Offset = c
529+
p.To.Type = obj.TYPE_REG
530+
p.To.Reg = mips.REG_R1 + int16(yVal)
531+
}
532+
case ssa.OpMIPSLoweredPanicExtendRC:
533+
extend = true
534+
xIsReg = true
535+
hi := int(v.Args[0].Reg() - mips.REG_R1)
536+
lo := int(v.Args[1].Reg() - mips.REG_R1)
537+
xVal = hi<<2 + lo // encode 2 register numbers
538+
c := v.Aux.(ssa.PanicBoundsC).C
539+
if c >= 0 && c <= abi.BoundsMaxConst {
540+
yVal = int(c)
541+
} else {
542+
// Move constant to a register
543+
for yVal == hi || yVal == lo {
544+
yVal++
545+
}
546+
p := s.Prog(mips.AMOVW)
547+
p.From.Type = obj.TYPE_CONST
548+
p.From.Offset = c
549+
p.To.Type = obj.TYPE_REG
550+
p.To.Reg = mips.REG_R1 + int16(yVal)
551+
}
552+
case ssa.OpMIPSLoweredPanicBoundsCR:
553+
yIsReg = true
554+
yVal := int(v.Args[0].Reg() - mips.REG_R1)
555+
c := v.Aux.(ssa.PanicBoundsC).C
556+
if c >= 0 && c <= abi.BoundsMaxConst {
557+
xVal = int(c)
558+
} else if signed && int64(int32(c)) == c || !signed && int64(uint32(c)) == c {
559+
// Move constant to a register
560+
xIsReg = true
561+
if xVal == yVal {
562+
xVal = 1
563+
}
564+
p := s.Prog(mips.AMOVW)
565+
p.From.Type = obj.TYPE_CONST
566+
p.From.Offset = c
567+
p.To.Type = obj.TYPE_REG
568+
p.To.Reg = mips.REG_R1 + int16(xVal)
569+
} else {
570+
// Move constant to two registers
571+
extend = true
572+
xIsReg = true
573+
hi := 0
574+
lo := 1
575+
if hi == yVal {
576+
hi = 2
577+
}
578+
if lo == yVal {
579+
lo = 2
580+
}
581+
xVal = hi<<2 + lo
582+
p := s.Prog(mips.AMOVW)
583+
p.From.Type = obj.TYPE_CONST
584+
p.From.Offset = c >> 32
585+
p.To.Type = obj.TYPE_REG
586+
p.To.Reg = mips.REG_R1 + int16(hi)
587+
p = s.Prog(mips.AMOVW)
588+
p.From.Type = obj.TYPE_CONST
589+
p.From.Offset = int64(int32(c))
590+
p.To.Type = obj.TYPE_REG
591+
p.To.Reg = mips.REG_R1 + int16(lo)
592+
}
593+
case ssa.OpMIPSLoweredPanicBoundsCC:
594+
c := v.Aux.(ssa.PanicBoundsCC).Cx
595+
if c >= 0 && c <= abi.BoundsMaxConst {
596+
xVal = int(c)
597+
} else if signed && int64(int32(c)) == c || !signed && int64(uint32(c)) == c {
598+
// Move constant to a register
599+
xIsReg = true
600+
p := s.Prog(mips.AMOVW)
601+
p.From.Type = obj.TYPE_CONST
602+
p.From.Offset = c
603+
p.To.Type = obj.TYPE_REG
604+
p.To.Reg = mips.REG_R1 + int16(xVal)
605+
} else {
606+
// Move constant to two registers
607+
extend = true
608+
xIsReg = true
609+
hi := 0
610+
lo := 1
611+
xVal = hi<<2 + lo
612+
p := s.Prog(mips.AMOVW)
613+
p.From.Type = obj.TYPE_CONST
614+
p.From.Offset = c >> 32
615+
p.To.Type = obj.TYPE_REG
616+
p.To.Reg = mips.REG_R1 + int16(hi)
617+
p = s.Prog(mips.AMOVW)
618+
p.From.Type = obj.TYPE_CONST
619+
p.From.Offset = int64(int32(c))
620+
p.To.Type = obj.TYPE_REG
621+
p.To.Reg = mips.REG_R1 + int16(lo)
622+
}
623+
c = v.Aux.(ssa.PanicBoundsCC).Cy
624+
if c >= 0 && c <= abi.BoundsMaxConst {
625+
yVal = int(c)
626+
} else {
627+
// Move constant to a register
628+
yIsReg = true
629+
yVal = 2
630+
p := s.Prog(mips.AMOVW)
631+
p.From.Type = obj.TYPE_CONST
632+
p.From.Offset = c
633+
p.To.Type = obj.TYPE_REG
634+
p.To.Reg = mips.REG_R1 + int16(yVal)
635+
}
636+
}
637+
c := abi.BoundsEncode(code, signed, xIsReg, yIsReg, xVal, yVal)
638+
639+
p := s.Prog(obj.APCDATA)
640+
p.From.SetConst(abi.PCDATA_PanicBounds)
641+
p.To.SetConst(int64(c))
642+
p = s.Prog(obj.ACALL)
497643
p.To.Type = obj.TYPE_MEM
498644
p.To.Name = obj.NAME_EXTERN
499-
p.To.Sym = ssagen.ExtendCheckFunc[v.AuxInt]
500-
s.UseArgs(12) // space used in callee args area by assembly stubs
645+
if extend {
646+
p.To.Sym = ir.Syms.PanicExtend
647+
} else {
648+
p.To.Sym = ir.Syms.PanicBounds
649+
}
650+
501651
case ssa.OpMIPSLoweredAtomicLoad8,
502652
ssa.OpMIPSLoweredAtomicLoad32:
503653
s.Prog(mips.ASYNC)

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,13 +423,17 @@
423423
// Publication barrier as intrinsic
424424
(PubBarrier ...) => (LoweredPubBarrier ...)
425425

426-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
427-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
428-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
429426

430-
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
431-
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
432-
(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
427+
(PanicBounds ...) => (LoweredPanicBoundsRR ...)
428+
(PanicExtend ...) => (LoweredPanicExtendRR ...)
429+
430+
(LoweredPanicBoundsRR [kind] x (MOVWconst [c]) mem) => (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:int64(c)}} mem)
431+
(LoweredPanicBoundsRR [kind] (MOVWconst [c]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(c)}} y mem)
432+
(LoweredPanicBoundsRC [kind] {p} (MOVWconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(c), Cy:p.C}} mem)
433+
434+
(LoweredPanicExtendRR [kind] hi lo (MOVWconst [c]) mem) => (LoweredPanicExtendRC [kind] hi lo {PanicBoundsC{C:int64(c)}} mem)
435+
(LoweredPanicExtendRR [kind] (MOVWconst [hi]) (MOVWconst [lo]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:int64(hi)<<32 + int64(uint32(lo))}} y mem)
436+
(LoweredPanicExtendRC [kind] {p} (MOVWconst [hi]) (MOVWconst [lo]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:int64(hi)<<32+int64(uint32(lo)), Cy:p.C}} mem)
433437

434438
// Optimizations
435439

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,8 @@ func init() {
120120
lo = buildReg("LO")
121121
hi = buildReg("HI")
122122
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
123-
r1 = buildReg("R1")
124-
r2 = buildReg("R2")
125-
r3 = buildReg("R3")
126-
r4 = buildReg("R4")
127-
r5 = buildReg("R5")
123+
first16 = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16")
124+
first4 = buildReg("R1 R2 R3 R4")
128125
)
129126
// Common regInfo
130127
var (
@@ -411,16 +408,19 @@ func init() {
411408
// Do data barrier. arg0=memorys
412409
{name: "LoweredPubBarrier", argLength: 1, asm: "SYNC", hasSideEffects: true},
413410

414-
// There are three of these functions so that they can have three different register inputs.
415-
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
416-
// default registers to match so we don't need to copy registers around unnecessarily.
417-
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
418-
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
419-
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
420-
// Extend ops are the same as Bounds ops except the indexes are 64-bit.
421-
{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r3, r4}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
422-
{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
423-
{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
411+
// LoweredPanicBoundsRR takes x and y, two values that caused a bounds check to fail.
412+
// the RC and CR versions are used when one of the arguments is a constant. CC is used
413+
// when both are constant (normally both 0, as prove derives the fact that a [0] bounds
414+
// failure means the length must have also been 0).
415+
// AuxInt contains a report code (see PanicBounds in genericOps.go).
416+
{name: "LoweredPanicBoundsRR", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{first16, first16}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
417+
{name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, typ: "Mem", call: true}, // arg0=x, arg1=mem, returns memory.
418+
{name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first16}}, typ: "Mem", call: true}, // arg0=y, arg1=mem, returns memory.
419+
{name: "LoweredPanicBoundsCC", argLength: 1, aux: "PanicBoundsCC", reg: regInfo{}, typ: "Mem", call: true}, // arg0=mem, returns memory.
420+
421+
// Same as above, but the x value is 64 bits.
422+
{name: "LoweredPanicExtendRR", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{first4, first4, first16}}, typ: "Mem", call: true}, // arg0=x_hi, arg1=x_lo, arg2=y, arg3=mem, returns memory.
423+
{name: "LoweredPanicExtendRC", argLength: 3, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first4, first4}}, typ: "Mem", call: true}, // arg0=x_hi, arg1=x_lo, arg2=mem, returns memory.
424424
}
425425

426426
blocks := []blockData{

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

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

0 commit comments

Comments
 (0)