(Geq32U x y) -> (GreaterEqualU (CMPW x y))
(Geq64U x y) -> (GreaterEqualU (CMP x y))
+// Optimize comparision between a floating-point value and 0.0 with "FCMP $(0.0), Fn"
+(FCMPS x (FMOVSconst [0])) -> (FCMPS0 x)
+(FCMPS (FMOVSconst [0]) x) -> (InvertFlags (FCMPS0 x))
+(FCMPD x (FMOVDconst [0])) -> (FCMPD0 x)
+(FCMPD (FMOVDconst [0]) x) -> (InvertFlags (FCMPD0 x))
+
// CSEL needs a flag-generating argument. Synthesize a CMPW if necessary.
(CondSelect x y bool) && flagArg(bool) != nil -> (CSEL {bool.Op} x y flagArg(bool))
(CondSelect x y bool) && flagArg(bool) == nil -> (CSEL {OpARM64NotEqual} x y (CMPWconst [0] bool))
(LessEqualU (InvertFlags x)) -> (GreaterEqualU x)
(GreaterEqual (InvertFlags x)) -> (LessEqual x)
(GreaterEqualU (InvertFlags x)) -> (LessEqualU x)
+(LessThanF (InvertFlags x)) -> (GreaterThanF x)
+(LessEqualF (InvertFlags x)) -> (GreaterEqualF x)
+(GreaterThanF (InvertFlags x)) -> (LessThanF x)
+(GreaterEqualF (InvertFlags x)) -> (LessEqualF x)
// Boolean-generating instructions always
// zero upper bit of the register; no need to zero-extend
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
fp2flags = regInfo{inputs: []regMask{fp, fp}}
+ fp1flags = regInfo{inputs: []regMask{fp}}
fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
fp2load = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{fp}}
fpstore = regInfo{inputs: []regMask{gpspsbg, fp}}
{name: "TSTWconst", argLength: 1, reg: gp1flags, asm: "TSTW", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0, 32 bit
{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "FCMPS", typ: "Flags"}, // arg0 compare to arg1, float32
{name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to arg1, float64
+ {name: "FCMPS0", argLength: 1, reg: fp1flags, asm: "FCMPS", typ: "Flags"}, // arg0 compare to 0, float32
+ {name: "FCMPD0", argLength: 1, reg: fp1flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to 0, float64
// shifted ops
{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0<<auxInt)
return rewriteValueARM64_OpARM64FADDD_0(v)
case OpARM64FADDS:
return rewriteValueARM64_OpARM64FADDS_0(v)
+ case OpARM64FCMPD:
+ return rewriteValueARM64_OpARM64FCMPD_0(v)
+ case OpARM64FCMPS:
+ return rewriteValueARM64_OpARM64FCMPS_0(v)
case OpARM64FMOVDfpgp:
return rewriteValueARM64_OpARM64FMOVDfpgp_0(v)
case OpARM64FMOVDgpfp:
return rewriteValueARM64_OpARM64FSUBS_0(v)
case OpARM64GreaterEqual:
return rewriteValueARM64_OpARM64GreaterEqual_0(v)
+ case OpARM64GreaterEqualF:
+ return rewriteValueARM64_OpARM64GreaterEqualF_0(v)
case OpARM64GreaterEqualU:
return rewriteValueARM64_OpARM64GreaterEqualU_0(v)
case OpARM64GreaterThan:
return rewriteValueARM64_OpARM64GreaterThan_0(v)
+ case OpARM64GreaterThanF:
+ return rewriteValueARM64_OpARM64GreaterThanF_0(v)
case OpARM64GreaterThanU:
return rewriteValueARM64_OpARM64GreaterThanU_0(v)
case OpARM64LessEqual:
return rewriteValueARM64_OpARM64LessEqual_0(v)
+ case OpARM64LessEqualF:
+ return rewriteValueARM64_OpARM64LessEqualF_0(v)
case OpARM64LessEqualU:
return rewriteValueARM64_OpARM64LessEqualU_0(v)
case OpARM64LessThan:
return rewriteValueARM64_OpARM64LessThan_0(v)
+ case OpARM64LessThanF:
+ return rewriteValueARM64_OpARM64LessThanF_0(v)
case OpARM64LessThanU:
return rewriteValueARM64_OpARM64LessThanU_0(v)
case OpARM64MADD:
}
return false
}
+func rewriteValueARM64_OpARM64FCMPD_0(v *Value) bool {
+ b := v.Block
+ _ = b
+ // match: (FCMPD x (FMOVDconst [0]))
+ // cond:
+ // result: (FCMPD0 x)
+ for {
+ _ = v.Args[1]
+ x := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARM64FMOVDconst {
+ break
+ }
+ if v_1.AuxInt != 0 {
+ break
+ }
+ v.reset(OpARM64FCMPD0)
+ v.AddArg(x)
+ return true
+ }
+ // match: (FCMPD (FMOVDconst [0]) x)
+ // cond:
+ // result: (InvertFlags (FCMPD0 x))
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64FMOVDconst {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ x := v.Args[1]
+ v.reset(OpARM64InvertFlags)
+ v0 := b.NewValue0(v.Pos, OpARM64FCMPD0, types.TypeFlags)
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+ return false
+}
+func rewriteValueARM64_OpARM64FCMPS_0(v *Value) bool {
+ b := v.Block
+ _ = b
+ // match: (FCMPS x (FMOVSconst [0]))
+ // cond:
+ // result: (FCMPS0 x)
+ for {
+ _ = v.Args[1]
+ x := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARM64FMOVSconst {
+ break
+ }
+ if v_1.AuxInt != 0 {
+ break
+ }
+ v.reset(OpARM64FCMPS0)
+ v.AddArg(x)
+ return true
+ }
+ // match: (FCMPS (FMOVSconst [0]) x)
+ // cond:
+ // result: (InvertFlags (FCMPS0 x))
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64FMOVSconst {
+ break
+ }
+ if v_0.AuxInt != 0 {
+ break
+ }
+ x := v.Args[1]
+ v.reset(OpARM64InvertFlags)
+ v0 := b.NewValue0(v.Pos, OpARM64FCMPS0, types.TypeFlags)
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+ return false
+}
func rewriteValueARM64_OpARM64FMOVDfpgp_0(v *Value) bool {
b := v.Block
_ = b
}
return false
}
+func rewriteValueARM64_OpARM64GreaterEqualF_0(v *Value) bool {
+ // match: (GreaterEqualF (InvertFlags x))
+ // cond:
+ // result: (LessEqualF x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpARM64LessEqualF)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueARM64_OpARM64GreaterEqualU_0(v *Value) bool {
// match: (GreaterEqualU (FlagEQ))
// cond:
}
return false
}
+func rewriteValueARM64_OpARM64GreaterThanF_0(v *Value) bool {
+ // match: (GreaterThanF (InvertFlags x))
+ // cond:
+ // result: (LessThanF x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpARM64LessThanF)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueARM64_OpARM64GreaterThanU_0(v *Value) bool {
// match: (GreaterThanU (FlagEQ))
// cond:
}
return false
}
+func rewriteValueARM64_OpARM64LessEqualF_0(v *Value) bool {
+ // match: (LessEqualF (InvertFlags x))
+ // cond:
+ // result: (GreaterEqualF x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpARM64GreaterEqualF)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueARM64_OpARM64LessEqualU_0(v *Value) bool {
// match: (LessEqualU (FlagEQ))
// cond:
}
return false
}
+func rewriteValueARM64_OpARM64LessThanF_0(v *Value) bool {
+ // match: (LessThanF (InvertFlags x))
+ // cond:
+ // result: (GreaterThanF x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpARM64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpARM64GreaterThanF)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueARM64_OpARM64LessThanU_0(v *Value) bool {
// match: (LessThanU (FlagEQ))
// cond: