let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
defm LDM : arm_ldst_mult<"ldm", "", 1, 0, LdStMulFrm, IIC_iLoad_m,
- IIC_iLoad_mu>;
+ IIC_iLoad_mu>, ComplexDeprecationPredicate<"ARMLoad">;
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
defm STM : arm_ldst_mult<"stm", "", 0, 0, LdStMulFrm, IIC_iStore_m,
return false;
}
+static bool getARMLoadDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
+ std::string &Info) {
+ if (STI.getFeatureBits() & llvm::ARM::ModeThumb)
+ return false;
+
+ assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
+ bool ListContainsPC = false, ListContainsLR = false;
+ for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
+ assert(MI.getOperand(OI).isReg() && "expected register");
+ switch (MI.getOperand(OI).getReg()) {
+ default:
+ break;
+ case ARM::LR:
+ ListContainsLR = true;
+ break;
+ case ARM::PC:
+ ListContainsPC = true;
+ break;
+ case ARM::SP:
+ Info = "use of SP in the list is deprecated";
+ return true;
+ }
+ }
+
+ if (ListContainsPC && ListContainsLR) {
+ Info = "use of LR and PC simultaneously in the list is deprecated";
+ return true;
+ }
+
+ return false;
+}
+
#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"
-@ RUN: llvm-mc -triple armv7-linux-eabi -filetype asm -o /dev/null %s 2>&1 \
+@ RUN: llvm-mc -triple armv6t2-linux-eabi -filetype asm -o - %s 2>&1 \
@ RUN: | FileCheck %s
+@ RUN: not llvm-mc -triple armv7-linux-eabi -filetype asm -o - %s 2>&1 \
+@ RUN: | FileCheck %s -check-prefix CHECK -check-prefix CHECK-V7
+
.syntax unified
.arm
@ CHECK: push {sp}
@ CHECK: ^
- .global single
- .type single,%function
-single:
+ .global ldm
+ .type ldm,%function
+ldm:
+ ldm r0!, {r1, sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldm r0!, {sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldm r0!, {r1, lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+ ldm r0!, {lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+
+ .global ldmda
+ .type ldmda,%function
+ldmda:
+ ldmda r0!, {r1, sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmda r0!, {sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmda r0!, {r1, lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+ ldmda r0!, {lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+
+ .global ldmdb
+ .type ldmdb,%function
+ldmdb:
+ ldmdb r0!, {r1, sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmdb r0!, {sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmdb r0!, {r1, lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+ ldmdb r0!, {lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+
+ .global ldmib
+ .type ldmib,%function
+ldmib:
+ ldmib r0!, {r1, sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmib r0!, {sp}
+@ CHECK: warning: use of SP in the list is deprecated
+ ldmib r0!, {r1, lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+ ldmib r0!, {lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+
+ .global pop
+ .type pop,%function
+pop:
+ pop {r0, sp}
+@ CHECK: warning: use of SP in the list is deprecated
+@ CHECK-V7: error: writeback register not allowed in register list
+ pop {sp}
+@ CHECK: warning: use of SP in the list is deprecated
+@ CHECK-V7: error: writeback register not allowed in register list
+ pop {r0, lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+ pop {lr, pc}
+@ CHECK: warning: use of LR and PC simultaneously in the list is deprecated
+
+ .global valid
+ .type valid,%function
+valid:
stmdaeq r0, {r0}
-@ CHECK-NOT: warning
+@ CHECK: stmdaeq r0, {r0}
+ ldmdaeq r0, {r0}
+@ CHECK: ldmdaeq r0, {r0}
+ pop {r0, pc}
+@ CHECK: pop {r0, pc}