[clang] Add support for MS inp functions. (PR #93804)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 30 04:08:48 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Malay Sanghi (MalaySanghi)

<details>
<summary>Changes</summary>

support _inp, _inpw, _inpd, inp, inpw.
These functions were removed from the Windows runtime library, but aare still supported for kernel mode development.

---
Full diff: https://github.com/llvm/llvm-project/pull/93804.diff


2 Files Affected:

- (modified) clang/lib/Headers/intrin.h (+22) 
- (modified) clang/test/CodeGen/X86/ms-x86-intrinsics.c (+76) 


``````````diff
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 5ceb986a1f652..67a062d2166b0 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -329,6 +329,28 @@ static __inline__ void __DEFAULT_FN_ATTRS __stosq(unsigned __int64 *__dst,
 static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
   __asm__ volatile("hlt");
 }
+
+static inline int _inp(unsigned short port) {
+  int ret;
+  __asm__ volatile("inb %b1, %b0" : "=a"(ret) : "Nd"(port));
+  return ret;
+}
+
+static inline unsigned short _inpw(unsigned short port) {
+  unsigned short ret;
+  __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
+  return ret;
+}
+
+static inline unsigned long _inpd(unsigned short port) {
+  unsigned long ret;
+  __asm__ volatile("inb %k1, %b0" : "=a"(ret) : "Nd"(port));
+  return ret;
+}
+
+#define inp(port) _inp((port))
+#define inpw(port) _inpw((port))
+
 #endif
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
index aa557c8e19a83..c51f2d53ca771 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -63,6 +63,82 @@ unsigned __int64 test__emulu(unsigned int a, unsigned int b) {
 // CHECK: [[RES:%[0-9]+]] = mul nuw i64 [[Y]], [[X]]
 // CHECK: ret i64 [[RES]]
 
+
+int test_inp(unsigned short port) {
+  return _inp(port);
+}
+// CHECK-I386-LABEL: define dso_local i32 @test_inp(
+// CHECK-I386-SAME: i16 noundef zeroext [[PORT:%.*]])
+// CHECK-I386-NEXT:  entry:
+// CHECK-I386-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:b}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-I386-NEXT:    ret i32 [[TMP0]]
+//
+// CHECK-X64-LABEL: define dso_local i32 @test_inp(
+// CHECK-X64-SAME: i16 noundef [[PORT:%.*]])
+// CHECK-X64-NEXT:  entry:
+// CHECK-X64-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:b}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-X64-NEXT:    ret i32 [[TMP0]]
+
+unsigned short test_inpw(unsigned short port) {
+  return _inpw(port);
+}
+// CHECK-I386-LABEL: define dso_local zeroext i16 @test_inpw(
+// CHECK-I386-SAME: i16 noundef zeroext [[PORT:%.*]])
+// CHECK-I386-NEXT:  entry:
+// CHECK-I386-NEXT:    [[TMP0:%.*]] = tail call i16 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-I386-NEXT:    ret i16 [[TMP0]]
+//
+// CHECK-X64-LABEL: define dso_local i16 @test_inpw(
+// CHECK-X64-SAME: i16 noundef [[PORT:%.*]])
+// CHECK-X64-NEXT:  entry:
+// CHECK-X64-NEXT:    [[TMP0:%.*]] = tail call i16 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-X64-NEXT:    ret i16 [[TMP0]]
+
+unsigned long test_inpd(unsigned short port) {
+  return _inpd(port);
+}
+// CHECK-I386-LABEL: define dso_local i32 @test_inpd(
+// CHECK-I386-SAME: i16 noundef zeroext [[PORT:%.*]])
+// CHECK-I386-NEXT:  entry:
+// CHECK-I386-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:k}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-I386-NEXT:    ret i32 [[TMP0]]
+//
+// CHECK-X64-LABEL: define dso_local i32 @test_inpd(
+// CHECK-X64-SAME: i16 noundef [[PORT:%.*]])
+// CHECK-X64-NEXT:  entry:
+// CHECK-X64-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:k}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-X64-NEXT:    ret i32 [[TMP0]]
+
+int test_inp2(unsigned short port) {
+  return inp(port);
+}
+// CHECK-I386-LABEL: define dso_local i32 @test_inp2(
+// CHECK-I386-SAME: i16 noundef zeroext [[PORT:%.*]])
+// CHECK-I386-NEXT:  entry:
+// CHECK-I386-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:b}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-I386-NEXT:    ret i32 [[TMP0]]
+//
+// CHECK-X64-LABEL: define dso_local i32 @test_inp2(
+// CHECK-X64-SAME: i16 noundef [[PORT:%.*]])
+// CHECK-X64-NEXT:  entry:
+// CHECK-X64-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:b}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-X64-NEXT:    ret i32 [[TMP0]]
+
+unsigned short test_inpw2(unsigned short port) {
+  return inpw(port);
+}
+// CHECK-I386-LABEL: define dso_local zeroext i16 @test_inpw2(
+// CHECK-I386-SAME: i16 noundef zeroext [[PORT:%.*]])
+// CHECK-I386-NEXT:  entry:
+// CHECK-I386-NEXT:    [[TMP0:%.*]] = tail call i16 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-I386-NEXT:    ret i16 [[TMP0]]
+//
+// CHECK-X64-LABEL: define dso_local i16 @test_inpw2(
+// CHECK-X64-SAME: i16 noundef [[PORT:%.*]])
+// CHECK-X64-NEXT:  entry:
+// CHECK-X64-NEXT:    [[TMP0:%.*]] = tail call i16 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-X64-NEXT:    ret i16 [[TMP0]]
+
 #if defined(__x86_64__)
 
 char test__readgsbyte(unsigned long Offset) {

``````````

</details>


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


More information about the cfe-commits mailing list