aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorFreddy Ye <freddy.ye@intel.com>2023-10-15 19:12:53 -0700
committerGitHub <noreply@github.com>2023-10-16 10:12:53 +0800
commit819ac45d1c1b7a2d784b2606c84de46ce714f278 (patch)
tree72851a651dade70a2f5be0c7c7934e3c5dbbade2 /llvm
parent993e839480449de63aefb1a1ae9142eefed5e7a6 (diff)
downloadllvm-819ac45d1c1b7a2d784b2606c84de46ce714f278.zip
llvm-819ac45d1c1b7a2d784b2606c84de46ce714f278.tar.gz
llvm-819ac45d1c1b7a2d784b2606c84de46ce714f278.tar.bz2
[X86] Add USER_MSR instructions. (#68944)
For more details about this instruction, please refer to the latest ISE document: https://www.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/ReleaseNotes.rst1
-rw-r--r--llvm/include/llvm/IR/IntrinsicsX86.td10
-rw-r--r--llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h5
-rw-r--r--llvm/include/llvm/TargetParser/X86TargetParser.def1
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp9
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h3
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h3
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp4
-rw-r--r--llvm/lib/Target/X86/X86.td2
-rw-r--r--llvm/lib/Target/X86/X86InstrFormats.td4
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td1
-rw-r--r--llvm/lib/Target/X86/X86InstrSystem.td16
-rw-r--r--llvm/lib/TargetParser/Host.cpp1
-rw-r--r--llvm/lib/TargetParser/X86TargetParser.cpp1
-rw-r--r--llvm/test/CodeGen/X86/usermsr-intrinsics.ll64
-rw-r--r--llvm/test/MC/Disassembler/X86/usermsr-64.txt28
-rw-r--r--llvm/test/MC/X86/usermsr-64-att.s18
-rw-r--r--llvm/test/MC/X86/usermsr-64-intel.s18
-rw-r--r--llvm/utils/TableGen/X86DisassemblerTables.cpp1
-rw-r--r--llvm/utils/TableGen/X86DisassemblerTables.h3
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.cpp1
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.h2
22 files changed, 190 insertions, 6 deletions
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 467b4b5..94b4380 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -133,6 +133,7 @@ Changes to the X86 Backend
benefits external projects such as Rust which aim to be binary compatible
with C, but also fixes code generation where LLVM already assumed that the
type matched and called into libgcc helper functions.
+* Support ISA of ``USER_MSR``.
Changes to the OCaml bindings
-----------------------------
diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td
index 57cd1dc..fdc2b0f 100644
--- a/llvm/include/llvm/IR/IntrinsicsX86.td
+++ b/llvm/include/llvm/IR/IntrinsicsX86.td
@@ -5673,8 +5673,16 @@ let TargetPrefix = "x86" in {
Intrinsic<[], [llvm_i64_ty], []>;
}
+let TargetPrefix = "x86" in {
+def int_x86_urdmsr : ClangBuiltin<"__builtin_ia32_urdmsr">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty],
+ [IntrInaccessibleMemOnly]>;
+def int_x86_uwrmsr : ClangBuiltin<"__builtin_ia32_uwrmsr">,
+ Intrinsic<[], [llvm_i64_ty, llvm_i64_ty],
+ [IntrInaccessibleMemOnly]>;
+}
+
//===----------------------------------------------------------------------===//
-// avx512_fp16: vaddph
let TargetPrefix = "x86" in {
def int_x86_avx512fp16_add_ph_512
: ClangBuiltin<"__builtin_ia32_addph512">,
diff --git a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
index 169b8e9..6e08fc6 100644
--- a/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
+++ b/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
@@ -33,6 +33,7 @@ namespace X86Disassembler {
#define THREEDNOW_MAP_SYM x86Disassembler3DNowOpcodes
#define MAP5_SYM x86DisassemblerMap5Opcodes
#define MAP6_SYM x86DisassemblerMap6Opcodes
+#define MAP7_SYM x86DisassemblerMap7Opcodes
#define INSTRUCTIONS_STR "x86DisassemblerInstrSpecifiers"
#define CONTEXTS_STR "x86DisassemblerContexts"
@@ -46,6 +47,7 @@ namespace X86Disassembler {
#define THREEDNOW_MAP_STR "x86Disassembler3DNowOpcodes"
#define MAP5_STR "x86DisassemblerMap5Opcodes"
#define MAP6_STR "x86DisassemblerMap6Opcodes"
+#define MAP7_STR "x86DisassemblerMap7Opcodes"
// Attributes of an instruction that must be known before the opcode can be
// processed correctly. Most of these indicate the presence of particular
@@ -296,7 +298,8 @@ enum OpcodeType {
XOPA_MAP = 6,
THREEDNOW_MAP = 7,
MAP5 = 8,
- MAP6 = 9
+ MAP6 = 9,
+ MAP7 = 10
};
// The following structs are used for the hierarchical decode table. After
diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def
index 85ff699..709ff86 100644
--- a/llvm/include/llvm/TargetParser/X86TargetParser.def
+++ b/llvm/include/llvm/TargetParser/X86TargetParser.def
@@ -241,6 +241,7 @@ X86_FEATURE (SM3, "sm3")
X86_FEATURE (SM4, "sm4")
X86_FEATURE (AVXVNNIINT16, "avxvnniint16")
X86_FEATURE (EVEX512, "evex512")
+X86_FEATURE (USERMSR, "usermsr")
// These features aren't really CPU features, but the frontend can set them.
X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk")
X86_FEATURE (RETPOLINE_INDIRECT_BRANCHES, "retpoline-indirect-branches")
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 967c757..2ec7a57 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -156,6 +156,9 @@ static InstrUID decode(OpcodeType type, InstructionContext insnContext,
case MAP6:
dec = &MAP6_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
break;
+ case MAP7:
+ dec = &MAP7_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
+ break;
}
switch (dec->modrm_type) {
@@ -918,6 +921,9 @@ static bool readOpcode(struct InternalInstruction *insn) {
case VEX_LOB_MAP6:
insn->opcodeType = MAP6;
return consume(insn, insn->opcode);
+ case VEX_LOB_MAP7:
+ insn->opcodeType = MAP7;
+ return consume(insn, insn->opcode);
}
} else if (insn->vectorExtensionType == TYPE_VEX_2B) {
insn->opcodeType = TWOBYTE;
@@ -1059,6 +1065,9 @@ static int getInstructionIDWithAttrMask(uint16_t *instructionID,
case MAP6:
decision = &MAP6_SYM;
break;
+ case MAP7:
+ decision = &MAP7_SYM;
+ break;
}
if (decision->opcodeDecisions[insnCtx]
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index 95d3c8e..2d72814 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -484,7 +484,8 @@ enum VEXLeadingOpcodeByte {
VEX_LOB_0F38 = 0x2,
VEX_LOB_0F3A = 0x3,
VEX_LOB_MAP5 = 0x5,
- VEX_LOB_MAP6 = 0x6
+ VEX_LOB_MAP6 = 0x6,
+ VEX_LOB_MAP7 = 0x7
};
enum XOPMapSelect {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index e2293fe..1e5a360 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -829,9 +829,10 @@ namespace X86II {
/// this flag to indicate that the encoder should do the wacky 3DNow! thing.
ThreeDNow = 7 << OpMapShift,
- // MAP5, MAP6 - Prefix after the 0x0F prefix.
+ // MAP5, MAP6, MAP7 - Prefix after the 0x0F prefix.
T_MAP5 = 8 << OpMapShift,
T_MAP6 = 9 << OpMapShift,
+ T_MAP7 = 10 << OpMapShift,
//===------------------------------------------------------------------===//
// REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 59a04f3..b85404b 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -89,6 +89,7 @@ class X86OpcodePrefixHelper {
// 0b00100: Reserved for future use
// 0b00101: VEX MAP5
// 0b00110: VEX MAP6
+ // 0b00111: VEX MAP7
// 0b00111-0b11111: Reserved for future use
// 0b01000: XOP map select - 08h instructions with imm byte
// 0b01001: XOP map select - 09h instructions with no imm byte
@@ -917,6 +918,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
case X86II::T_MAP6:
Prefix.set5M(0x6);
break;
+ case X86II::T_MAP7:
+ Prefix.set5M(0x7);
+ break;
}
Prefix.setL(TSFlags & X86II::VEX_L);
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 64f91ae..f3f8d57 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -325,6 +325,8 @@ def FeatureTSXLDTRK : SubtargetFeature<"tsxldtrk", "HasTSXLDTRK", "true",
"Support TSXLDTRK instructions">;
def FeatureUINTR : SubtargetFeature<"uintr", "HasUINTR", "true",
"Has UINTR Instructions">;
+def FeatureUSERMSR : SubtargetFeature<"usermsr", "HasUSERMSR", "true",
+ "Support USERMSR instructions">;
def FeaturePCONFIG : SubtargetFeature<"pconfig", "HasPCONFIG", "true",
"platform configuration instruction">;
def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true",
diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td
index f45869e..70ffd41 100644
--- a/llvm/lib/Target/X86/X86InstrFormats.td
+++ b/llvm/lib/Target/X86/X86InstrFormats.td
@@ -163,6 +163,7 @@ def XOPA : Map<6>;
def ThreeDNow : Map<7>;
def T_MAP5 : Map<8>;
def T_MAP6 : Map<9>;
+def T_MAP7 : Map<10>;
// Class specifying the encoding
class Encoding<bits<2> val> {
@@ -217,6 +218,9 @@ class T_MAP6PS : T_MAP6 { Prefix OpPrefix = PS; }
class T_MAP6PD : T_MAP6 { Prefix OpPrefix = PD; }
class T_MAP6XS : T_MAP6 { Prefix OpPrefix = XS; }
class T_MAP6XD : T_MAP6 { Prefix OpPrefix = XD; }
+class T_MAP7 { Map OpMap = T_MAP7; }
+class T_MAP7XS : T_MAP7 { Prefix OpPrefix = XS; } // 0xF3
+class T_MAP7XD : T_MAP7 { Prefix OpPrefix = XD; } // 0xF2
class OBXS { Prefix OpPrefix = XS; }
class PS : TB { Prefix OpPrefix = PS; }
class PD : TB { Prefix OpPrefix = PD; }
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index a20fa6a..cb740bc 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -1017,6 +1017,7 @@ def HasAMXBF16 : Predicate<"Subtarget->hasAMXBF16()">;
def HasAMXINT8 : Predicate<"Subtarget->hasAMXINT8()">;
def HasAMXCOMPLEX : Predicate<"Subtarget->hasAMXCOMPLEX()">;
def HasUINTR : Predicate<"Subtarget->hasUINTR()">;
+def HasUSERMSR : Predicate<"Subtarget->hasUSERMSR()">;
def HasCRC32 : Predicate<"Subtarget->hasCRC32()">;
def HasX86_64 : Predicate<"Subtarget->hasX86_64()">;
diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td
index 0272f7d..b559561 100644
--- a/llvm/lib/Target/X86/X86InstrSystem.td
+++ b/llvm/lib/Target/X86/X86InstrSystem.td
@@ -436,6 +436,22 @@ def WRMSRLIST : I<0x01, MRM_C6, (outs), (ins), "wrmsrlist", []>, XS;
def RDMSRLIST : I<0x01, MRM_C6, (outs), (ins), "rdmsrlist", []>, XD;
}
+let Predicates = [HasUSERMSR], mayLoad = 1 in {
+ def URDMSRrr : I<0xf8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
+ "urdmsr\t{$src, $dst|$dst, $src}",
+ [(set GR64:$dst, (int_x86_urdmsr GR64:$src))]>, T8XD;
+ def URDMSRri : Ii32<0xf8, MRM0r, (outs GR64:$dst), (ins i64i32imm:$imm),
+ "urdmsr\t{$imm, $dst|$dst, $imm}",
+ [(set GR64:$dst, (int_x86_urdmsr i64immSExt32_su:$imm))]>, T_MAP7XD, VEX;
+}
+let Predicates = [HasUSERMSR], mayStore = 1 in {
+ def UWRMSRrr : I<0xf8, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2),
+ "uwrmsr\t{$src1, $src2|$src2, $src1}",
+ [(int_x86_uwrmsr GR64:$src1, GR64:$src2)]>, T8XS;
+ def UWRMSRir : Ii32<0xf8, MRM0r, (outs), (ins GR64:$src, i64i32imm:$imm),
+ "uwrmsr\t{$src, $imm|$imm, $src}",
+ [(int_x86_uwrmsr GR64:$src, i64immSExt32_su:$imm)]>, T_MAP7XS, VEX;
+}
let Defs = [RAX, RDX], Uses = [ECX] in
def RDPMC : I<0x33, RawFrm, (outs), (ins), "rdpmc", []>, TB;
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 436a5eb..b320911 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1796,6 +1796,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
+ Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
bool HasLeafD = MaxLevel >= 0xd &&
!getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp
index b9908dd..94849f9 100644
--- a/llvm/lib/TargetParser/X86TargetParser.cpp
+++ b/llvm/lib/TargetParser/X86TargetParser.cpp
@@ -509,6 +509,7 @@ constexpr FeatureBitset ImpliedFeaturesSHSTK = {};
constexpr FeatureBitset ImpliedFeaturesTBM = {};
constexpr FeatureBitset ImpliedFeaturesTSXLDTRK = {};
constexpr FeatureBitset ImpliedFeaturesUINTR = {};
+constexpr FeatureBitset ImpliedFeaturesUSERMSR = {};
constexpr FeatureBitset ImpliedFeaturesWAITPKG = {};
constexpr FeatureBitset ImpliedFeaturesWBNOINVD = {};
constexpr FeatureBitset ImpliedFeaturesVZEROUPPER = {};
diff --git a/llvm/test/CodeGen/X86/usermsr-intrinsics.ll b/llvm/test/CodeGen/X86/usermsr-intrinsics.ll
new file mode 100644
index 0000000..29801a4
--- /dev/null
+++ b/llvm/test/CodeGen/X86/usermsr-intrinsics.ll
@@ -0,0 +1,64 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s -verify-machineinstrs -mtriple=x86_64-unknown-unknown --show-mc-encoding -mattr=+usermsr | FileCheck %s --check-prefixes=X64
+
+define i64 @test_int_x86_urdmsr(i64 %A) nounwind {
+; X64-LABEL: test_int_x86_urdmsr:
+; X64: # %bb.0:
+; X64-NEXT: urdmsr %rdi, %rax # encoding: [0xf2,0x0f,0x38,0xf8,0xc7]
+; X64-NEXT: retq # encoding: [0xc3]
+ %ret = call i64 @llvm.x86.urdmsr(i64 %A)
+ ret i64 %ret
+}
+
+define i64 @test_int_x86_urdmsr_const() nounwind {
+; X64-LABEL: test_int_x86_urdmsr_const:
+; X64: # %bb.0:
+; X64-NEXT: urdmsr $123, %rax # encoding: [0xc4,0xe7,0x7b,0xf8,0xc0,0x7b,0x00,0x00,0x00]
+; X64-NEXT: retq # encoding: [0xc3]
+ %ret = call i64 @llvm.x86.urdmsr(i64 123)
+ ret i64 %ret
+}
+
+define i64 @test_int_x86_urdmsr_const_i64() nounwind {
+; X64-LABEL: test_int_x86_urdmsr_const_i64:
+; X64: # %bb.0:
+; X64-NEXT: movabsq $8589934591, %rax # encoding: [0x48,0xb8,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00]
+; X64-NEXT: # imm = 0x1FFFFFFFF
+; X64-NEXT: urdmsr %rax, %rax # encoding: [0xf2,0x0f,0x38,0xf8,0xc0]
+; X64-NEXT: retq # encoding: [0xc3]
+ %ret = call i64 @llvm.x86.urdmsr(i64 8589934591)
+ ret i64 %ret
+}
+
+declare i64 @llvm.x86.urdmsr(i64 %A)
+
+define void @test_int_x86_uwrmsr(i64 %A, i64 %B) nounwind {
+; X64-LABEL: test_int_x86_uwrmsr:
+; X64: # %bb.0:
+; X64-NEXT: uwrmsr %rdi, %rsi # encoding: [0xf3,0x0f,0x38,0xf8,0xfe]
+; X64-NEXT: retq # encoding: [0xc3]
+ call void @llvm.x86.uwrmsr(i64 %A, i64 %B)
+ ret void
+}
+
+define void @test_int_x86_uwrmsr_const(i64 %A) nounwind {
+; X64-LABEL: test_int_x86_uwrmsr_const:
+; X64: # %bb.0:
+; X64-NEXT: uwrmsr %rdi, $123 # encoding: [0xc4,0xe7,0x7a,0xf8,0xc7,0x7b,0x00,0x00,0x00]
+; X64-NEXT: retq # encoding: [0xc3]
+ call void @llvm.x86.uwrmsr(i64 %A, i64 123)
+ ret void
+}
+
+define void @test_int_x86_uwrmsr_const_i64(i64 %A) nounwind {
+; X64-LABEL: test_int_x86_uwrmsr_const_i64:
+; X64: # %bb.0:
+; X64-NEXT: movabsq $8589934591, %rax # encoding: [0x48,0xb8,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00]
+; X64-NEXT: # imm = 0x1FFFFFFFF
+; X64-NEXT: uwrmsr %rdi, %rax # encoding: [0xf3,0x0f,0x38,0xf8,0xf8]
+; X64-NEXT: retq # encoding: [0xc3]
+ call void @llvm.x86.uwrmsr(i64 %A, i64 8589934591)
+ ret void
+}
+
+declare void @llvm.x86.uwrmsr(i64 %A, i64 %B)
diff --git a/llvm/test/MC/Disassembler/X86/usermsr-64.txt b/llvm/test/MC/Disassembler/X86/usermsr-64.txt
new file mode 100644
index 0000000..592a1a2
--- /dev/null
+++ b/llvm/test/MC/Disassembler/X86/usermsr-64.txt
@@ -0,0 +1,28 @@
+# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
+# RUN: llvm-mc --disassemble %s -triple=x86_64 --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL
+
+# ATT: urdmsr $123, %r9
+# INTEL: urdmsr r9, 123
+0xc4,0xc7,0x7b,0xf8,0xc1,0x7b,0x00,0x00,0x00
+
+# ATT: urdmsr %r9, %r9
+# INTEL: urdmsr r9, r9
+0xf2,0x45,0x0f,0x38,0xf8,0xc9
+
+# Test if WIG is supported for this instruction/form.
+# ATT: urdmsr %r9, %r9
+# INTEL: urdmsr r9, r9
+0xf2,0x4d,0x0f,0x38,0xf8,0xc9
+
+# ATT: uwrmsr %r9, $123
+# INTEL: uwrmsr 123, r9
+0xc4,0xc7,0x7a,0xf8,0xc1,0x7b,0x00,0x00,0x00
+
+# ATT: uwrmsr %r9, %r9
+# INTEL: uwrmsr r9, r9
+0xf3,0x45,0x0f,0x38,0xf8,0xc9
+
+# Test if WIG is supported for this instruction/form.
+# ATT: uwrmsr %r9, %r9
+# INTEL: uwrmsr r9, r9
+0xf3,0x4d,0x0f,0x38,0xf8,0xc9
diff --git a/llvm/test/MC/X86/usermsr-64-att.s b/llvm/test/MC/X86/usermsr-64-att.s
new file mode 100644
index 0000000..e89d0a80
--- /dev/null
+++ b/llvm/test/MC/X86/usermsr-64-att.s
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -triple x86_64 --show-encoding %s | FileCheck %s
+
+// CHECK: urdmsr $123, %r9
+// CHECK: encoding: [0xc4,0xc7,0x7b,0xf8,0xc1,0x7b,0x00,0x00,0x00]
+ urdmsr $123, %r9
+
+// CHECK: urdmsr %r9, %r9
+// CHECK: encoding: [0xf2,0x45,0x0f,0x38,0xf8,0xc9]
+ urdmsr %r9, %r9
+
+// CHECK: uwrmsr %r9, $123
+// CHECK: encoding: [0xc4,0xc7,0x7a,0xf8,0xc1,0x7b,0x00,0x00,0x00]
+ uwrmsr %r9, $123
+
+// CHECK: uwrmsr %r9, %r9
+// CHECK: encoding: [0xf3,0x45,0x0f,0x38,0xf8,0xc9]
+ uwrmsr %r9, %r9
+
diff --git a/llvm/test/MC/X86/usermsr-64-intel.s b/llvm/test/MC/X86/usermsr-64-intel.s
new file mode 100644
index 0000000..13d9161
--- /dev/null
+++ b/llvm/test/MC/X86/usermsr-64-intel.s
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -triple x86_64 -x86-asm-syntax=intel -output-asm-variant=1 --show-encoding %s | FileCheck %s
+
+// CHECK: urdmsr r9, 123
+// CHECK: encoding: [0xc4,0xc7,0x7b,0xf8,0xc1,0x7b,0x00,0x00,0x00]
+ urdmsr r9, 123
+
+// CHECK: urdmsr r9, r9
+// CHECK: encoding: [0xf2,0x45,0x0f,0x38,0xf8,0xc9]
+ urdmsr r9, r9
+
+// CHECK: uwrmsr 123, r9
+// CHECK: encoding: [0xc4,0xc7,0x7a,0xf8,0xc1,0x7b,0x00,0x00,0x00]
+ uwrmsr 123, r9
+
+// CHECK: uwrmsr r9, r9
+// CHECK: encoding: [0xf3,0x45,0x0f,0x38,0xf8,0xc9]
+ uwrmsr r9, r9
+
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp
index 708c92a..ba51bf4 100644
--- a/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -982,6 +982,7 @@ void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[7], THREEDNOW_MAP_STR);
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[8], MAP5_STR);
emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[9], MAP6_STR);
+ emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[10], MAP7_STR);
}
void DisassemblerTables::emit(raw_ostream &o) const {
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.h b/llvm/utils/TableGen/X86DisassemblerTables.h
index 966f740..4b6f654 100644
--- a/llvm/utils/TableGen/X86DisassemblerTables.h
+++ b/llvm/utils/TableGen/X86DisassemblerTables.h
@@ -46,7 +46,8 @@ private:
/// [7] 3dnow map opcode
/// [8] fixed length MAP5 opcode
/// [9] fixed length MAP6 opcode
- std::unique_ptr<ContextDecision> Tables[10];
+ /// [10] fixed length MAP7 opcode
+ std::unique_ptr<ContextDecision> Tables[11];
// Table of ModRM encodings.
typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index b2f51ba..962da62 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -791,6 +791,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::ThreeDNow: opcodeType = THREEDNOW_MAP; break;
case X86Local::T_MAP5: opcodeType = MAP5; break;
case X86Local::T_MAP6: opcodeType = MAP6; break;
+ case X86Local::T_MAP7: opcodeType = MAP7; break;
}
std::unique_ptr<ModRMFilter> filter;
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h
index 5efacdb..38bca87 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -137,7 +137,7 @@ namespace X86Local {
enum {
OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6, ThreeDNow = 7,
- T_MAP5 = 8, T_MAP6 = 9
+ T_MAP5 = 8, T_MAP6 = 9, T_MAP7 = 10
};
enum {