diff options
author | Craig Topper <craig.topper@gmail.com> | 2011-12-30 06:23:39 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2011-12-30 06:23:39 +0000 |
commit | 06f554d06ab0f9390d04bcbaabb76f572d940249 (patch) | |
tree | 57e6926f50790b141be81683d379a4429a7e64ae | |
parent | e6a3a2990e3f783c906e9db58e55439cb06f9fa5 (diff) | |
download | external_llvm-06f554d06ab0f9390d04bcbaabb76f572d940249.zip external_llvm-06f554d06ab0f9390d04bcbaabb76f572d940249.tar.gz external_llvm-06f554d06ab0f9390d04bcbaabb76f572d940249.tar.bz2 |
Add disassembler support for VPERMIL2PD and VPERMIL2PS.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147368 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrXOP.td | 6 | ||||
-rw-r--r-- | test/MC/Disassembler/X86/simple-tests.txt | 7 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 14 |
4 files changed, 26 insertions, 11 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index 1a24807..c915df0 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -1472,6 +1472,7 @@ static int readVVVV(struct InternalInstruction* insn) { static int readOperands(struct InternalInstruction* insn) { int index; int hasVVVV, needVVVV; + int sawRegImm = 0; dbgprintf(insn, "readOperands()"); @@ -1500,11 +1501,20 @@ static int readOperands(struct InternalInstruction* insn) { dbgprintf(insn, "We currently don't hande code-offset encodings"); return -1; case ENCODING_IB: + if (sawRegImm) { + // saw a register immediate so don't read again and instead split the previous immediate + // FIXME: This is a hack + insn->immediates[insn->numImmediatesConsumed++] = insn->immediates[insn->numImmediatesConsumed - 1] & 0xf; + break; + } if (readImmediate(insn, 1)) return -1; if (insn->spec->operands[index].type == TYPE_IMM3 && insn->immediates[insn->numImmediatesConsumed - 1] > 7) return -1; + if (insn->spec->operands[index].type == TYPE_XMM128 || + insn->spec->operands[index].type == TYPE_XMM256) + sawRegImm = 1; break; case ENCODING_IW: if (readImmediate(insn, 2)) diff --git a/lib/Target/X86/X86InstrXOP.td b/lib/Target/X86/X86InstrXOP.td index 9ab5a50..aef2c3a 100644 --- a/lib/Target/X86/X86InstrXOP.td +++ b/lib/Target/X86/X86InstrXOP.td @@ -237,7 +237,5 @@ multiclass xop5op<bits<8> opc, string OpcodeStr> { []>; } -let isAsmParserOnly = 1 in { - defm VPERMIL2PD : xop5op<0x49, "vpermil2pd">; - defm VPERMIL2PS : xop5op<0x48, "vpermil2ps">; -} +defm VPERMIL2PD : xop5op<0x49, "vpermil2pd">; +defm VPERMIL2PS : xop5op<0x48, "vpermil2ps">; diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 03d64f4..4f55068 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -684,8 +684,11 @@ # CHECK: vfmadd132sd (%rax), %xmm12, %xmm10 0xc4 0x62 0x99 0x99 0x10 -# CHEDCK: vfmaddss (%rcx), %xmm1, %xmm0, %xmm0 +# CHECK: vfmaddss (%rcx), %xmm1, %xmm0, %xmm0 0xc4 0xe3 0xf9 0x6a 0x01 0x10 -# CHEDCK: vfmaddss %xmm1, (%rcx), %xmm0, %xmm0 +# CHECK: vfmaddss %xmm1, (%rcx), %xmm0, %xmm0 0xc4 0xe3 0x79 0x6a 0x01 0x10 + +# CHECK: vpermil2ps $1, 4(%rax), %xmm2, %xmm3, %xmm0 +0xc4 0xe3 0xe1 0x48 0x40 0x04 0x21 diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index b8b282a..385e579 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -559,7 +559,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { bool hasFROperands = false; - assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); + assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) { if (OperandList[operandIndex].Constraints.size()) { @@ -678,7 +678,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { // Operand 3 (optional) is an immediate. if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) - assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); else assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && @@ -699,7 +699,9 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { if (HasVEX_4VOp3Prefix) HANDLE_OPERAND(vvvvRegister) - HANDLE_OPTIONAL(immediate) + if (!HasMemOp4Prefix) + HANDLE_OPTIONAL(immediate) + HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 break; case X86Local::MRMSrcMem: // Operand 1 is a register operand in the Reg/Opcode field. @@ -708,7 +710,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { // Operand 3 (optional) is an immediate. if (HasVEX_4VPrefix || HasVEX_4VOp3Prefix) - assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 && "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); else assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && @@ -729,7 +731,9 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { if (HasVEX_4VOp3Prefix) HANDLE_OPERAND(vvvvRegister) - HANDLE_OPTIONAL(immediate) + if (!HasMemOp4Prefix) + HANDLE_OPTIONAL(immediate) + HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 break; case X86Local::MRM0r: case X86Local::MRM1r: |