1
0
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:
Archana R 2022-11-11 06:10:59 -06:00 committed by Lynn Boger
parent def0be5e34
commit a432d89137
8 changed files with 1159 additions and 759 deletions

View File

@ -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

View File

@ -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))

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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
}