Properly pseudo-ize the ARM LDMIA_RET instruction. This has the nice side-
authorJim Grosbach <grosbach@apple.com>
Fri, 11 Mar 2011 22:51:41 +0000 (22:51 +0000)
committerJim Grosbach <grosbach@apple.com>
Fri, 11 Mar 2011 22:51:41 +0000 (22:51 +0000)
effect that we get proper instruction printing using the "pop" mnemonic for it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127502 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMInstrInfo.td
test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll
test/CodeGen/ARM/2010-10-25-ifcvt-ldm.ll
test/CodeGen/ARM/2010-11-29-PrologueBug.ll
test/CodeGen/ARM/bx_fold.ll
test/CodeGen/ARM/code-placement.ll
test/CodeGen/ARM/ifcvt10.ll
test/CodeGen/ARM/ifcvt5.ll
test/CodeGen/ARM/ifcvt6.ll
test/CodeGen/ARM/ifcvt7.ll
test/CodeGen/ARM/ifcvt8.ll
test/CodeGen/ARM/ldm.ll

index e1a2cc57abf0bb65bd41f611e390dcd0f69e31e3..478c2468381f70e314a4e05c8663a82eb2e62b77 100644 (file)
@@ -945,6 +945,16 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   unsigned Opc = MI->getOpcode();
   switch (Opc) {
   default: break;
+  case ARM::LDMIA_RET: {
+    // LDMIA_RET is just a normal LDMIA_UPD instruction that targets PC and as
+    // such has additional code-gen properties and scheduling information.
+    // To emit it, we just construct as normal and set the opcode to LDMIA_UPD.
+    MCInst TmpInst;
+    LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
+    TmpInst.setOpcode(ARM::LDMIA_UPD);
+    OutStreamer.EmitInstruction(TmpInst);
+    return;
+  }
   case ARM::t2ADDrSPi:
   case ARM::t2ADDrSPi12:
   case ARM::t2SUBrSPi:
index 2bfe11c955e0011052231863b47cec0701fe6742..bb40e39903b1945d9ef5b9b1219f01c18604521c 100644 (file)
@@ -1928,16 +1928,10 @@ def : MnemonicAlias<"stm", "stmia">;
 // FIXME: Should pc be an implicit operand like PICADD, etc?
 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
     hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
-// FIXME: Should be a pseudo-instruction.
-def LDMIA_RET : AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
-                                      reglist:$regs, variable_ops),
-                     IndexModeUpd, LdStMulFrm, IIC_iLoad_mBr,
-                     "ldmia${p}\t$Rn!, $regs",
-                     "$Rn = $wb", []> {
-  let Inst{24-23} = 0b01;       // Increment After
-  let Inst{21}    = 1;          // Writeback
-  let Inst{20}    = 1;          // Load
-}
+def LDMIA_RET : ARMPseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
+                                               reglist:$regs, variable_ops),
+                     Size4Bytes, IIC_iLoad_mBr, []>,
+      RegConstraint<"$Rn = $wb">;
 
 //===----------------------------------------------------------------------===//
 //  Move Instructions.
index d9e1a1486a3cd95e0807f3638d38667d268f5c8d..fee86008ad713dbc1a696976202720e9aaf60cfd 100644 (file)
@@ -6,7 +6,7 @@ define i32 @bar(i32 %a) nounwind {
 entry:
   %0 = tail call i32 @foo(i32 %a) nounwind ; <i32> [#uses=1]
   %1 = add nsw i32 %0, 3                          ; <i32> [#uses=1]
-; CHECK: ldmia sp!, {r11, pc}
+; CHECK: pop {r11, pc}
 ; V4: pop
 ; V4-NEXT: mov pc, lr
   ret i32 %1
index 163c9b030ec8efe3e1d77ce7685422bd0d6d7a0e..32d350e9c8b1ea5c8ce9caf1be706b6a791980c8 100644 (file)
@@ -4,9 +4,9 @@
 ; was being treated as an instruction count.
 
 ; CHECK: push
-; CHECK: ldmia
-; CHECK: ldmia
-; CHECK: ldmia
+; CHECK: pop
+; CHECK: pop
+; CHECK: pop
 
 define i32 @test(i32 %x) {
 entry:
index 8d7541feae949a73cf9835c2f0c6d2b9c365d8da..e3c18cefd51df7d0197a9a5d1280100f0b02714d 100644 (file)
@@ -10,7 +10,7 @@ entry:
 ; ARM: bl _foo
 ; ARM: bl _foo
 ; ARM: bl _foo
-; ARM: ldmia sp!, {r7, pc}
+; ARM: pop {r7, pc}
 
 ; THUMB2: t:
 ; THUMB2: push
index 09f1aae0a9f0dbea39a1121f8d34ce048cc2ef96..5533038fb8280eb1a17352b9f85209f138c30c13 100644 (file)
@@ -24,7 +24,7 @@ bb1:          ; preds = %bb, %entry
 
 bb18:          ; preds = %bb1
 ; CHECK-NOT: bx
-; CHECK: ldmia sp!
+; CHECK: pop
        ret void
 }
 
index 036598fc0606bee242236f42bb0c59ff4a97094e..91ef65925221ff9064626b042940bc9f8b218cb9 100644 (file)
@@ -72,7 +72,7 @@ bb2.preheader:                                    ; preds = %bb3, %bb.nph15
   br i1 %4, label %bb1, label %bb3
 
 ; CHECK: LBB1_[[RET]]: @ %bb5
-; CHECK: ldmia sp!
+; CHECK: pop
 bb5:                                              ; preds = %bb3, %entry
   %sum.1.lcssa = phi i32 [ 0, %entry ], [ %sum.0.lcssa, %bb3 ] ; <i32> [#uses=1]
   ret i32 %sum.1.lcssa
index 75428ac2165510a9851d4928bc65bedadfb094c9..18f87bfc2e71c49ec4ffba21c72d295af3dd0ac9 100644 (file)
@@ -9,9 +9,9 @@ entry:
 ; CHECK: t:
 ; CHECK: vpop {d8}
 ; CHECK-NOT: vpopne
-; CHECK: ldmia sp!, {r7, pc}
+; CHECK: pop {r7, pc}
 ; CHECK: vpop {d8}
-; CHECK: ldmia sp!, {r7, pc}
+; CHECK: pop {r7, pc}
   br i1 undef, label %if.else, label %if.then
 
 if.then:                                          ; preds = %entry
index bca2ae346a6f19990e568740d84293142e3298bf..3615055f8b29123e345d691f68ec094d09dc480c 100644 (file)
@@ -11,7 +11,7 @@ entry:
 
 define i32 @t1(i32 %a, i32 %b) {
 ; CHECK: t1:
-; CHECK: ldmialt sp!, {r7, pc}
+; CHECK: poplt {r7, pc}
 entry:
        %tmp1 = icmp sgt i32 %a, 10             ; <i1> [#uses=1]
        br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
index 5edf32fd1af677601dab255631114b480f0f428c..232765768550f3a22d2c5a59fc3099e5000e666b 100644 (file)
@@ -3,7 +3,7 @@
 define void @foo(i32 %X, i32 %Y) {
 entry:
 ; CHECK: cmpne
-; CHECK: ldmiahi sp!
+; CHECK: pophi
        %tmp1 = icmp ult i32 %X, 4              ; <i1> [#uses=1]
        %tmp4 = icmp eq i32 %Y, 0               ; <i1> [#uses=1]
        %tmp7 = or i1 %tmp4, %tmp1              ; <i1> [#uses=1]
index 62e13557cfdc09670a9b98b1227568e1e67cc24b..476ed4d47c6481d8aa1fe1408bdd7ec1e5026dea 100644 (file)
@@ -6,7 +6,7 @@
 define fastcc i32 @CountTree(%struct.quad_struct* %tree) {
 ; CHECK: cmpeq
 ; CHECK: moveq
-; CHECK: ldmiaeq sp!
+; CHECK: popeq
 entry:
        br label %tailrecurse
 
index 5fdfc4ea6805912ef701e2d6b42e0aa700b870fa..ca9a5c63cda67c1af7f1c05df9f2218e2fe731ad 100644 (file)
@@ -5,7 +5,7 @@
 declare void @abort()
 
 define fastcc void @t(%struct.SString* %word, i8 signext  %c) {
-; CHECK: ldmiane sp!
+; CHECK: popne
 entry:
        %tmp1 = icmp eq %struct.SString* %word, null            ; <i1> [#uses=1]
        br i1 %tmp1, label %cond_true, label %cond_false
index 2f1b85ebbb043f64e57996b2fce89b983d79dcba..db78fd06ab2db1fcc360eb714ceb06618edd81e7 100644 (file)
@@ -5,9 +5,9 @@
 
 define i32 @t1() {
 ; CHECK: t1:
-; CHECK: ldmia
+; CHECK: pop
 ; V4T: t1:
-; V4T: ldmia
+; V4T: pop
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 0)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1)           ; <i32> [#uses=1]
         %tmp4 = tail call i32 @f1( i32 %tmp, i32 %tmp3 )                ; <i32> [#uses=1]
@@ -16,9 +16,9 @@ define i32 @t1() {
 
 define i32 @t2() {
 ; CHECK: t2:
-; CHECK: ldmia
+; CHECK: pop
 ; V4T: t2:
-; V4T: ldmia
+; V4T: pop
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3)           ; <i32> [#uses=1]
         %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 4)           ; <i32> [#uses=1]
@@ -29,7 +29,7 @@ define i32 @t2() {
 define i32 @t3() {
 ; CHECK: t3:
 ; CHECK: ldmib
-; CHECK: ldmia sp!
+; CHECK: pop
 ; V4T: t3:
 ; V4T: ldmib
 ; V4T: pop