From 383c36e3a805e5c2f0cc6dbca5d1a6e61fff229b Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Fri, 5 Dec 2014 18:24:06 +0000 Subject: [PATCH] [Hexagon] Adding DoubleRegs decoder. Moving C2_mux and A2_nop. Adding combine imm-imm form. llvm-svn: 223494 --- .../Disassembler/HexagonDisassembler.cpp | 24 ++++++++++ llvm/lib/Target/Hexagon/HexagonISelLowering.h | 1 + llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 45 ++++++++++++++----- .../MC/Disassembler/Hexagon/alu32_perm.txt | 2 + 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 72ba2f5ea54a..26640c5e1f61 100644 --- a/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -61,6 +61,16 @@ static const uint16_t IntRegDecoderTable[] = { static const uint16_t PredRegDecoderTable[] = { Hexagon::P0, Hexagon::P1, Hexagon::P2, Hexagon::P3 }; +static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, + const uint16_t Table[], size_t Size) { + if (RegNo < Size) { + Inst.addOperand(MCOperand::CreateReg(Table[RegNo])); + return MCDisassembler::Success; + } + else + return MCDisassembler::Fail; +} + static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, void const *Decoder) { @@ -72,6 +82,20 @@ static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, const void *Decoder) { + static const uint16_t DoubleRegDecoderTable[] = { + Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, + Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, + Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, + Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15 + }; + + return (DecodeRegisterClass(Inst, RegNo >> 1, + DoubleRegDecoderTable, + sizeof (DoubleRegDecoderTable))); +} + static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, void const *Decoder) { diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 63e4392e06f5..99ac0eebd180 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -49,6 +49,7 @@ namespace llvm { RET_FLAG, // Return with a flag operand. BR_JT, // Jump table. BARRIER, // Memory barrier. + COMBINE, WrapperJT, WrapperCP, WrapperCombineII, diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 82f047c4d8a2..50f982654cd0 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -95,6 +95,8 @@ multiclass CMP64_rr { //===----------------------------------------------------------------------===// def SDTHexagonI64I32I32 : SDTypeProfile<1, 2, [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; + +def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>; def HexagonWrapperCombineII : SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>; @@ -267,6 +269,39 @@ def C2_mux: ALU32_rr<(outs IntRegs:$Rd), let Inst{4-0} = Rd; } +def: Pat<(i32 (select (i1 PredRegs:$Pu), (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))), + (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>; + +// Combines the two immediates into a double register. +// Increase complexity to make it greater than any complexity of a combine +// that involves a register. + +let isReMaterializable = 1, isMoveImm = 1, isAsCheapAsAMove = 1, + isExtentSigned = 1, isExtendable = 1, opExtentBits = 8, opExtendable = 1, + AddedComplexity = 75, isCodeGenOnly = 0 in +def A2_combineii: ALU32Inst <(outs DoubleRegs:$Rdd), (ins s8Ext:$s8, s8Imm:$S8), + "$Rdd = combine(#$s8, #$S8)", + [(set (i64 DoubleRegs:$Rdd), + (i64 (HexagonCOMBINE(i32 s8ExtPred:$s8), (i32 s8ImmPred:$S8))))]> { + bits<5> Rdd; + bits<8> s8; + bits<8> S8; + + let IClass = 0b0111; + let Inst{27-23} = 0b11000; + let Inst{22-16} = S8{7-1}; + let Inst{13} = S8{0}; + let Inst{12-5} = s8; + let Inst{4-0} = Rdd; + } + +// Nop. +let hasSideEffects = 0, isCodeGenOnly = 0 in +def A2_nop: ALU32Inst <(outs), (ins), "nop" > { + let IClass = 0b0111; + let Inst{27-24} = 0b1111; +} + multiclass ALU32_Pbase { let isPredicatedNew = isPredNew in @@ -400,9 +435,6 @@ multiclass ZXTB_base minOp> { let isCodeGenOnly=0 in defm zxtb : ZXTB_base<"zxtb",0b100>, PredNewRel; -def: Pat<(i32 (select (i1 PredRegs:$Pu), (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))), - (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>; - // Combines the two integer registers SRC1 and SRC2 into a double register. let isPredicable = 1 in class T_Combine : ALU32_rr<(outs DoubleRegs:$dst), @@ -491,13 +523,6 @@ def AND_ri : ALU32_ri<(outs IntRegs:$dst), [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), s10ExtPred:$src2))]>, ImmRegRel; -// Nop. -let hasSideEffects = 0, isCodeGenOnly = 0 in -def A2_nop: ALU32Inst <(outs), (ins), "nop" > { - let IClass = 0b0111; - let Inst{27-24} = 0b1111; -} - // Rd32=sub(#s10,Rs32) let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10, CextOpcode = "SUB", InputType = "imm" in diff --git a/llvm/test/MC/Disassembler/Hexagon/alu32_perm.txt b/llvm/test/MC/Disassembler/Hexagon/alu32_perm.txt index 00ea8923b4e6..b6009a429f89 100644 --- a/llvm/test/MC/Disassembler/Hexagon/alu32_perm.txt +++ b/llvm/test/MC/Disassembler/Hexagon/alu32_perm.txt @@ -8,6 +8,8 @@ # CHECK: r17 = combine(r31.l, r21.h) 0x11 0xdf 0xf5 0xf3 # CHECK: r17 = combine(r31.l, r21.l) +0xb0 0xe2 0x0f 0x7c +# CHECK: r17:16 = combine(#21, #31) 0x11 0xc0 0x15 0x70 # CHECK: r17 = aslh(r21) 0x11 0xc0 0x35 0x70