From 8449c0d5ed1e1a9b723329e42873b96e935b4e7c Mon Sep 17 00:00:00 2001 From: Amaury de la Vieuville Date: Mon, 24 Jun 2013 09:15:01 +0000 Subject: [PATCH] ARM: check predicate bits for thumb instructions When encoded to thumb, VFP instruction and VMOV/VDUP between scalar and core registers, must have their predicate bit to 0b1110. llvm-svn: 184707 --- .../ARM/Disassembler/ARMDisassembler.cpp | 30 +++++++++++-------- .../Disassembler/ARM/invalid-NEON-thumb.txt | 9 ++++++ .../MC/Disassembler/ARM/invalid-VFP-thumb.txt | 9 ++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 llvm/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt create mode 100644 llvm/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 6aaf4c06b3c5..31941c10ea47 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -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/llvm/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt b/llvm/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt new file mode 100644 index 000000000000..a191d9e11853 --- /dev/null +++ b/llvm/test/MC/Disassembler/ARM/invalid-NEON-thumb.txt @@ -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/llvm/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt b/llvm/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt new file mode 100644 index 000000000000..7a4ddaa0a47c --- /dev/null +++ b/llvm/test/MC/Disassembler/ARM/invalid-VFP-thumb.txt @@ -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