diff options
author | Tim Northover <tnorthover@apple.com> | 2013-11-12 21:32:41 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2013-11-12 21:32:41 +0000 |
commit | 59e648e3c8966e0678902a2994558f25c8573ce4 (patch) | |
tree | f5ba89454cb1bd0e34536a5cb9a3d6f616f2d712 | |
parent | d4765aa047c43dc0ce2c4a6a3ccdb91b8fa73c51 (diff) | |
download | external_llvm-59e648e3c8966e0678902a2994558f25c8573ce4.zip external_llvm-59e648e3c8966e0678902a2994558f25c8573ce4.tar.gz external_llvm-59e648e3c8966e0678902a2994558f25c8573ce4.tar.bz2 |
ARM: diagnose invalid system LDM/STM
The system LDM and STM instructions can't usually writeback to the base
register. The one exception is when an LDM is actually an exception-return
(i.e. contains PC in the register list).
(There's already a test that "ldm sp!, {r0-r3, pc}^" works, which is why there
is no positive test).
rdar://problem/15223374
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194512 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 | ||||
-rw-r--r-- | test/MC/ARM/diagnostics.s | 5 |
2 files changed, 21 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 727bd26..e3f9e0d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5481,6 +5481,22 @@ validateInstruction(MCInst &Inst, "writeback register not allowed in register list"); break; } + case ARM::sysLDMIA_UPD: + case ARM::sysLDMDA_UPD: + case ARM::sysLDMDB_UPD: + case ARM::sysLDMIB_UPD: + if (!listContainsReg(Inst, 3, ARM::PC)) + return Error(Operands[4]->getStartLoc(), + "writeback register only allowed on system LDM " + "if PC in register-list"); + break; + case ARM::sysSTMIA_UPD: + case ARM::sysSTMDA_UPD: + case ARM::sysSTMDB_UPD: + case ARM::sysSTMIB_UPD: + return Error(Operands[2]->getStartLoc(), + "system STM cannot have writeback register"); + break; case ARM::tMUL: { // The second source operand must be the same register as the destination // operand. diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index 11c8306..3c26f6d 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -460,3 +460,8 @@ @ CHECK-ERRORS: error: instruction requires: FPARMv8 @ CHECK-ERRORS: error: instruction requires: FPARMv8 @ CHECK-ERRORS: error: instruction requires: FPARMv8 + + stm sp!, {r0, pc}^ + ldm sp!, {r0}^ +@ CHECK-ERRORS: error: system STM cannot have writeback register +@ CHECK-ERRORS: error: writeback register only allowed on system LDM if PC in register-list |