Index: lib/Target/ARM/Disassembler/ARMDisassembler.cpp =================================================================== --- lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -405,6 +405,28 @@ return new ThumbDisassembler(STI, Ctx); } +// Post-decoding checks +static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size, + uint64_t Address, raw_ostream &OS, + raw_ostream &CS, + uint32_t Insn, + DecodeStatus Result) +{ + switch (MI.getOpcode()) { + case ARM::HVC: { + // HVC is undefined if condition = 0xf otherwise upredictable + // if condition != 0xe + uint32_t Cond = (Insn >> 28) & 0xF; + if (Cond == 0xF) + return MCDisassembler::Fail; + if (Cond != 0xE) + return MCDisassembler::SoftFail; + return Result; + } + default: return Result; + } +} + DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ArrayRef Bytes, uint64_t Address, raw_ostream &OS, @@ -430,7 +452,7 @@ decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI); if (Result != MCDisassembler::Fail) { Size = 4; - return Result; + return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result); } // VFP and NEON instructions, similarly, are shared between ARM Index: test/MC/Disassembler/ARM/invalid-virtexts.arm.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/ARM/invalid-virtexts.arm.txt @@ -0,0 +1,10 @@ +# RUN: not llvm-mc -disassemble -triple armv7a -mcpu=cortex-a15 %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s + +# HVC (ARM) +[0x7f,0xff,0x4f,0xf1] +# CHECK-ARM: warning: invalid instruction encoding + +[0x70,0xff,0x4f,0x01] +[0x7f,0xff,0x4f,0xd1] +# CHECK-ARM: warning: potentially undefined instruction encoding +# CHECK-ARM: warning: potentially undefined instruction encoding