From 18f28b2de617f8cd30e6b9aee73d97b3f3b0d7f9 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Tue, 16 Dec 2014 20:57:56 +0000 Subject: [PATCH] [Hexagon] Adding bit count and twiddling instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224367 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonInstrInfo.td | 99 ++++++++++++++++++++++ test/MC/Disassembler/Hexagon/xtype_bit.txt | 30 +++++++ 2 files changed, 129 insertions(+) diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index eadf93873be..1eb6ebefd33 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -2847,6 +2847,105 @@ def S2_deinterleave : T_S2op_3 <"deinterleave", 0b11, 0b100>; //===----------------------------------------------------------------------===// // STYPE/BIT + //===----------------------------------------------------------------------===// +// Bit count + +let hasSideEffects = 0, hasNewValue = 1 in +class T_COUNT_LEADING MajOp, bits<3> MinOp, bit Is32, + dag Out, dag Inp> + : SInst { + bits<5> Rs; + bits<5> Rd; + let IClass = 0b1000; + let Inst{27} = 0b1; + let Inst{26} = Is32; + let Inst{25-24} = 0b00; + let Inst{23-21} = MajOp; + let Inst{20-16} = Rs; + let Inst{7-5} = MinOp; + let Inst{4-0} = Rd; +} + +class T_COUNT_LEADING_32 MajOp, bits<3> MinOp> + : T_COUNT_LEADING; + +class T_COUNT_LEADING_64 MajOp, bits<3> MinOp> + : T_COUNT_LEADING; + +let isCodeGenOnly = 0 in { +def S2_cl0 : T_COUNT_LEADING_32<"cl0", 0b000, 0b101>; +def S2_cl1 : T_COUNT_LEADING_32<"cl1", 0b000, 0b110>; +def S2_ct0 : T_COUNT_LEADING_32<"ct0", 0b010, 0b100>; +def S2_ct1 : T_COUNT_LEADING_32<"ct1", 0b010, 0b101>; +def S2_cl0p : T_COUNT_LEADING_64<"cl0", 0b010, 0b010>; +def S2_cl1p : T_COUNT_LEADING_64<"cl1", 0b010, 0b100>; +def S2_clb : T_COUNT_LEADING_32<"clb", 0b000, 0b100>; +def S2_clbp : T_COUNT_LEADING_64<"clb", 0b010, 0b000>; +def S2_clbnorm : T_COUNT_LEADING_32<"normamt", 0b000, 0b111>; +} + +def: Pat<(i32 (ctlz I32:$Rs)), (S2_cl0 I32:$Rs)>; +def: Pat<(i32 (ctlz (not I32:$Rs))), (S2_cl1 I32:$Rs)>; +def: Pat<(i32 (cttz I32:$Rs)), (S2_ct0 I32:$Rs)>; +def: Pat<(i32 (cttz (not I32:$Rs))), (S2_ct1 I32:$Rs)>; +def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>; +def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>; + +// Bit set/clear/toggle + +let hasSideEffects = 0, hasNewValue = 1 in +class T_SCT_BIT_IMM MinOp> + : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, u5Imm:$u5), + "$Rd = "#MnOp#"($Rs, #$u5)", [], "", S_2op_tc_1_SLOT23> { + bits<5> Rd; + bits<5> Rs; + bits<5> u5; + let IClass = 0b1000; + let Inst{27-21} = 0b1100110; + let Inst{20-16} = Rs; + let Inst{13} = 0b0; + let Inst{12-8} = u5; + let Inst{7-5} = MinOp; + let Inst{4-0} = Rd; +} + +let hasSideEffects = 0, hasNewValue = 1 in +class T_SCT_BIT_REG MinOp> + : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt), + "$Rd = "#MnOp#"($Rs, $Rt)", [], "", S_3op_tc_1_SLOT23> { + bits<5> Rd; + bits<5> Rs; + bits<5> Rt; + let IClass = 0b1100; + let Inst{27-22} = 0b011010; + let Inst{20-16} = Rs; + let Inst{12-8} = Rt; + let Inst{7-6} = MinOp; + let Inst{4-0} = Rd; +} + +let isCodeGenOnly = 0 in { +def S2_clrbit_i : T_SCT_BIT_IMM<"clrbit", 0b001>; +def S2_setbit_i : T_SCT_BIT_IMM<"setbit", 0b000>; +def S2_togglebit_i : T_SCT_BIT_IMM<"togglebit", 0b010>; +def S2_clrbit_r : T_SCT_BIT_REG<"clrbit", 0b01>; +def S2_setbit_r : T_SCT_BIT_REG<"setbit", 0b00>; +def S2_togglebit_r : T_SCT_BIT_REG<"togglebit", 0b10>; +} + +def: Pat<(i32 (and (i32 IntRegs:$Rs), (not (shl 1, u5ImmPred:$u5)))), + (S2_clrbit_i IntRegs:$Rs, u5ImmPred:$u5)>; +def: Pat<(i32 (or (i32 IntRegs:$Rs), (shl 1, u5ImmPred:$u5))), + (S2_setbit_i IntRegs:$Rs, u5ImmPred:$u5)>; +def: Pat<(i32 (xor (i32 IntRegs:$Rs), (shl 1, u5ImmPred:$u5))), + (S2_togglebit_i IntRegs:$Rs, u5ImmPred:$u5)>; +def: Pat<(i32 (and (i32 IntRegs:$Rs), (not (shl 1, (i32 IntRegs:$Rt))))), + (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>; +def: Pat<(i32 (or (i32 IntRegs:$Rs), (shl 1, (i32 IntRegs:$Rt)))), + (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>; +def: Pat<(i32 (xor (i32 IntRegs:$Rs), (shl 1, (i32 IntRegs:$Rt)))), + (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>; // clrbit. def CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), diff --git a/test/MC/Disassembler/Hexagon/xtype_bit.txt b/test/MC/Disassembler/Hexagon/xtype_bit.txt index 40e5f0335e2..d4a10cf3fab 100644 --- a/test/MC/Disassembler/Hexagon/xtype_bit.txt +++ b/test/MC/Disassembler/Hexagon/xtype_bit.txt @@ -1,8 +1,38 @@ # RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s +0x11 0xc0 0x54 0x88 +# CHECK: r17 = clb(r21:20) +0x51 0xc0 0x54 0x88 +# CHECK: r17 = cl0(r21:20) +0x91 0xc0 0x54 0x88 +# CHECK: r17 = cl1(r21:20) +0x91 0xc0 0x15 0x8c +# CHECK: r17 = clb(r21) +0xb1 0xc0 0x15 0x8c +# CHECK: r17 = cl0(r21) +0xd1 0xc0 0x15 0x8c +# CHECK: r17 = cl1(r21) +0xf1 0xc0 0x15 0x8c +# CHECK: r17 = normamt(r21) +0x91 0xc0 0x55 0x8c +# CHECK: r17 = ct0(r21) +0xb1 0xc0 0x55 0x8c +# CHECK: r17 = ct1(r21) 0x90 0xc0 0xd4 0x80 # CHECK: r17:16 = deinterleave(r21:20) 0xb0 0xc0 0xd4 0x80 # CHECK: r17:16 = interleave(r21:20) 0x11 0xde 0x14 0xd0 # CHECK: r17 = parity(r21:20, r31:30) +0x11 0xdf 0xd5 0x8c +# CHECK: r17 = setbit(r21, #31) +0x31 0xdf 0xd5 0x8c +# CHECK: r17 = clrbit(r21, #31) +0x51 0xdf 0xd5 0x8c +# CHECK: r17 = togglebit(r21, #31) +0x11 0xdf 0x95 0xc6 +# CHECK: r17 = setbit(r21, r31) +0x51 0xdf 0x95 0xc6 +# CHECK: r17 = clrbit(r21, r31) +0x91 0xdf 0x95 0xc6 +# CHECK: r17 = togglebit(r21, r31) -- 2.34.1