From 3daa5c29d444a759a0c60656d1aaf2579e5e447c Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 30 Aug 2011 07:09:35 +0000 Subject: [PATCH] Add vvvv support to disassembling of instructions with MRMDestMem and MRMDestReg form. Needed to support mem dest form of vmaskmovps/d. Fixes PR10807. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138795 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/MC/Disassembler/X86/simple-tests.txt | 3 +++ utils/TableGen/X86RecognizableInstr.cpp | 31 ++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index f1bdf145d77..ab4efe85ec9 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -96,3 +96,6 @@ # CHECK: vcvtsd2si %xmm0, %rax 0xc4 0xe1 0xfb 0x2d 0xc0 + +# CHECK: vmaskmovpd %xmm0, %xmm1, (%rax) +0xc4 0xe2 0x71 0x2f 0x00 diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 2604d42090a..1b37aa8fe84 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -623,20 +623,43 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { case X86Local::MRMDestReg: // Operand 1 is a register operand in the R/M field. // Operand 2 is a register operand in the Reg/Opcode field. + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMDestRegFrm"); + if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMDestRegFrm"); + HANDLE_OPERAND(rmRegister) + + if (HasVEX_4VPrefix) + // FIXME: In AVX, the register below becomes the one encoded + // in ModRMVEX and the one above the one in the VEX.VVVV field + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(roRegister) HANDLE_OPTIONAL(immediate) break; case X86Local::MRMDestMem: // Operand 1 is a memory operand (possibly SIB-extended) // Operand 2 is a register operand in the Reg/Opcode field. + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMDestMemFrm"); + if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMDestMemFrm"); HANDLE_OPERAND(memory) + + if (HasVEX_4VPrefix) + // FIXME: In AVX, the register below becomes the one encoded + // in ModRMVEX and the one above the one in the VEX.VVVV field + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(roRegister) HANDLE_OPTIONAL(immediate) break;