From: Colin LeMahieu Date: Tue, 25 Nov 2014 20:20:09 +0000 (+0000) Subject: [Hexagon] Adding C2_mux instruction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=609c7fa14eca7e98f979c62efe69071d9b8e4681;p=llvm [Hexagon] Adding C2_mux instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222784 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index e527ab1163c..c59bc0b21c0 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -338,7 +338,7 @@ static unsigned doesIntrinsicContainPredicate(unsigned ID) case Intrinsic::hexagon_C2_mask: return Hexagon::MASK_p; case Intrinsic::hexagon_C2_mux: - return Hexagon::MUX_rr; + return Hexagon::C2_mux; // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but // that's how it's mapped in q6protos.h. diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index a8081001fac..1574f8cb745 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -296,6 +296,30 @@ multiclass ZXTB_base minOp> { defm zxtb : ZXTB_base<"zxtb",0b100>, PredNewRel; +let CextOpcode = "MUX", InputType = "reg", hasNewValue = 1 in +def C2_mux: ALU32_rr<(outs IntRegs:$Rd), + (ins PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt), + "$Rd = mux($Pu, $Rs, $Rt)", [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel { + bits<5> Rd; + bits<2> Pu; + bits<5> Rs; + bits<5> Rt; + + let CextOpcode = "mux"; + let InputType = "reg"; + let hasSideEffects = 0; + let IClass = 0b1111; + + let Inst{27-24} = 0b0100; + let Inst{20-16} = Rs; + let Inst{12-8} = Rt; + let Inst{6-5} = Pu; + 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 integer registers SRC1 and SRC2 into a double register. let isPredicable = 1 in class T_Combine : ALU32_rr<(outs DoubleRegs:$dst), @@ -557,14 +581,6 @@ def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, "$dst = vmux($src1, $src2, $src3)", []>; -let CextOpcode = "MUX", InputType = "reg" in -def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, - IntRegs:$src2, IntRegs:$src3), - "$dst = mux($src1, $src2, $src3)", - [(set (i32 IntRegs:$dst), - (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))]>, ImmRegRel; - let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, CextOpcode = "MUX", InputType = "imm" in def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2, @@ -1999,19 +2015,6 @@ def TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1), "$dst = #$src1", [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>; -// Pseudo instruction to encode a set of conditional transfers. -// This instruction is used instead of a mux and trades-off codesize -// for performance. We conduct this transformation optimistically in -// the hope that these instructions get promoted to dot-new transfers. -let AddedComplexity = 100, isPredicated = 1 in -def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, - IntRegs:$src2, - IntRegs:$src3), - "Error; should not emit", - [(set (i32 IntRegs:$dst), - (i32 (select (i1 PredRegs:$src1), - (i32 IntRegs:$src2), - (i32 IntRegs:$src3))))]>; let AddedComplexity = 100, isPredicated = 1 in def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3), @@ -2430,12 +2433,12 @@ def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), // Hexagon does not support 64-bit MUXes; so emulate with combines. def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src3)), - (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1), + (i64 (COMBINE_rr (i32 (C2_mux (i1 PredRegs:$src1), (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)), (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), subreg_hireg)))), - (i32 (MUX_rr (i1 PredRegs:$src1), + (i32 (C2_mux (i1 PredRegs:$src1), (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)), (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp index 25d6c68e62b..8f7be60b70b 100644 --- a/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -199,8 +199,7 @@ static bool commonChecksToProhibitNewValueJump(bool afterRA, // of registers by individual passes in the backend. At this time, // we don't know the scope of usage and definitions of these // instructions. - if (MII->getOpcode() == Hexagon::TFR_condset_rr || - MII->getOpcode() == Hexagon::TFR_condset_ii || + if (MII->getOpcode() == Hexagon::TFR_condset_ii || MII->getOpcode() == Hexagon::TFR_condset_ri || MII->getOpcode() == Hexagon::TFR_condset_ir || MII->getOpcode() == Hexagon::LDriw_pred || diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp index 8912152c943..a7a96757f75 100644 --- a/lib/Target/Hexagon/HexagonPeephole.cpp +++ b/lib/Target/Hexagon/HexagonPeephole.cpp @@ -269,10 +269,9 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) { unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices. switch (Op) { - case Hexagon::TFR_condset_rr: - case Hexagon::TFR_condset_ii: + case Hexagon::C2_mux: case Hexagon::MUX_ii: - case Hexagon::MUX_rr: + case Hexagon::TFR_condset_ii: NewOp = Op; break; case Hexagon::TFR_condset_ri: diff --git a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp index 1052b80f7e9..ac620618f2e 100644 --- a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp +++ b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp @@ -92,15 +92,13 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) { MachineInstr *MI = MII; int Opc1, Opc2; switch(MI->getOpcode()) { - case Hexagon::TFR_condset_rr: case Hexagon::TFR_condset_rr_f: case Hexagon::TFR_condset_rr64_f: { int DestReg = MI->getOperand(0).getReg(); int SrcReg1 = MI->getOperand(2).getReg(); int SrcReg2 = MI->getOperand(3).getReg(); - if (MI->getOpcode() == Hexagon::TFR_condset_rr || - MI->getOpcode() == Hexagon::TFR_condset_rr_f) { + if (MI->getOpcode() == Hexagon::TFR_condset_rr_f) { Opc1 = Hexagon::TFR_cPt; Opc2 = Hexagon::TFR_cNotPt; } diff --git a/test/MC/Hexagon/inst_select.ll b/test/MC/Hexagon/inst_select.ll new file mode 100644 index 00000000000..daafa20ca8e --- /dev/null +++ b/test/MC/Hexagon/inst_select.ll @@ -0,0 +1,10 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-objdump -s - | FileCheck %s + +define i32 @foo (i1 %a, i32 %b, i32 %c) +{ + %1 = select i1 %a, i32 %b, i32 %c + ret i32 %1 +} + +; CHECK: 0000 00400000 004201f4 00c09f52 \ No newline at end of file