forked from OSchip/llvm-project
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:
parent
4f8ccdf2f8
commit
6d371ce37e
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -24,7 +24,7 @@ bb1: ; preds = %bb, %entry
|
|||
|
||||
bb18: ; preds = %bb1
|
||||
; CHECK-NOT: bx
|
||||
; CHECK: ldmia sp!
|
||||
; CHECK: pop
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue