[clang] [X86] Add USER_MSR instructions. (PR #68944)

via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 12 18:12:28 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Freddy Ye (FreddyLeaf)

<details>
<summary>Changes</summary>

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


---

Patch is 29.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/68944.diff


35 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/include/clang/Basic/BuiltinsX86_64.def (+3) 
- (modified) clang/include/clang/Driver/Options.td (+2) 
- (modified) clang/lib/Basic/Targets/X86.cpp (+6) 
- (modified) clang/lib/Basic/Targets/X86.h (+1) 
- (modified) clang/lib/Headers/CMakeLists.txt (+1) 
- (added) clang/lib/Headers/usermsrintrin.h (+30) 
- (modified) clang/lib/Headers/x86gprintrin.h (+5) 
- (added) clang/test/CodeGen/X86/usermsr-builtins-error-32.c (+14) 
- (added) clang/test/CodeGen/X86/usermsr-builtins.c (+29) 
- (modified) clang/test/Driver/x86-target-features.c (+5) 
- (modified) clang/test/Preprocessor/x86_target_features.c (+6) 
- (modified) llvm/CMakeLists.txt (-2) 
- (modified) llvm/docs/ReleaseNotes.rst (+1) 
- (modified) llvm/include/llvm/IR/IntrinsicsX86.td (+9-1) 
- (modified) llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h (+4-1) 
- (modified) llvm/include/llvm/TargetParser/X86TargetParser.def (+1) 
- (modified) llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp (+9) 
- (modified) llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (+2-1) 
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (+2-1) 
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+4) 
- (modified) llvm/lib/Target/X86/X86.td (+2) 
- (modified) llvm/lib/Target/X86/X86InstrFormats.td (+4) 
- (modified) llvm/lib/Target/X86/X86InstrInfo.td (+1) 
- (modified) llvm/lib/Target/X86/X86InstrSystem.td (+16) 
- (modified) llvm/lib/TargetParser/Host.cpp (+1) 
- (modified) llvm/lib/TargetParser/X86TargetParser.cpp (+1) 
- (added) llvm/test/CodeGen/X86/usermsr-intrinsics.ll (+64) 
- (added) llvm/test/MC/Disassembler/X86/usermsr-64.txt (+26) 
- (added) llvm/test/MC/X86/usermsr-64-att.s (+18) 
- (added) llvm/test/MC/X86/usermsr-64-intel.s (+18) 
- (modified) llvm/utils/TableGen/X86DisassemblerTables.cpp (+1) 
- (modified) llvm/utils/TableGen/X86DisassemblerTables.h (+2-1) 
- (modified) llvm/utils/TableGen/X86RecognizableInstr.cpp (+1) 
- (modified) llvm/utils/TableGen/X86RecognizableInstr.h (+1-1) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 31969201a1cac8c..5300f8458760809 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -538,6 +538,9 @@ X86 Support
 
 - Added option ``-m[no-]evex512`` to disable ZMM and 64-bit mask instructions
   for AVX512 features.
+- Support ISA of ``USER_MSR``.
+  * Support intrinsic of ``_urdmsr``.
+  * Support intrinsic of ``_uwrmsr``.
 
 Arm and AArch64 Support
 ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def
index e5c1fe8b319217e..5e00916d4b25ae3 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.def
+++ b/clang/include/clang/Basic/BuiltinsX86_64.def
@@ -104,6 +104,9 @@ TARGET_BUILTIN(__builtin_ia32_clui, "v", "n", "uintr")
 TARGET_BUILTIN(__builtin_ia32_stui, "v", "n", "uintr")
 TARGET_BUILTIN(__builtin_ia32_testui, "Uc", "n", "uintr")
 TARGET_BUILTIN(__builtin_ia32_senduipi, "vUWi", "n", "uintr")
+// USERMSR
+TARGET_BUILTIN(__builtin_ia32_urdmsr, "ULLiULLi", "n", "usermsr")
+TARGET_BUILTIN(__builtin_ia32_uwrmsr, "vULLiULLi", "n", "usermsr")
 
 // AMX internal builtin
 TARGET_BUILTIN(__builtin_ia32_tile_loadconfig_internal, "vvC*", "n", "amx-tile")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3f2058a5d4650ca..f0ee6eba67374d8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5904,6 +5904,8 @@ def mtsxldtrk : Flag<["-"], "mtsxldtrk">, Group<m_x86_Features_Group>;
 def mno_tsxldtrk : Flag<["-"], "mno-tsxldtrk">, Group<m_x86_Features_Group>;
 def muintr : Flag<["-"], "muintr">, Group<m_x86_Features_Group>;
 def mno_uintr : Flag<["-"], "mno-uintr">, Group<m_x86_Features_Group>;
+def musermsr : Flag<["-"], "musermsr">, Group<m_x86_Features_Group>;
+def mno_usermsr : Flag<["-"], "mno-usermsr">, Group<m_x86_Features_Group>;
 def mvaes : Flag<["-"], "mvaes">, Group<m_x86_Features_Group>;
 def mno_vaes : Flag<["-"], "mno-vaes">, Group<m_x86_Features_Group>;
 def mvpclmulqdq : Flag<["-"], "mvpclmulqdq">, Group<m_x86_Features_Group>;
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 022d5753135e160..bea5c52a7b8d7c9 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -376,6 +376,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasTSXLDTRK = true;
     } else if (Feature == "+uintr") {
       HasUINTR = true;
+    } else if (Feature == "+usermsr") {
+      HasUSERMSR = true;
     } else if (Feature == "+crc32") {
       HasCRC32 = true;
     } else if (Feature == "+x87") {
@@ -869,6 +871,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
     Builder.defineMacro("__TSXLDTRK__");
   if (HasUINTR)
     Builder.defineMacro("__UINTR__");
+  if (HasUSERMSR)
+    Builder.defineMacro("__USERMSR__");
   if (HasCRC32)
     Builder.defineMacro("__CRC32__");
 
@@ -1053,6 +1057,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
       .Case("tbm", true)
       .Case("tsxldtrk", true)
       .Case("uintr", true)
+      .Case("usermsr", true)
       .Case("vaes", true)
       .Case("vpclmulqdq", true)
       .Case("wbnoinvd", true)
@@ -1162,6 +1167,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
       .Case("tbm", HasTBM)
       .Case("tsxldtrk", HasTSXLDTRK)
       .Case("uintr", HasUINTR)
+      .Case("usermsr", HasUSERMSR)
       .Case("vaes", HasVAES)
       .Case("vpclmulqdq", HasVPCLMULQDQ)
       .Case("wbnoinvd", HasWBNOINVD)
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 4fdc94de1e0cb4d..298db55c67442c9 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -162,6 +162,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
   bool HasAMXCOMPLEX = false;
   bool HasSERIALIZE = false;
   bool HasTSXLDTRK = false;
+  bool HasUSERMSR = false;
   bool HasUINTR = false;
   bool HasCRC32 = false;
   bool HasX87 = false;
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 8deea823e396694..3b6fec3da2b16ff 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -224,6 +224,7 @@ set(x86_files
   tmmintrin.h
   tsxldtrkintrin.h
   uintrintrin.h
+  usermsrintrin.h
   vaesintrin.h
   vpclmulqdqintrin.h
   waitpkgintrin.h
diff --git a/clang/lib/Headers/usermsrintrin.h b/clang/lib/Headers/usermsrintrin.h
new file mode 100644
index 000000000000000..6d1424ad3b2edd7
--- /dev/null
+++ b/clang/lib/Headers/usermsrintrin.h
@@ -0,0 +1,30 @@
+/*===--------------- usermsrintrin.h - USERMSR intrinsics -----------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+#ifndef __X86GPRINTRIN_H
+#error "Never use <usermsrintrin.h> directly; include <x86gprintrin.h> instead."
+#endif // __X86GPRINTRIN_H
+
+#ifndef __USERMSRINTRIN_H
+#define __USERMSRINTRIN_H
+#ifdef __x86_64__
+
+static __inline__ unsigned long long
+    __attribute__((__always_inline__, __nodebug__, __target__("usermsr")))
+    _urdmsr(unsigned long long __A) {
+  return __builtin_ia32_urdmsr(__A);
+}
+
+static __inline__ void
+    __attribute__((__always_inline__, __nodebug__, __target__("usermsr")))
+    _uwrmsr(unsigned long long __A, unsigned long long __B) {
+  return __builtin_ia32_uwrmsr(__A, __B);
+}
+
+#endif // __x86_64__
+#endif // __USERMSRINTRIN_H
diff --git a/clang/lib/Headers/x86gprintrin.h b/clang/lib/Headers/x86gprintrin.h
index f9a765be432219b..1bdaad7dba279f6 100644
--- a/clang/lib/Headers/x86gprintrin.h
+++ b/clang/lib/Headers/x86gprintrin.h
@@ -20,6 +20,11 @@
 #include <uintrintrin.h>
 #endif
 
+#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
+    defined(__UINTR__)
+#include <usermsrintrin.h>
+#endif
+
 #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
     defined(__CRC32__)
 #include <crc32intrin.h>
diff --git a/clang/test/CodeGen/X86/usermsr-builtins-error-32.c b/clang/test/CodeGen/X86/usermsr-builtins-error-32.c
new file mode 100644
index 000000000000000..5b3c8d00a46f68f
--- /dev/null
+++ b/clang/test/CodeGen/X86/usermsr-builtins-error-32.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -ffreestanding -triple=i386-unknown-unknown -target-feature +usermsr \
+// RUN: -emit-llvm -fsyntax-only -verify
+
+#include <immintrin.h>
+
+unsigned long long test_urdmsr(unsigned long long __A) {
+  return _urdmsr(__A); // expected-error {{call to undeclared function '_urdmsr'}}
+}
+
+void test_uwrmsr(unsigned long long __A, unsigned long long __B) {
+  // CHECK-LABEL: @test_uwrmsr(
+  // CHECK: call void @llvm.x86.uwrmsr(
+  _uwrmsr(__A, __B); // expected-error {{call to undeclared function '_uwrmsr'}}
+}
diff --git a/clang/test/CodeGen/X86/usermsr-builtins.c b/clang/test/CodeGen/X86/usermsr-builtins.c
new file mode 100644
index 000000000000000..4ca68f4f35f2ac0
--- /dev/null
+++ b/clang/test/CodeGen/X86/usermsr-builtins.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +usermsr \
+// RUN: -emit-llvm -o - -Wall -Werror -pedantic -Wno-gnu-statement-expression | FileCheck %s
+
+#include <immintrin.h>
+
+unsigned long long test_urdmsr(unsigned long long __A) {
+  // CHECK-LABEL: @test_urdmsr(
+  // CHECK: call i64 @llvm.x86.urdmsr(
+  return _urdmsr(__A);
+}
+
+unsigned long long test_urdmsr_const(unsigned long long __A) {
+  // CHECK-LABEL: @test_urdmsr_const(
+  // CHECK: call i64 @llvm.x86.urdmsr(
+  return _urdmsr(123u);
+}
+
+void test_uwrmsr(unsigned long long __A, unsigned long long __B) {
+  // CHECK-LABEL: @test_uwrmsr(
+  // CHECK: call void @llvm.x86.uwrmsr(
+  _uwrmsr(__A, __B);
+}
+
+void test_uwrmsr_const(unsigned long long __A, unsigned long long __B) {
+  // CHECK-LABEL: @test_uwrmsr_const(
+  // CHECK: call void @llvm.x86.uwrmsr(
+  _uwrmsr(123u, __B);
+}
+
diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c
index a6ecedbb8a58e7b..464dcda504bbdc3 100644
--- a/clang/test/Driver/x86-target-features.c
+++ b/clang/test/Driver/x86-target-features.c
@@ -374,6 +374,11 @@
 // EVEX512: "-target-feature" "+evex512"
 // NO-EVEX512: "-target-feature" "-evex512"
 
+// RUN: %clang --target=i386 -musermsr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=USERMSR %s
+// RUN: %clang --target=i386 -mno-usermsr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-USERMSR %s
+// USERMSR: "-target-feature" "+usermsr"
+// NO-USERMSR: "-target-feature" "-usermsr"
+
 // RUN: %clang --target=i386 -march=i386 -mcrc32 %s -### 2>&1 | FileCheck -check-prefix=CRC32 %s
 // RUN: %clang --target=i386 -march=i386 -mno-crc32 %s -### 2>&1 | FileCheck -check-prefix=NO-CRC32 %s
 // CRC32: "-target-feature" "+crc32"
diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c
index 36d4af59d4c66f6..873416d79b1255c 100644
--- a/clang/test/Preprocessor/x86_target_features.c
+++ b/clang/test/Preprocessor/x86_target_features.c
@@ -750,6 +750,12 @@
 // AVXVNNIINT16NOAVX2-NOT: #define __AVX2__ 1
 // AVXVNNIINT16NOAVX2-NOT: #define __AVXVNNIINT16__ 1
 
+// RUN: %clang -target i686-unknown-linux-gnu -march=atom -musermsr -x c -E -dM -o - %s | FileCheck  -check-prefix=USERMSR %s
+// USERMSR: #define __USERMSR__ 1
+
+// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mno-usermsr -x c -E -dM -o - %s | FileCheck  -check-prefix=NO-USERMSR %s
+// NO-USERMSR-NOT: #define __USERMSR__ 1
+
 // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mcrc32 -x c -E -dM -o - %s | FileCheck -check-prefix=CRC32 %s
 
 // CRC32: #define __CRC32__ 1
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 103c08ffbe83b38..364342f20cf8215 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -922,8 +922,6 @@ endif()
 
 include(HandleLLVMOptions)
 
-######
-
 # Configure all of the various header file fragments LLVM uses which depend on
 # configuration variables.
 set(LLVM_ENUM_TARGETS "")
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 3453c7e61ae4a63..3d11c43052f322d 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 57cd1dc47bd9fc9..fdc2b0fb7f80f12 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 169b8e97986e154..6e08fc6a0ccb650 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 85ff6996d335ae7..7505444313d4a01 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 49651da63ecf966..0678a5a11d9f730 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 95d3c8ede366f96..2d728143d3c9aa4 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 e2293fe30561fb4..1e5a3606f33a6fc 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 59a04f3167d863c..b85404be3063dae 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 64f91ae90e2b0ce..0b9a2e8acf9e10b 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 f45869e15267c89..70ffd4175e1f145 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 a20fa6a0c3b6c63..cb740bc99f7884c 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 0272f7de0f9e4b5..b55956169ff2cfe 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}...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/68944


More information about the cfe-commits mailing list