ARM: check predicate bits for thumb instructions
authorAmaury de la Vieuville <amaury.dlv@gmail.com>
Mon, 24 Jun 2013 09:15:01 +0000 (09:15 +0000)
committerAmaury de la Vieuville <amaury.dlv@gmail.com>
Mon, 24 Jun 2013 09:15:01 +0000 (09:15 +0000)
When encoded to thumb, VFP instruction and VMOV/VDUP between scalar and
core registers, must have their predicate bit to 0b1110.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184707 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/Disassembler/ARMDisassembler.cpp
test/MC/Disassembler/ARM/invalid-NEON-thumb.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/invalid-VFP-thumb.txt [new file with mode: 0644]

index 6aaf4c06b3c5e7fd942dad5793c08232af157cb6..31941c10ea47e2d84aa5f5d94a980dde27d665a3 100644 (file)
@@ -754,21 +754,25 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
     return result;
   }
 
-  MI.clear();
-  result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI);
-  if (result != MCDisassembler::Fail) {
-    Size = 4;
-    UpdateThumbVFPPredicate(MI);
-    return result;
+  if (fieldFromInstruction(insn32, 28, 4) == 0xE) {
+    MI.clear();
+    result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI);
+    if (result != MCDisassembler::Fail) {
+      Size = 4;
+      UpdateThumbVFPPredicate(MI);
+      return result;
+    }
   }
 
-  MI.clear();
-  result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address,
-                             this, STI);
-  if (result != MCDisassembler::Fail) {
-    Size = 4;
-    Check(result, AddThumbPredicate(MI));
-    return result;
+  if (fieldFromInstruction(insn32, 28, 4) == 0xE) {
+    MI.clear();
+    result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address,
+                               this, STI);
+    if (result != MCDisassembler::Fail) {
+      Size = 4;
+      Check(result, AddThumbPredicate(MI));
+      return result;
+    }
   }
 
   if (fieldFromInstruction(insn32, 24, 8) == 0xF9) {
diff --git a/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt b/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt
new file mode 100644 (file)
index 0000000..a191d9e
--- /dev/null
@@ -0,0 +1,9 @@
+# VMOV/VDUP between scalar and core registers with invalid predicate bits (pred != 0b1110)
+
+# VMOV
+# RUN: echo "0x00 0xde 0x10 0x0b" | llvm-mc -triple thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# VDUP
+# RUN: echo "0xff 0xde 0xf0 0xfb" | llvm-mc -triple thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# CHECK: invalid instruction encoding
diff --git a/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt b/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt
new file mode 100644 (file)
index 0000000..7a4ddaa
--- /dev/null
@@ -0,0 +1,9 @@
+# VFP instructions with invalid predicate bits (pred != 0b1110)
+
+# VABS
+# RUN: echo "0x40 0xde 0x00 0x0a" | llvm-mc -triple thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# VMLA
+# RUN: echo "0xf0 0xde 0xe0 0x0b" | llvm-mc -triple thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# CHECK: invalid instruction encoding