From 13f8b36205607ff87ad0c4daf28f63b2660e7c0f Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 1 Aug 2009 01:43:45 +0000 Subject: [PATCH] Split t2MOVCCs since some assemblers do not recognize mov shifted register alias with predicate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77764 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 19 ++++++++++++--- lib/Target/ARM/ARMInstrThumb2.td | 18 ++++++++++---- test/CodeGen/Thumb2/thumb2-select.ll | 35 ++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 8f1be437ed9..bcef059fa3c 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1101,12 +1101,25 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { SDValue CPTmp2; if (Subtarget->isThumb()) { if (SelectT2ShifterOperandReg(Op, N1, CPTmp0, CPTmp1)) { + unsigned SOVal = cast(CPTmp1)->getZExtValue(); + unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); + unsigned Opc = 0; + switch (SOShOp) { + case ARM_AM::lsl: Opc = ARM::t2MOVCClsl; break; + case ARM_AM::lsr: Opc = ARM::t2MOVCClsr; break; + case ARM_AM::asr: Opc = ARM::t2MOVCCasr; break; + case ARM_AM::ror: Opc = ARM::t2MOVCCror; break; + default: + llvm_unreachable("Unknown so_reg opcode!"); + break; + } + SDValue SOShImm = + CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32); SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) cast(N2)->getZExtValue()), MVT::i32); - SDValue Ops[] = { N0, CPTmp0, CPTmp1, Tmp2, N3, InFlag }; - return CurDAG->SelectNodeTo(Op.getNode(), - ARM::t2MOVCCs, MVT::i32,Ops, 6); + SDValue Ops[] = { N0, CPTmp0, SOShImm, Tmp2, N3, InFlag }; + return CurDAG->SelectNodeTo(Op.getNode(), Opc, MVT::i32,Ops, 6); } } else { if (SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) { diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index bb4f11a307b..afab366639b 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -980,16 +980,24 @@ def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $dst">; -def t2MOVCCs : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_reg:$true), - "mov", ".w $dst, $true", -[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_reg:$true, imm:$cc, CCR:$ccr))*/]>, - RegConstraint<"$false = $dst">; - def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), "mov", ".w $dst, $true", [/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $dst">; +def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), + "lsl", ".w $dst, $true, $rhs", []>, + RegConstraint<"$false = $dst">; +def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), + "lsr", ".w $dst, $true, $rhs", []>, + RegConstraint<"$false = $dst">; +def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), + "asr", ".w $dst, $true, $rhs", []>, + RegConstraint<"$false = $dst">; +def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs), + "ror", ".w $dst, $true, $rhs", []>, + RegConstraint<"$false = $dst">; + //===----------------------------------------------------------------------===// // TLS Instructions // diff --git a/test/CodeGen/Thumb2/thumb2-select.ll b/test/CodeGen/Thumb2/thumb2-select.ll index 86f7c0359a8..91639a13e9d 100644 --- a/test/CodeGen/Thumb2/thumb2-select.ll +++ b/test/CodeGen/Thumb2/thumb2-select.ll @@ -61,3 +61,38 @@ entry: %tmp1.s = select i1 %tmp, i32 2, i32 3 ret i32 %tmp1.s } + +define i32 @f7(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f7: +; CHECK: it hi +; CHECK: lsrhi.w + %tmp1 = icmp ugt i32 %a, %b + %tmp2 = udiv i32 %c, 3 + %tmp3 = select i1 %tmp1, i32 %tmp2, i32 3 + ret i32 %tmp3 +} + +define i32 @f8(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f8: +; CHECK: it lo +; CHECK: lsllo.w + %tmp1 = icmp ult i32 %a, %b + %tmp2 = mul i32 %c, 4 + %tmp3 = select i1 %tmp1, i32 %tmp2, i32 3 + ret i32 %tmp3 +} + +define i32 @f9(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f9: +; CHECK: it ge +; CHECK: rorge.w + %tmp1 = icmp sge i32 %a, %b + %tmp2 = shl i32 %c, 10 + %tmp3 = lshr i32 %c, 22 + %tmp4 = or i32 %tmp2, %tmp3 + %tmp5 = select i1 %tmp1, i32 %tmp4, i32 3 + ret i32 %tmp5 +} -- 2.34.1