aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/CSKY/CSKYInstrInfo.td
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/CSKY/CSKYInstrInfo.td')
-rw-r--r--llvm/lib/Target/CSKY/CSKYInstrInfo.td52
1 files changed, 51 insertions, 1 deletions
diff --git a/llvm/lib/Target/CSKY/CSKYInstrInfo.td b/llvm/lib/Target/CSKY/CSKYInstrInfo.td
index 549c883c34a7..c6bfc2495ae2 100644
--- a/llvm/lib/Target/CSKY/CSKYInstrInfo.td
+++ b/llvm/lib/Target/CSKY/CSKYInstrInfo.td
@@ -158,6 +158,30 @@ def uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
let DecoderMethod = "decodeImmShiftOpValue";
}
+// Optimize (or x, imm) to (BSETI x, log2(imm)). We should exclude the
+// case can be opimized to (ORI32/ORI16 x, imm).
+def imm32_1_pop_bit_XFORM : SDNodeXForm<imm, [{
+ uint32_t I = N->getZExtValue();
+ return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N),
+ N->getValueType(0));
+}]>;
+def imm32_1_pop_bit : PatLeaf<(imm), [{
+ uint32_t I = N->getZExtValue();
+ return llvm::popcount(I) == 1 && I > 0xfff;
+}]>;
+
+// Optimize (and x, imm) to (BCLRI x, log2(~imm)). We should exclude the
+// case can be opimized to (ANDNI x, ~imm).
+def imm32_1_zero_bit_XFORM : SDNodeXForm<imm, [{
+ uint32_t I = ~N->getZExtValue();
+ return CurDAG->getTargetConstant(llvm::Log2_32(I), SDLoc(N),
+ N->getValueType(0));
+}]>;
+def imm32_1_zero_bit : PatLeaf<(imm), [{
+ uint32_t I = ~N->getZExtValue();
+ return llvm::popcount(I) == 1 && I > 0xfff;
+}]>;
+
def CSKYSymbol : AsmOperandClass {
let Name = "CSKYSymbol";
let RenderMethod = "addImmOperands";
@@ -1178,6 +1202,13 @@ multiclass BTF32Pat0<PatFrag cond0, PatFrag cond1, ImmLeaf imm_ty, Instruction i
defm : BTF32Pat0<setne, seteq, uimm16, CMPNEI32>;
defm : BTF32Pat0<setuge, setult, oimm16, CMPHSI32>;
defm : BTF32Pat0<setlt, setge, oimm16, CMPLTI32>;
+
+def : Pat<(brcond (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16),
+ (BT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
+ bb:$imm16)>;
+def : Pat<(brcond (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)), bb:$imm16),
+ (BF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
+ bb:$imm16)>;
}
let Predicates = [iHas2E3] in {
@@ -1226,6 +1257,8 @@ def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 -1))), bb:$imm16),
let Predicates = [iHas2E3] in {
def : Pat<(setne GPR:$rs1, GPR:$rs2),
(CMPNE32 GPR:$rs1, GPR:$rs2)>;
+ def : Pat<(setne (and GPR:$rs, imm32_1_pop_bit:$im), 0),
+ (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im))>;
def : Pat<(i32 (seteq GPR:$rs1, GPR:$rs2)),
(MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>;
def : Pat<(setuge GPR:$rs1, GPR:$rs2),
@@ -1342,8 +1375,16 @@ def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false),
(ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false),
(ISEL32 CARRY:$ca, GPR:$rx, GPR:$false)>;
-}
+def : Pat<(select (i32 (setne (and GPR:$rs, imm32_1_pop_bit:$im), 0)),
+ GPR:$true, GPR:$false),
+ (MOVT32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
+ GPR:$true, GPR:$false)>;
+def : Pat<(select (i32 (seteq (and GPR:$rs, imm32_1_pop_bit:$im), 0)),
+ GPR:$true, GPR:$false),
+ (MOVF32 (BTSTI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$im)),
+ GPR:$true, GPR:$false)>;
+}
let Predicates = [iHas2E3] in {
def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), (add GPR:$rx, uimm5:$imm), GPR:$false),
@@ -1422,6 +1463,14 @@ let Predicates = [iHasE2] in
def : Pat<(i32 imm:$imm),
(ORI32 (MOVIH32 (uimm32_hi16 imm:$imm)), (uimm32_lo16 imm:$imm))>;
+// Bit operations.
+let Predicates = [iHasE2] in {
+ def : Pat<(or GPR:$rs, imm32_1_pop_bit:$imm),
+ (BSETI32 GPR:$rs, (imm32_1_pop_bit_XFORM imm32_1_pop_bit:$imm))>;
+ def : Pat<(and GPR:$rs, imm32_1_zero_bit:$imm),
+ (BCLRI32 GPR:$rs, (imm32_1_zero_bit_XFORM imm32_1_zero_bit:$imm))>;
+}
+
// Other operations.
let Predicates = [iHasE2] in {
def : Pat<(rotl GPR:$rs1, GPR:$rs2),
@@ -1429,6 +1478,7 @@ let Predicates = [iHasE2] in {
let Predicates = [iHas2E3] in {
def : Pat<(bitreverse GPR:$rx), (BREV32 GPR:$rx)>;
def : Pat<(bswap GPR:$rx), (REVB32 GPR:$rx)>;
+ def : Pat<(i32 (cttz GPR:$rx)), (FF1 (BREV32 GPR:$rx))>;
}
def : Pat<(i32 (ctlz GPR:$rx)), (FF1 GPR:$rx)>;
}