From b46f844518de7b6acd232699c2df02e1a56e8957 Mon Sep 17 00:00:00 2001 From: Elena Demikhovsky Date: Tue, 9 Jun 2015 13:02:10 +0000 Subject: [PATCH] X86-MPX: Implemented encoding for MPX instructions. Added encoding tests. llvm-svn: 239403 --- .../X86/Disassembler/X86Disassembler.cpp | 3 + .../X86DisassemblerDecoderCommon.h | 1 + lib/Target/X86/X86InstrInfo.td | 3 + lib/Target/X86/X86InstrMPX.td | 70 +++++++++++++++++++ lib/Target/X86/X86RegisterInfo.td | 6 +- test/MC/X86/mpx-encodings.s | 38 ++++++++++ utils/TableGen/X86RecognizableInstr.cpp | 3 + 7 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 lib/Target/X86/X86InstrMPX.td create mode 100644 test/MC/X86/mpx-encodings.s diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index 3469d19f4fd..6e99c37c2bc 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -546,6 +546,8 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, case TYPE_XMM512: mcInst.addOperand(MCOperand::createReg(X86::ZMM0 + (immediate >> 4))); return; + case TYPE_BNDR: + mcInst.addOperand(MCOperand::createReg(X86::BND0 + (immediate >> 4))); case TYPE_REL8: isBranch = true; pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize; @@ -827,6 +829,7 @@ static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand, case TYPE_VK16: case TYPE_DEBUGREG: case TYPE_CONTROLREG: + case TYPE_BNDR: return translateRMRegister(mcInst, insn); case TYPE_M: case TYPE_M8: diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index 9e650500139..301db72feaf 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -460,6 +460,7 @@ enum OperandEncoding { ENUM_ENTRY(TYPE_SEGMENTREG, "Segment register operand") \ ENUM_ENTRY(TYPE_DEBUGREG, "Debug register operand") \ ENUM_ENTRY(TYPE_CONTROLREG, "Control register operand") \ + ENUM_ENTRY(TYPE_BNDR, "MPX bounds register") \ \ ENUM_ENTRY(TYPE_Mv, "Memory operand of operand size") \ ENUM_ENTRY(TYPE_Rv, "Register operand of operand size") \ diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 5fc92e85112..e936b4bc466 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -2457,6 +2457,9 @@ include "X86InstrAVX512.td" include "X86InstrMMX.td" include "X86Instr3DNow.td" +// MPX instructions +include "X86InstrMPX.td" + include "X86InstrVMX.td" include "X86InstrSVM.td" diff --git a/lib/Target/X86/X86InstrMPX.td b/lib/Target/X86/X86InstrMPX.td new file mode 100644 index 00000000000..cf5e2e38fe5 --- /dev/null +++ b/lib/Target/X86/X86InstrMPX.td @@ -0,0 +1,70 @@ +//===-- X86InstrMPX.td - MPX Instruction Set ---------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the X86 MPX instruction set, defining the +// instructions, and properties of the instructions which are needed for code +// generation, machine code emission, and analysis. +// +//===----------------------------------------------------------------------===// + +multiclass mpx_bound_make opc, string OpcodeStr> { + def 32rm: I, + Requires<[HasMPX, Not64BitMode]>; + def 64rm: RI, + Requires<[HasMPX, In64BitMode]>; +} + +defm BNDMK : mpx_bound_make<0x1B, "bndmk">, XS; + +multiclass mpx_bound_check opc, string OpcodeStr> { + def 32rm: I, + Requires<[HasMPX, Not64BitMode]>; + def 64rm: RI, + Requires<[HasMPX, In64BitMode]>; + def 32rr: I, + Requires<[HasMPX, Not64BitMode]>; + def 64rr: RI, + Requires<[HasMPX, In64BitMode]>; +} +defm BNDCL : mpx_bound_check<0x1A, "bndcl">, XS; +defm BNDCU : mpx_bound_check<0x1A, "bndcu">, XD; +defm BNDCN : mpx_bound_check<0x1B, "bndcn">, XD; + +def BNDMOVRMrr : I<0x1A, MRMSrcReg, (outs BNDR:$dst), (ins BNDR:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX]>; +def BNDMOVRM32rm : I<0x1A, MRMSrcMem, (outs BNDR:$dst), (ins i64mem:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX, Not64BitMode]>; +def BNDMOVRM64rm : RI<0x1A, MRMSrcMem, (outs BNDR:$dst), (ins i128mem:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX, In64BitMode]>; + +def BNDMOVMRrr : I<0x1B, MRMDestReg, (outs BNDR:$dst), (ins BNDR:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX]>; +def BNDMOVMR32mr : I<0x1B, MRMDestMem, (outs i64mem:$dst), (ins BNDR:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX, Not64BitMode]>; +def BNDMOVMR64mr : RI<0x1B, MRMDestMem, (outs i128mem:$dst), (ins BNDR:$src), + "bndmov \t{$src, $dst|$dst, $src}", []>, PD, + Requires<[HasMPX, In64BitMode]>; + +def BNDSTXmr: I<0x1B, MRMDestMem, (outs), (ins i64mem:$dst, BNDR:$src), + "bndstx \t{$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMPX]>; +def BNDLDXrm: I<0x1A, MRMSrcMem, (outs BNDR:$dst), (ins i64mem:$src), + "bndldx \t{$src, $dst|$dst, $src}", []>, TB, + Requires<[HasMPX]>; \ No newline at end of file diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index d2ea5a4f13b..cdb151c26a0 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -304,9 +304,9 @@ def RIZ : X86Reg<"riz", 4>; // Bound registers, used in MPX instructions def BND0 : X86Reg<"bnd0", 0>; -def BND1 : X86Reg<"bnd1", 0>; -def BND2 : X86Reg<"bnd2", 0>; -def BND3 : X86Reg<"bnd3", 0>; +def BND1 : X86Reg<"bnd1", 1>; +def BND2 : X86Reg<"bnd2", 2>; +def BND3 : X86Reg<"bnd3", 3>; //===----------------------------------------------------------------------===// // Register Class Definitions... now that we have all of the pieces, define the diff --git a/test/MC/X86/mpx-encodings.s b/test/MC/X86/mpx-encodings.s new file mode 100644 index 00000000000..6fe4e0f328e --- /dev/null +++ b/test/MC/X86/mpx-encodings.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple x86_64-unknown-unknown -mcpu=knl --show-encoding %s | FileCheck %s + +// CHECK: bndmk (%rax), %bnd0 +// CHECK: encoding: [0xf3,0x48,0x0f,0x1b,0x00] +bndmk (%rax), %bnd0 + +// CHECK: bndmk 1024(%rax), %bnd1 +// CHECK: encoding: [0xf3,0x48,0x0f,0x1b,0x88,0x00,0x04,0x00,0x00] +bndmk 1024(%rax), %bnd1 + +// CHECK: bndmov %bnd2, %bnd1 +// CHECK: encoding: [0x66,0x0f,0x1b,0xd1] +bndmov %bnd2, %bnd1 + +// CHECK: bndmov %bnd1, 1024(%r9) +// CHECK: encoding: [0x66,0x49,0x0f,0x1b,0x89,0x00,0x04,0x00,0x00] +bndmov %bnd1, 1024(%r9) + +// CHECK: bndstx %bnd1, 1024(%rax) +// CHECK: encoding: [0x0f,0x1b,0x88,0x00,0x04,0x00,0x00] +bndstx %bnd1, 1024(%rax) + +// CHECK: bndldx 1024(%r8), %bnd1 +// CHECK: encoding: [0x41,0x0f,0x1a,0x88,0x00,0x04,0x00,0x00] +bndldx 1024(%r8), %bnd1 + +// CHECK: bndcl 121(%r10), %bnd1 +// CHECK: encoding: [0xf3,0x49,0x0f,0x1a,0x4a,0x79] +bndcl 121(%r10), %bnd1 + +// CHECK: bndcn 121(%rcx), %bnd3 +// CHECK: encoding: [0xf2,0x48,0x0f,0x1b,0x59,0x79] +bndcn 121(%rcx), %bnd3 + +// CHECK: bndcu %rdx, %bnd3 +// CHECK: encoding: [0xf2,0x48,0x0f,0x1a,0xda] +bndcu %rdx, %bnd3 + diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index ae461bcfbc8..dde21c6d45f 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -1033,6 +1033,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("vy64mem", TYPE_M64) TYPE("vy64xmem", TYPE_M64) TYPE("vz64mem", TYPE_M64) + TYPE("BNDR", TYPE_BNDR) errs() << "Unhandled type string " << s << "\n"; llvm_unreachable("Unhandled type string"); } @@ -1102,6 +1103,7 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s, ENCODING("VK16", ENCODING_RM) ENCODING("VK32", ENCODING_RM) ENCODING("VK64", ENCODING_RM) + ENCODING("BNDR", ENCODING_RM) errs() << "Unhandled R/M register encoding " << s << "\n"; llvm_unreachable("Unhandled R/M register encoding"); } @@ -1141,6 +1143,7 @@ RecognizableInstr::roRegisterEncodingFromString(const std::string &s, ENCODING("VK16WM", ENCODING_REG) ENCODING("VK32WM", ENCODING_REG) ENCODING("VK64WM", ENCODING_REG) + ENCODING("BNDR", ENCODING_REG) errs() << "Unhandled reg/opcode register encoding " << s << "\n"; llvm_unreachable("Unhandled reg/opcode register encoding"); }