mirror of
https://github.com/golang/go
synced 2024-09-28 19:24:29 -06:00
cmd/compile: add rules to emit SETBC/R instructions on power10
This CL adds rules that replaces instances of ISEL that produce a boolean result based on a condition register by SETBC/SETBCR operations. On Power10 these are convereted to SETBC/SETBCR instructions that use one register instead of 3 registers conventionally used by ISEL and hence reduces register pressure. On loops written specifically to exercise such instances of ISEL extensively, a performance improvement of 2.5% is seen on Power10. Also added verification tests to verify correct generation of SETBC/SETBCR instructions on Power10. Change-Id: Ib719897f09d893de40324440a43052dca026e8fa Reviewed-on: https://go-review.googlesource.com/c/go/+/449795 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Archana Ravindar <aravind5@in.ibm.com> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
def0be5e34
commit
a432d89137
@ -993,6 +993,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = v.AuxInt & 3
|
||||
|
||||
case ssa.OpPPC64SETBC, ssa.OpPPC64SETBCR:
|
||||
p := s.Prog(v.Op.Asm())
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = v.Reg()
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = int16(ppc64.REG_CR0LT + v.AuxInt)
|
||||
|
||||
case ssa.OpPPC64LoweredQuadZero, ssa.OpPPC64LoweredQuadZeroShort:
|
||||
// The LoweredQuad code generation
|
||||
// generates STXV instructions on
|
||||
|
@ -409,10 +409,14 @@
|
||||
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(OR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (ORCC x y)) yes no)
|
||||
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(XOR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (XORCC x y)) yes no)
|
||||
|
||||
(CondSelect x y (SETBC [a] cmp)) => (ISEL [a] x y cmp)
|
||||
(CondSelect x y (SETBCR [a] cmp)) => (ISEL [a+4] x y cmp)
|
||||
// Only lower after bool is lowered. It should always lower. This helps ensure the folding below happens reliably.
|
||||
(CondSelect x y bool) && flagArg(bool) == nil => (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [1] bool)))
|
||||
// Fold any CR -> GPR -> CR transfers when applying the above rule.
|
||||
(ISEL [6] x y (Select1 (ANDCCconst [1] (ISELB [c] one cmp)))) => (ISEL [c] x y cmp)
|
||||
(ISEL [6] x y (Select1 (ANDCCconst [1] (SETBC [c] cmp)))) => (ISEL [c] x y cmp)
|
||||
(ISEL [6] x y ((CMP|CMPW)const [0] (SETBC [c] cmp))) => (ISEL [c] x y cmp)
|
||||
(ISEL [6] x y ((CMP|CMPW)const [0] (SETBCR [c] cmp))) => (ISEL [c+4] x y cmp)
|
||||
|
||||
// Lowering loads
|
||||
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
|
||||
@ -862,33 +866,43 @@
|
||||
// Canonicalize the order of arguments to comparisons - helps with CSE.
|
||||
((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
|
||||
|
||||
// SETBC auxInt values 0=LT 1=GT 2=EQ Crbit==1 ? 1 : 0
|
||||
// SETBCR auxInt values 0=LT 1=GT 2=EQ Crbit==1 ? 0 : 1
|
||||
(Equal cmp) => (SETBC [2] cmp)
|
||||
(NotEqual cmp) => (SETBCR [2] cmp)
|
||||
(LessThan cmp) => (SETBC [0] cmp)
|
||||
(FLessThan cmp) => (SETBC [0] cmp)
|
||||
(FLessEqual cmp) => (OR (SETBC [2] cmp) (SETBC [0] cmp))
|
||||
(GreaterEqual cmp) => (SETBCR [0] cmp)
|
||||
(GreaterThan cmp) => (SETBC [1] cmp)
|
||||
(FGreaterEqual cmp) => (OR (SETBC [2] cmp) (SETBC [1] cmp))
|
||||
(FGreaterThan cmp) => (SETBC [1] cmp)
|
||||
(LessEqual cmp) => (SETBCR [1] cmp)
|
||||
|
||||
(SETBC [0] (FlagLT)) => (MOVDconst [1])
|
||||
(SETBC [0] (Flag(GT|EQ))) => (MOVDconst [0])
|
||||
(SETBC [1] (FlagGT)) => (MOVDconst [1])
|
||||
(SETBC [1] (Flag(LT|EQ))) => (MOVDconst [0])
|
||||
(SETBC [2] (FlagEQ)) => (MOVDconst [1])
|
||||
(SETBC [2] (Flag(LT|GT))) => (MOVDconst [0])
|
||||
|
||||
(SETBCR [0] (FlagLT)) => (MOVDconst [0])
|
||||
(SETBCR [0] (Flag(GT|EQ))) => (MOVDconst [1])
|
||||
(SETBCR [1] (FlagGT)) => (MOVDconst [0])
|
||||
(SETBCR [1] (Flag(LT|EQ))) => (MOVDconst [1])
|
||||
(SETBCR [2] (FlagEQ)) => (MOVDconst [0])
|
||||
(SETBCR [2] (Flag(LT|GT))) => (MOVDconst [1])
|
||||
|
||||
(SETBC [0] (InvertFlags bool)) => (SETBC [1] bool)
|
||||
(SETBC [1] (InvertFlags bool)) => (SETBC [0] bool)
|
||||
(SETBC [2] (InvertFlags bool)) => (SETBC [2] bool)
|
||||
|
||||
(SETBCR [0] (InvertFlags bool)) => (SETBCR [1] bool)
|
||||
(SETBCR [1] (InvertFlags bool)) => (SETBCR [0] bool)
|
||||
(SETBCR [2] (InvertFlags bool)) => (SETBCR [2] bool)
|
||||
|
||||
// ISEL auxInt values 0=LT 1=GT 2=EQ arg2 ? arg0 : arg1
|
||||
// ISEL auxInt values 4=GE 5=LE 6=NE !arg2 ? arg1 : arg0
|
||||
// ISELB special case where arg0, arg1 values are 0, 1
|
||||
|
||||
(Equal cmp) => (ISELB [2] (MOVDconst [1]) cmp)
|
||||
(NotEqual cmp) => (ISELB [6] (MOVDconst [1]) cmp)
|
||||
(LessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
|
||||
(FLessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
|
||||
(FLessEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [0] (MOVDconst [1]) cmp) cmp)
|
||||
(GreaterEqual cmp) => (ISELB [4] (MOVDconst [1]) cmp)
|
||||
(GreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
|
||||
(FGreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
|
||||
(FGreaterEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [1] (MOVDconst [1]) cmp) cmp)
|
||||
(LessEqual cmp) => (ISELB [5] (MOVDconst [1]) cmp)
|
||||
|
||||
(ISELB [0] _ (FlagLT)) => (MOVDconst [1])
|
||||
(ISELB [0] _ (Flag(GT|EQ))) => (MOVDconst [0])
|
||||
(ISELB [1] _ (FlagGT)) => (MOVDconst [1])
|
||||
(ISELB [1] _ (Flag(LT|EQ))) => (MOVDconst [0])
|
||||
(ISELB [2] _ (FlagEQ)) => (MOVDconst [1])
|
||||
(ISELB [2] _ (Flag(LT|GT))) => (MOVDconst [0])
|
||||
(ISELB [4] _ (FlagLT)) => (MOVDconst [0])
|
||||
(ISELB [4] _ (Flag(GT|EQ))) => (MOVDconst [1])
|
||||
(ISELB [5] _ (FlagGT)) => (MOVDconst [0])
|
||||
(ISELB [5] _ (Flag(LT|EQ))) => (MOVDconst [1])
|
||||
(ISELB [6] _ (FlagEQ)) => (MOVDconst [0])
|
||||
(ISELB [6] _ (Flag(LT|GT))) => (MOVDconst [1])
|
||||
|
||||
(ISEL [2] x _ (FlagEQ)) => x
|
||||
(ISEL [2] _ y (Flag(LT|GT))) => y
|
||||
@ -910,31 +924,30 @@
|
||||
|
||||
(ISEL [2] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [2] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
(ISEL [6] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
(ISELB [2] x ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (XORconst [1] (Select0 <typ.UInt64> (ANDCCconst [1] z )))
|
||||
(ISELB [6] x ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (Select0 <typ.UInt64> (ANDCCconst [1] z ))
|
||||
(SETBC [n] (InvertFlags bool)) => (SETBCR [n] bool)
|
||||
(SETBCR [n] (InvertFlags bool)) => (SETBC [n] bool)
|
||||
|
||||
(ISELB [2] x (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (ISELB [2] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
(ISELB [6] x (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (ISELB [6] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
|
||||
// Only CMPconst for these in case AND|OR|XOR result is > 32 bits
|
||||
(ISELB [2] x (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (ANDCC y z )))
|
||||
(ISELB [6] x (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (ANDCC y z )))
|
||||
|
||||
(ISELB [2] x (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (ORCC y z )))
|
||||
(ISELB [6] x (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (ORCC y z )))
|
||||
|
||||
(ISELB [2] x (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (XORCC y z )))
|
||||
(ISELB [6] x (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (XORCC y z )))
|
||||
|
||||
(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 0 => (ISELB [n+1] (MOVDconst [1]) bool)
|
||||
(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 1 => (ISELB [n-1] (MOVDconst [1]) bool)
|
||||
(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 2 => (ISELB [n] (MOVDconst [1]) bool)
|
||||
(ISEL [n] x y (InvertFlags bool)) && n%4 == 0 => (ISEL [n+1] x y bool)
|
||||
(ISEL [n] x y (InvertFlags bool)) && n%4 == 1 => (ISEL [n-1] x y bool)
|
||||
(ISEL [n] x y (InvertFlags bool)) && n%4 == 2 => (ISEL [n] x y bool)
|
||||
(XORconst [1] (ISELB [6] (MOVDconst [1]) cmp)) => (ISELB [2] (MOVDconst [1]) cmp)
|
||||
(XORconst [1] (ISELB [5] (MOVDconst [1]) cmp)) => (ISELB [1] (MOVDconst [1]) cmp)
|
||||
(XORconst [1] (ISELB [4] (MOVDconst [1]) cmp)) => (ISELB [0] (MOVDconst [1]) cmp)
|
||||
(XORconst [1] (SETBCR [n] cmp)) => (SETBC [n] cmp)
|
||||
(XORconst [1] (SETBC [n] cmp)) => (SETBCR [n] cmp)
|
||||
|
||||
(SETBC [2] ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (XORconst [1] (Select0 <typ.UInt64> (ANDCCconst [1] z )))
|
||||
(SETBCR [2] ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (Select0 <typ.UInt64> (ANDCCconst [1] z ))
|
||||
|
||||
(SETBC [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (SETBC [2] (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
(SETBCR [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (SETBCR [2] (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
|
||||
|
||||
// Only CMPconst for these in case AND|OR|XOR result is > 32 bits
|
||||
(SETBC [2] (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (SETBC [2] (Select1 <types.TypeFlags> (ANDCC y z )))
|
||||
(SETBCR [2] (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (SETBCR [2] (Select1 <types.TypeFlags> (ANDCC y z )))
|
||||
|
||||
(SETBC [2] (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (SETBC [2] (Select1 <types.TypeFlags> (ORCC y z )))
|
||||
(SETBCR [2] (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (SETBCR [2] (Select1 <types.TypeFlags> (ORCC y z )))
|
||||
|
||||
(SETBC [2] (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (SETBC [2] (Select1 <types.TypeFlags> (XORCC y z )))
|
||||
(SETBCR [2] (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (SETBCR [2] (Select1 <types.TypeFlags> (XORCC y z )))
|
||||
|
||||
// A particular pattern seen in cgo code:
|
||||
(AND (MOVDconst [c]) x:(MOVBZload _ _)) => (Select0 (ANDCCconst [c&0xFF] x))
|
||||
|
@ -416,6 +416,11 @@ func init() {
|
||||
{name: "ISELB", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32", typ: "Int32"},
|
||||
{name: "ISELZ", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32"},
|
||||
|
||||
// SETBC auxInt values 0=LT 1=GT 2=EQ (CRbit=1)? 1 : 0
|
||||
{name: "SETBC", argLength: 1, reg: crgp, asm: "SETBC", aux: "Int32", typ: "Int32"},
|
||||
// SETBCR auxInt values 0=LT 1=GT 2=EQ (CRbit=1)? 0 : 1
|
||||
{name: "SETBCR", argLength: 1, reg: crgp, asm: "SETBCR", aux: "Int32", typ: "Int32"},
|
||||
|
||||
// pseudo-ops
|
||||
{name: "Equal", argLength: 1, reg: crgp}, // bool, true flags encode x==y false otherwise.
|
||||
{name: "NotEqual", argLength: 1, reg: crgp}, // bool, true flags encode x!=y false otherwise.
|
||||
|
@ -8,3 +8,12 @@
|
||||
(ISEL [a] x (MOVDconst [0]) z) => (ISELZ [a] x z)
|
||||
// Simplify ISEL $0 y z into ISELZ by inverting comparison and reversing arguments.
|
||||
(ISEL [a] (MOVDconst [0]) y z) => (ISELZ [a^0x4] y z)
|
||||
|
||||
// SETBC, SETBCR is supported on ISA 3.1(Power10) and newer, use ISELZ for
|
||||
// older targets
|
||||
(SETBC [2] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [2] (MOVDconst [1]) cmp)
|
||||
(SETBCR [2] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [6] (MOVDconst [1]) cmp)
|
||||
(SETBC [0] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [0] (MOVDconst [1]) cmp)
|
||||
(SETBCR [0] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [4] (MOVDconst [1]) cmp)
|
||||
(SETBC [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [1] (MOVDconst [1]) cmp)
|
||||
(SETBCR [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [5] (MOVDconst [1]) cmp)
|
||||
|
@ -2244,6 +2244,8 @@ const (
|
||||
OpPPC64ISEL
|
||||
OpPPC64ISELB
|
||||
OpPPC64ISELZ
|
||||
OpPPC64SETBC
|
||||
OpPPC64SETBCR
|
||||
OpPPC64Equal
|
||||
OpPPC64NotEqual
|
||||
OpPPC64LessThan
|
||||
@ -30130,6 +30132,28 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SETBC",
|
||||
auxType: auxInt32,
|
||||
argLen: 1,
|
||||
asm: ppc64.ASETBC,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SETBCR",
|
||||
auxType: auxInt32,
|
||||
argLen: 1,
|
||||
asm: ppc64.ASETBCR,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Equal",
|
||||
argLen: 1,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,10 +2,16 @@
|
||||
|
||||
package ssa
|
||||
|
||||
import "internal/buildcfg"
|
||||
|
||||
func rewriteValuePPC64latelower(v *Value) bool {
|
||||
switch v.Op {
|
||||
case OpPPC64ISEL:
|
||||
return rewriteValuePPC64latelower_OpPPC64ISEL(v)
|
||||
case OpPPC64SETBC:
|
||||
return rewriteValuePPC64latelower_OpPPC64SETBC(v)
|
||||
case OpPPC64SETBCR:
|
||||
return rewriteValuePPC64latelower_OpPPC64SETBCR(v)
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -43,6 +49,126 @@ func rewriteValuePPC64latelower_OpPPC64ISEL(v *Value) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64latelower_OpPPC64SETBC(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (SETBC [2] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [2] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 2 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(2)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
// match: (SETBC [0] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [0] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(0)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
// match: (SETBC [1] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [1] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 1 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(1)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64latelower_OpPPC64SETBCR(v *Value) bool {
|
||||
v_0 := v.Args[0]
|
||||
b := v.Block
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (SETBCR [2] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [6] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 2 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(6)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
// match: (SETBCR [0] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [4] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 0 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(4)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
// match: (SETBCR [1] cmp)
|
||||
// cond: buildcfg.GOPPC64 <= 9
|
||||
// result: (ISELZ [5] (MOVDconst [1]) cmp)
|
||||
for {
|
||||
if auxIntToInt32(v.AuxInt) != 1 {
|
||||
break
|
||||
}
|
||||
cmp := v_0
|
||||
if !(buildcfg.GOPPC64 <= 9) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64ISELZ)
|
||||
v.AuxInt = int32ToAuxInt(5)
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
|
||||
v0.AuxInt = int64ToAuxInt(1)
|
||||
v.AddArg2(v0, cmp)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteBlockPPC64latelower(b *Block) bool {
|
||||
return false
|
||||
}
|
||||
|
@ -55,3 +55,159 @@ func convertEqBool64(x uint64) bool {
|
||||
// ppc64x:"ANDCC","XOR",-"CMP",-"ISEL"
|
||||
return x&1 == 0
|
||||
}
|
||||
|
||||
func TestSetEq64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
|
||||
b := x == y
|
||||
return b
|
||||
}
|
||||
func TestSetNeq64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
b := x != y
|
||||
return b
|
||||
}
|
||||
func TestSetLt64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
|
||||
b := x < y
|
||||
return b
|
||||
}
|
||||
func TestSetLe64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
|
||||
b := x <= y
|
||||
return b
|
||||
}
|
||||
func TestSetGt64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := x > y
|
||||
return b
|
||||
}
|
||||
func TestSetGe64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
|
||||
b := x >= y
|
||||
return b
|
||||
}
|
||||
func TestSetLtFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := x < y
|
||||
return b
|
||||
}
|
||||
func TestSetLeFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
|
||||
// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
|
||||
// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
|
||||
b := x <= y
|
||||
return b
|
||||
}
|
||||
func TestSetGtFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := x > y
|
||||
return b
|
||||
}
|
||||
func TestSetGeFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
|
||||
// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
|
||||
// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
|
||||
b := x >= y
|
||||
return b
|
||||
}
|
||||
func TestSetInvEq64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
b := !(x == y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvNeq64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
|
||||
b := !(x != y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvLt64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
|
||||
b := !(x < y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvLe64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := !(x <= y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvGt64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
|
||||
b := !(x > y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvGe64(x uint64, y uint64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
|
||||
// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
|
||||
// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
|
||||
b := !(x >= y)
|
||||
return b
|
||||
}
|
||||
|
||||
func TestSetInvEqFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0EQ"
|
||||
b := !(x == y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvNeqFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0EQ"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0EQ"
|
||||
b := !(x != y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvLtFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
|
||||
b := !(x < y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvLeFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := !(x <= y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvGtFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
|
||||
b := !(x > y)
|
||||
return b
|
||||
}
|
||||
func TestSetInvGeFp64(x float64, y float64) bool {
|
||||
// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
|
||||
// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
|
||||
b := !(x >= y)
|
||||
return b
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user