[clang] 3482403 - [X86]Add support for __outbyte/word/dword and __inbyte/word/dword (#93774)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 20 22:09:52 PDT 2024


Author: Malay Sanghi
Date: 2024-06-21T13:09:47+08:00
New Revision: 348240362f9673c824c0ad22fd9e13ae3f937864

URL: https://github.com/llvm/llvm-project/commit/348240362f9673c824c0ad22fd9e13ae3f937864
DIFF: https://github.com/llvm/llvm-project/commit/348240362f9673c824c0ad22fd9e13ae3f937864.diff

LOG: [X86]Add support for __outbyte/word/dword and __inbyte/word/dword (#93774)

A previous commit implemented _inp/w/d and renaming that to
__inbyte/word/dword

These intrinsics were declared in the header but never implemented.

Added: 
    

Modified: 
    clang/lib/Headers/intrin.h
    clang/test/CodeGen/X86/ms-x86-intrinsics.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 1227f45d5432b..d2250926ce5e1 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -330,24 +330,35 @@ static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
   __asm__ volatile("hlt");
 }
 
-static inline int _inp(unsigned short port) {
-  int ret;
-  __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
+static inline unsigned char __inbyte(unsigned short port) {
+  unsigned char ret;
+  __asm__ __volatile__("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
   return ret;
 }
 
-static inline unsigned short _inpw(unsigned short port) {
+static inline unsigned short __inword(unsigned short port) {
   unsigned short ret;
-  __asm__ volatile("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
+  __asm__ __volatile__("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
   return ret;
 }
 
-static inline unsigned long _inpd(unsigned short port) {
+static inline unsigned long __indword(unsigned short port) {
   unsigned long ret;
-  __asm__ volatile("inl %w1, %k0" : "=a"(ret) : "Nd"(port));
+  __asm__ __volatile__("inl %w1, %k0" : "=a"(ret) : "Nd"(port));
   return ret;
 }
 
+static inline void __outbyte(unsigned short port, unsigned char data) {
+  __asm__ __volatile__("outb %b0, %w1" : : "a"(data), "Nd"(port));
+}
+
+static inline void __outword(unsigned short port, unsigned short data) {
+  __asm__ __volatile__("outw %w0, %w1" : : "a"(data), "Nd"(port));
+}
+
+static inline void __outdword(unsigned short port, unsigned long data) {
+  __asm__ __volatile__("outl %k0, %w1" : : "a"(data), "Nd"(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 9566951b44d2d..b90e2679e26d2 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -64,30 +64,54 @@ unsigned __int64 test__emulu(unsigned int a, unsigned int b) {
 // CHECK: ret i64 [[RES]]
 
 
-int test_inp(unsigned short port) {
-  return _inp(port);
+unsigned char test_inbyte(unsigned short port) {
+  return __inbyte(port);
 }
-// CHECK-LABEL: i32 @test_inp(i16 noundef
+// CHECK-LABEL: i8 @test_inbyte(i16 noundef
 // CHECK-SAME:  [[PORT:%.*]])
-// CHECK:       [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
-// CHECK-NEXT:  ret i32 [[TMP0]]
+// CHECK:       [[TMP0:%.*]] = tail call i8 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
+// CHECK-NEXT:  ret i8 [[TMP0]]
 
-unsigned short test_inpw(unsigned short port) {
-  return _inpw(port);
+unsigned short test_inword(unsigned short port) {
+  return __inword(port);
 }
-// CHECK-LABEL: i16 @test_inpw(i16 noundef
+// CHECK-LABEL: i16 @test_inword(i16 noundef
 // CHECK-SAME:  [[PORT:%.*]])
 // CHECK:       [[TMP0:%.*]] = tail call i16 asm sideeffect "inw ${1:w}, ${0:w}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
 // CHECK-NEXT:  ret i16 [[TMP0]]
 
-unsigned long test_inpd(unsigned short port) {
-  return _inpd(port);
+unsigned long test_indword(unsigned short port) {
+  return __indword(port);
 }
-// CHECK-LABEL: i32 @test_inpd(i16 noundef
+// CHECK-LABEL: i32 @test_indword(i16 noundef
 // CHECK-SAME:  [[PORT:%.*]])
 // CHECK:       [[TMP0:%.*]] = tail call i32 asm sideeffect "inl ${1:w}, ${0:k}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
 // CHECK-NEXT:  ret i32 [[TMP0]]
 
+void test_outbyte(unsigned short port, unsigned char data) {
+    return __outbyte(port, data);
+}
+// CHECK-LABEL: void @test_outbyte(
+// CHECK-SAME:  [[PORT:%.*]],
+// CHECK-SAME:  [[DATA:%.*]])
+// CHECK:       tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i8 [[DATA]], i16 [[PORT]])
+
+void test_outword(unsigned short port, unsigned short data) {
+    return __outword(port, data);
+}
+// CHECK-LABEL: void @test_outword(
+// CHECK-SAME:  [[PORT:%.*]],
+// CHECK-SAME:  [[DATA:%.*]])
+// CHECK:       tail call void asm sideeffect "outw ${0:w}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[DATA]], i16 [[PORT]])
+
+void test_outdword(unsigned short port, unsigned long data) {
+    return __outdword(port, data);
+}
+// CHECK-LABEL: void @test_outdword(
+// CHECK-SAME:  [[PORT:%.*]],
+// CHECK-SAME:  [[DATA:%.*]])
+// CHECK:       tail call void asm sideeffect "outl ${0:k}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]])
+
 #if defined(__x86_64__)
 
 char test__readgsbyte(unsigned long Offset) {


        


More information about the cfe-commits mailing list