//
//===----------------------------------------------------------------------===//
+def f32ImmPred : PatLeaf<(f32 fpimm:$F)>;
+def f64ImmPred : PatLeaf<(f64 fpimm:$F)>;
+
+def ftoi : SDNodeXForm<fpimm, [{
+ APInt I = N->getValueAPF().bitcastToAPInt();
+ return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N),
+ MVT::getIntegerVT(I.getBitWidth()));
+}]>;
+
//===----------------------------------------------------------------------===//
// XTYPE/MPY
//===----------------------------------------------------------------------===//
let Inst{20,13,7,4} = 0b1111;
}
-let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
-def CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1),
- "$dst = CONST64(#$src1)",
- [(set F64:$dst, fpimm:$src1)]>,
- Requires<[HasV5T]>;
-
-let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
-def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
- "$dst = CONST32(#$src1)",
- [(set F32:$dst, fpimm:$src1)]>,
- Requires<[HasV5T]>;
-
-// Transfer immediate float.
-// Only works with single precision fp value.
-// For double precision, use CONST64_float_real, as 64bit transfer
-// can only hold 40-bit values - 32 from const ext + 8 bit immediate.
-// Make sure that complexity is more than the CONST32 pattern in
-// HexagonInstrInfo.td patterns.
-let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
- isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
- isCodeGenOnly = 1, isPseudo = 1 in
-def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
- "$dst = #$src1",
- [(set F32:$dst, fpimm:$src1)]>,
- Requires<[HasV5T]>;
-
-let isExtended = 1, opExtendable = 2, isPredicated = 1, hasSideEffects = 0,
- validSubTargets = HasV5SubT, isCodeGenOnly = 1, isPseudo = 1 in
-def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, f32Ext:$src2),
- "if ($src1) $dst = #$src2", []>,
- Requires<[HasV5T]>;
-
-let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1,
- hasSideEffects = 0, validSubTargets = HasV5SubT, isPseudo = 1 in
-def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, f32Ext:$src2),
- "if (!$src1) $dst = #$src2", []>,
- Requires<[HasV5T]>;
-
def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
SDTCisVT<1, i64>]>;
let Predicates = [HasV5T] in {
def: Pat<(i1 (seto F32:$src1, F32:$src2)),
(C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
- def: Pat<(i1 (seto F32:$src1, fpimm:$src2)),
- (C2_not (F2_sfcmpuo (TFRI_f fpimm:$src2), F32:$src1))>;
+ def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)),
+ (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
def: Pat<(i1 (seto F64:$src1, F64:$src2)),
(C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
- def: Pat<(i1 (seto F64:$src1, fpimm:$src2)),
- (C2_not (F2_dfcmpuo (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
+ def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)),
+ (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>;
}
// Ordered lt.
let Predicates = [HasV5T] in {
def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
(F2_sfcmpgt F32:$src2, F32:$src1)>;
- def: Pat<(i1 (setolt F32:$src1, fpimm:$src2)),
- (F2_sfcmpgt (f32 (TFRI_f fpimm:$src2)), F32:$src1)>;
+ def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)),
+ (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
(F2_dfcmpgt F64:$src2, F64:$src1)>;
- def: Pat<(i1 (setolt F64:$src1, fpimm:$src2)),
- (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
+ def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)),
+ (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
}
// Unordered lt.
let Predicates = [HasV5T] in {
def: Pat<(i1 (setult F32:$src1, F32:$src2)),
- (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
+ (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
(F2_sfcmpgt F32:$src2, F32:$src1))>;
- def: Pat<(i1 (setult F32:$src1, fpimm:$src2)),
- (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)),
- (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1))>;
+ def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)),
+ (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
+ (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
def: Pat<(i1 (setult F64:$src1, F64:$src2)),
- (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
+ (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
(F2_dfcmpgt F64:$src2, F64:$src1))>;
- def: Pat<(i1 (setult F64:$src1, fpimm:$src2)),
- (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)),
- (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
+ def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)),
+ (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
+ (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>;
}
// Ordered le.
// rs <= rt -> rt >= rs.
def: Pat<(i1 (setole F32:$src1, F32:$src2)),
(F2_sfcmpge F32:$src2, F32:$src1)>;
- def: Pat<(i1 (setole F32:$src1, fpimm:$src2)),
- (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
+ def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)),
+ (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
// Rss <= Rtt -> Rtt >= Rss.
def: Pat<(i1 (setole F64:$src1, F64:$src2)),
(F2_dfcmpge F64:$src2, F64:$src1)>;
- def: Pat<(i1 (setole F64:$src1, fpimm:$src2)),
- (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
+ def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)),
+ (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
}
// Unordered le.
let Predicates = [HasV5T] in {
// rs <= rt -> rt >= rs.
def: Pat<(i1 (setule F32:$src1, F32:$src2)),
- (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
+ (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
(F2_sfcmpge F32:$src2, F32:$src1))>;
- def: Pat<(i1 (setule F32:$src1, fpimm:$src2)),
- (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)),
- (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1))>;
+ def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)),
+ (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
+ (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>;
def: Pat<(i1 (setule F64:$src1, F64:$src2)),
- (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
+ (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
(F2_dfcmpge F64:$src2, F64:$src1))>;
- def: Pat<(i1 (setule F64:$src1, fpimm:$src2)),
- (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)),
- (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
+ def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)),
+ (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
+ (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>;
}
// Ordered ne.
(C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
def: Pat<(i1 (setone F64:$src1, F64:$src2)),
(C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
- def: Pat<(i1 (setone F32:$src1, fpimm:$src2)),
- (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
- def: Pat<(i1 (setone F64:$src1, fpimm:$src2)),
- (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
+ def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)),
+ (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
+ def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)),
+ (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
}
// Unordered ne.
def: Pat<(i1 (setune F64:$src1, F64:$src2)),
(C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
(C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
- def: Pat<(i1 (setune F32:$src1, fpimm:$src2)),
- (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)),
- (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2))))>;
- def: Pat<(i1 (setune F64:$src1, fpimm:$src2)),
- (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)),
+ def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)),
+ (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))),
+ (C2_not (F2_sfcmpeq F32:$src1,
+ (f32 (A2_tfrsi (ftoi $src2))))))>;
+ def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)),
+ (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))),
(C2_not (F2_dfcmpeq F64:$src1,
- (CONST64_Float_Real fpimm:$src2))))>;
+ (CONST64 (ftoi $src2)))))>;
}
// Besides set[o|u][comparions], we also need set[comparisons].
// lt.
def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
(F2_sfcmpgt F32:$src2, F32:$src1)>;
- def: Pat<(i1 (setlt F32:$src1, fpimm:$src2)),
- (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1)>;
+ def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)),
+ (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
(F2_dfcmpgt F64:$src2, F64:$src1)>;
- def: Pat<(i1 (setlt F64:$src1, fpimm:$src2)),
- (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
+ def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)),
+ (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>;
// le.
// rs <= rt -> rt >= rs.
def: Pat<(i1 (setle F32:$src1, F32:$src2)),
(F2_sfcmpge F32:$src2, F32:$src1)>;
- def: Pat<(i1 (setle F32:$src1, fpimm:$src2)),
- (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
+ def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)),
+ (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>;
// Rss <= Rtt -> Rtt >= Rss.
def: Pat<(i1 (setle F64:$src1, F64:$src2)),
(F2_dfcmpge F64:$src2, F64:$src1)>;
- def: Pat<(i1 (setle F64:$src1, fpimm:$src2)),
- (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
+ def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)),
+ (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>;
// ne.
def: Pat<(i1 (setne F32:$src1, F32:$src2)),
(C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
def: Pat<(i1 (setne F64:$src1, F64:$src2)),
(C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
- def: Pat<(i1 (setne F32:$src1, fpimm:$src2)),
- (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
- def: Pat<(i1 (setne F64:$src1, fpimm:$src2)),
- (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
+ def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)),
+ (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>;
+ def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)),
+ (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>;
}
// F2 convert template classes:
def F2_sffma_lib: T_sfmpy_acc <0, 1>;
def F2_sffms_lib: T_sfmpy_acc <1, 1>;
-def : Pat <(f32 (fma F32:$src2, F32:$src3, F32:$src1)),
+def : Pat <(fma F32:$src2, F32:$src3, F32:$src1),
(F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
// Floating-point fused multiply add w/ additional scaling (2**pu).
let Inst{4-0} = Rx;
}
-let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 3,
- isPseudo = 1, InputType = "imm" in
-def MUX_ir_f : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, f32Ext:$src3),
- "$dst = mux($src1, $src2, #$src3)",
- [(set F32:$dst, (f32 (select I1:$src1, F32:$src2, fpimm:$src3)))]>,
+def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm),
+ (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>,
Requires<[HasV5T]>;
-let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 2,
- isPseudo = 1, InputType = "imm" in
-def MUX_ri_f : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, f32Ext:$src2, IntRegs:$src3),
- "$dst = mux($src1, #$src2, $src3)",
- [(set F32:$dst, (f32 (select I1:$src1, fpimm:$src2, F32:$src3)))]>,
+def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt),
+ (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>,
Requires<[HasV5T]>;
def: Pat<(select I1:$src1, F32:$src2, F32:$src3),
Requires<[HasV5T]>;
// Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
-// => r0 = MUX_ir_f(p0, #i, r1)
-def: Pat<(select (not I1:$src1), fpimm:$src2, F32:$src3),
- (MUX_ir_f I1:$src1, F32:$src3, fpimm:$src2)>,
+// => r0 = mux(p0, #i, r1)
+def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3),
+ (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>,
Requires<[HasV5T]>;
// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
-// => r0 = MUX_ri_f(p0, r1, #i)
-def: Pat<(select (not I1:$src1), F32:$src2, fpimm:$src3),
- (MUX_ri_f I1:$src1, fpimm:$src3, F32:$src2)>,
+// => r0 = mux(p0, r1, #i)
+def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3),
+ (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>,
Requires<[HasV5T]>;
def: Pat<(i32 (fp_to_sint F64:$src1)),
// Classify floating-point value
let isFP = 1 in
- def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
+def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
let isFP = 1 in
def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5),
}
let hasNewValue = 1, opNewValue = 0 in {
-def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>;
-def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>;
+ def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>;
+ def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>;
}
def F2_dfimm_p : T_fimm <"dfmake", DoubleRegs, 0b1001, 0>;