summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/AsmParser
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2013-11-12 21:32:41 +0000
committerTim Northover <tnorthover@apple.com>2013-11-12 21:32:41 +0000
commit59e648e3c8966e0678902a2994558f25c8573ce4 (patch)
treef5ba89454cb1bd0e34536a5cb9a3d6f616f2d712 /lib/Target/ARM/AsmParser
parentd4765aa047c43dc0ce2c4a6a3ccdb91b8fa73c51 (diff)
downloadllvm-59e648e3c8966e0678902a2994558f25c8573ce4.tar.gz
llvm-59e648e3c8966e0678902a2994558f25c8573ce4.tar.bz2
llvm-59e648e3c8966e0678902a2994558f25c8573ce4.tar.xz
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
Diffstat (limited to 'lib/Target/ARM/AsmParser')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 727bd26369..e3f9e0dc60 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.