Index: ../llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- ../llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ ../llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -190,7 +190,7 @@ } bool validatetLDMRegList(MCInst Inst, const OperandVector &Operands, - unsigned ListNo, bool IsPop = false); + unsigned ListNo, bool IsARPop = false); bool validatetSTMRegList(MCInst Inst, const OperandVector &Operands, unsigned ListNo); @@ -6021,7 +6021,7 @@ bool ARMAsmParser::validatetLDMRegList(MCInst Inst, const OperandVector &Operands, - unsigned ListNo, bool IsPop) { + unsigned ListNo, bool IsARPop) { const ARMOperand &Op = static_cast(*Operands[ListNo]); bool HasWritebackToken = Op.isToken() && Op.getToken() == "!"; @@ -6029,7 +6029,7 @@ bool ListContainsLR = listContainsReg(Inst, ListNo, ARM::LR); bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC); - if (!IsPop && ListContainsSP) + if (!IsARPop && ListContainsSP) return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), "SP may not be in the register list"); else if (ListContainsPC && ListContainsLR) @@ -6327,12 +6327,13 @@ // so only issue a diagnostic for thumb1. The instructions will be // switched to the t2 encodings in processInstruction() if necessary. case ARM::tPOP: { - bool ListContainsBase; + bool ListContainsBase, IsARPop; if (checkLowRegisterList(Inst, 2, 0, ARM::PC, ListContainsBase) && !isThumbTwo()) return Error(Operands[2]->getStartLoc(), "registers must be in range r0-r7 or pc"); - if (validatetLDMRegList(Inst, Operands, 2, /*IsPop=*/true)) + IsARPop = !isMClass(); + if (validatetLDMRegList(Inst, Operands, 2, IsARPop)) return true; break; } Index: ../llvm/test/MC/ARM/thumb-load-store-multiple.s =================================================================== --- ../llvm/test/MC/ARM/thumb-load-store-multiple.s +++ ../llvm/test/MC/ARM/thumb-load-store-multiple.s @@ -1,5 +1,7 @@ -@ RUN: not llvm-mc -triple thumbv7-eabi -filetype asm -o - %s 2>&1 \ +@ RUN: not llvm-mc -triple thumbv7a-eabi -filetype asm -o - %s 2>&1 \ @ RUN: | FileCheck %s +@ RUN: not llvm-mc -triple thumbv7m-eabi -filetype asm -o - %s 2>&1 \ +@ RUN: | FileCheck --check-prefix=CHECK-V7M %s .syntax unified .thumb @@ -6,15 +8,23 @@ .global ldm .type ldm,%function -ldb: +ldm: ldm r0!, {r1, sp} @ CHECK: error: SP may not be in the register list @ CHECK: ldm r0!, {r1, sp} @ CHECK: ^ +@ CHECK-V7M: error: SP may not be in the register list +@ CHECK-V7M: ldm r0!, {r1, sp} +@ CHECK-V7M: ^ + ldm r0!, {lr, pc} @ CHECK: error: PC and LR may not be in the register list simultaneously @ CHECK: ldm r0!, {lr, pc} @ CHECK: ^ +@ CHECK-V7M: error: PC and LR may not be in the register list simultaneously +@ CHECK-V7M: ldm r0!, {lr, pc} +@ CHECK-V7M: ^ + itt eq ldmeq r0!, {r1, pc} ldmeq r0!, {r2, lr} @@ -21,6 +31,9 @@ @ CHECK: error: instruction must be outside of IT block or the last instruction in an IT block @ CHECK: ldmeq r0!, {r1, pc} @ CHECK: ^ +@ CHECK-V7M: error: instruction must be outside of IT block or the last instruction in an IT block +@ CHECK-V7M: ldmeq r0!, {r1, pc} +@ CHECK-V7M: ^ .global ldmdb .type ldmdb,%function @@ -27,8 +40,20 @@ ldmdb: ldmdb r0!, {r1, sp} @ CHECK: error: SP may not be in the register list - ldm r0!, {lr, pc} -@ error: PC and LR may not be in the register list simultaneously +@ CHECK: ldmdb r0!, {r1, sp} +@ CHECK: ^ +@ CHECK-V7M: error: SP may not be in the register list +@ CHECK-V7M: ldmdb r0!, {r1, sp} +@ CHECK-V7M: ^ + + ldmdb r0!, {lr, pc} +@ CHECK: error: PC and LR may not be in the register list simultaneously +@ CHECK: ldmdb r0!, {lr, pc} +@ CHECK: ^ +@ CHECK-V7M: error: PC and LR may not be in the register list simultaneously +@ CHECK-V7M: ldmdb r0!, {lr, pc} +@ CHECK-V7M: ^ + itt eq ldmeq r0!, {r1, pc} ldmeq r0!, {r2, lr} @@ -35,6 +60,9 @@ @ CHECK: error: instruction must be outside of IT block or the last instruction in an IT block @ CHECK: ldmeq r0!, {r1, pc} @ CHECK: ^ +@ CHECK-V7M: error: instruction must be outside of IT block or the last instruction in an IT block +@ CHECK-V7M: ldmeq r0!, {r1, pc} +@ CHECK-V7M: ^ .global stm .type stm,%function @@ -41,10 +69,13 @@ stm: stm r0!, {r1, sp} @ CHECK: error: SP may not be in the register list +@ CHECK-V7M: error: SP may not be in the register list stm r0!, {r2, pc} @ CHECK: error: PC may not be in the register list +@ CHECK-V7M: error: PC may not be in the register list stm r0!, {sp, pc} @ CHECK: error: SP and PC may not be in the register list +@ CHECK-V7M: error: SP and PC may not be in the register list .global stmdb .type stmdb,%function @@ -51,10 +82,13 @@ stmdb: stmdb r0!, {r1, sp} @ CHECK: error: SP may not be in the register list +@ CHECK-V7M: error: SP may not be in the register list stmdb r0!, {r2, pc} @ CHECK: error: PC may not be in the register list +@ CHECK-V7M: error: PC may not be in the register list stmdb r0!, {sp, pc} @ CHECK: error: SP and PC may not be in the register list +@ CHECK-V7M: error: SP and PC may not be in the register list .global push .type push,%function @@ -61,18 +95,29 @@ push: push {sp} @ CHECK: error: SP may not be in the register list +@ CHECK-V7M: error: SP may not be in the register list push {pc} @ CHECK: error: PC may not be in the register list +@ CHECK-V7M: error: PC may not be in the register list push {sp,pc} @ CHECK: error: SP and PC may not be in the register list +@ CHECK-V7M: error: SP and PC may not be in the register list .global pop .type pop,%function pop: + pop {sp} +@ CHECK-V7M: error: SP may not be in the register list +@ CHECK-V7M: pop {sp} +@ CHECK-V7M: ^ pop {lr, pc} @ CHECK: error: PC and LR may not be in the register list simultaneously @ CHECK: pop {lr, pc} @ CHECK: ^ +@ CHECK-V7M: error: PC and LR may not be in the register list simultaneously +@ CHECK-V7M: pop {lr, pc} +@ CHECK-V7M: ^ + itt eq popeq {r1, pc} popeq {r2, lr} @@ -79,6 +124,9 @@ @ CHECK: error: instruction must be outside of IT block or the last instruction in an IT block @ CHECK: popeq {r1, pc} @ CHECK: ^ +@ CHECK-V7M: error: instruction must be outside of IT block or the last instruction in an IT block +@ CHECK-V7M: popeq {r1, pc} +@ CHECK-V7M: ^ .global valid .type valid,%function