Properly pseudo-ize the ARM LDMIA_RET instruction. This has the nice side-

effect that we get proper instruction printing using the "pop" mnemonic for it.

llvm-svn: 127502
This commit is contained in:
Jim Grosbach 2011-03-11 22:51:41 +00:00
parent 4f8ccdf2f8
commit 6d371ce37e
13 changed files with 32 additions and 28 deletions

View 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:

View 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.

View 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

View 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:

View 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

View File

@ -24,7 +24,7 @@ bb1: ; preds = %bb, %entry
bb18: ; preds = %bb1
; CHECK-NOT: bx
; CHECK: ldmia sp!
; CHECK: pop
ret void
}

View 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

View 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

View 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

View 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]

View 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

View 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

View 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