aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-08-01 01:43:45 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-08-01 01:43:45 +0000
commit13f8b36205607ff87ad0c4daf28f63b2660e7c0f (patch)
treecaf8857b20c7f0da2ef6f9e27afe71f60998e786
parent458ba32680488486b7166e40fd3e25b4dccf73fd (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.cpp19
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td18
-rw-r--r--test/CodeGen/Thumb2/thumb2-select.ll35
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
+}