diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-08-01 01:43:45 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-08-01 01:43:45 +0000 |
commit | 13f8b36205607ff87ad0c4daf28f63b2660e7c0f (patch) | |
tree | caf8857b20c7f0da2ef6f9e27afe71f60998e786 | |
parent | 458ba32680488486b7166e40fd3e25b4dccf73fd (diff) |
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
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 19 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 18 | ||||
-rw-r--r-- | 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 8f1be437ed..bcef059fa3 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<ConstantSDNode>(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<ConstantSDNode>(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 bb4f11a307..afab366639 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 86f7c0359a..91639a13e9 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 +} |