diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index db58ea8fca2..3d9a1106a83 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -3163,7 +3163,7 @@ let hasSideEffects = 0 in { 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, diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index ecc7f0b1650..2cbc071f74e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -92,6 +92,38 @@ static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, 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" diff --git a/test/MC/ARM/arm-store-deprecated.s b/test/MC/ARM/arm-load-store-multiple-deprecated.s similarity index 61% rename from test/MC/ARM/arm-store-deprecated.s rename to test/MC/ARM/arm-load-store-multiple-deprecated.s index 8a598abc424..9354822bc41 100644 --- a/test/MC/ARM/arm-store-deprecated.s +++ b/test/MC/ARM/arm-load-store-multiple-deprecated.s @@ -1,6 +1,9 @@ -@ 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 @@ -145,9 +148,75 @@ push: @ CHECK: push {sp} @ CHECK: ^ - .global single - .type single,%function -single: - stmdaeq r0, {r0} -@ CHECK-NOT: warning + .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: stmdaeq r0, {r0} + ldmdaeq r0, {r0} +@ CHECK: ldmdaeq r0, {r0} + pop {r0, pc} +@ CHECK: pop {r0, pc}