[clang] [X86]Add support for __outbyte/word/dword and __inbyte/word/dword (PR #93774)
Malay Sanghi via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 20 00:03:28 PDT 2024
https://github.com/MalaySanghi updated https://github.com/llvm/llvm-project/pull/93774
>From 17c3fc95c0753ec013b22ce0c539992b24b21055 Mon Sep 17 00:00:00 2001
From: Malay Sanghi <malay.sanghi at intel.com>
Date: Wed, 29 May 2024 22:40:47 -0700
Subject: [PATCH 1/5] Add support for _outp{|w|d}
---
clang/lib/Headers/intrin.h | 17 +++++++++++++++
clang/test/CodeGen/X86/ms-x86-intrinsics.c | 25 +++++++++++++++++++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 1227f45d5432b..b9d10a6941271 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -348,6 +348,23 @@ static inline unsigned long _inpd(unsigned short port) {
return ret;
}
+static inline int _outp(unsigned short port, int data) {
+ __asm__ volatile("outb %b0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ return data;
+}
+
+static inline unsigned short
+_outpw(unsigned short port, unsigned short data) {
+ __asm__ volatile("outw %w0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ return data;
+}
+
+static inline unsigned long _outpd(unsigned short port,
+ unsigned long data) {
+ __asm__ volatile("outl %k0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ return data;
+}
+
#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..79fa7028d8e05 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -63,7 +63,6 @@ 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);
}
@@ -88,6 +87,30 @@ unsigned long test_inpd(unsigned short 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]]
+int test_outp(unsigned short port, int data) {
+ return _outp(port, data);
+}
+// CHECK-LABEL: i32 @test_outp(
+// CHECK-SAME: [[PORT:%.*]], i32 noundef returned [[DATA:%.*]])
+// CHECK-NEXT: tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]]
+// CHECK-NEXT: ret i32 [[DATA]]
+
+unsigned short test_outpw(unsigned short port, unsigned short data) {
+ return _outpw(port, data);
+}
+// CHECK-LABEL: i16 @test_outpw(
+// CHECK-SAME: [[PORT:%.*]], i16 noundef returned zeroext [[DATA:%.*]])
+// CHECK-NEXT: tail call void asm sideeffect "outw ${0:w}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i16 [[DATA]], i16 [[PORT]])
+// CHECK-NEXT: ret i16 [[DATA]]
+
+unsigned long test_outpd(unsigned short port, unsigned long data) {
+ return _outpd(port, data);
+}
+// CHECK-LABEL: i32 @test_outpd(
+// CHECK-SAME: [[PORT:%.*]], i32 noundef returned [[DATA:%.*]])
+// CHECK-NEXT: tail call void asm sideeffect "outl ${0:k}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]])
+// CHECK-NEXT: ret i32 [[DATA]]
+
#if defined(__x86_64__)
char test__readgsbyte(unsigned long Offset) {
>From f0f4675c6ef13655a089d78bada9f55bb9ce5123 Mon Sep 17 00:00:00 2001
From: Malay Sanghi <malay.sanghi at intel.com>
Date: Thu, 30 May 2024 00:01:45 -0700
Subject: [PATCH 2/5] remove memory constraint and fix definition.
---
clang/lib/Headers/intrin.h | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index b9d10a6941271..92c7aa134c36d 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -349,25 +349,22 @@ static inline unsigned long _inpd(unsigned short port) {
}
static inline int _outp(unsigned short port, int data) {
- __asm__ volatile("outb %b0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ __asm__ volatile("outb %b0, %w1" : : "a"(data), "Nd"(port));
return data;
}
static inline unsigned short
_outpw(unsigned short port, unsigned short data) {
- __asm__ volatile("outw %w0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ __asm__ volatile("outw %w0, %w1" : : "a"(data), "Nd"(port));
return data;
}
static inline unsigned long _outpd(unsigned short port,
unsigned long data) {
- __asm__ volatile("outl %k0, %w1" : : "a"(data), "Nd"(port) : "memory");
+ __asm__ volatile("outl %k0, %w1" : : "a"(data), "Nd"(port));
return data;
}
-#endif
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
__asm__ volatile("nop");
}
>From 794872bf7fc0ccbe9f2842f8624803f199d1a72f Mon Sep 17 00:00:00 2001
From: Malay Sanghi <malay.sanghi at intel.com>
Date: Fri, 31 May 2024 01:06:11 -0700
Subject: [PATCH 3/5] merge checks
---
clang/lib/Headers/intrin.h | 8 ++++----
clang/test/CodeGen/X86/ms-x86-intrinsics.c | 16 ++++++++++------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 92c7aa134c36d..f928ca5cdcf5c 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -353,18 +353,18 @@ static inline int _outp(unsigned short port, int data) {
return data;
}
-static inline unsigned short
-_outpw(unsigned short port, unsigned short data) {
+static inline unsigned short _outpw(unsigned short port, unsigned short data) {
__asm__ volatile("outw %w0, %w1" : : "a"(data), "Nd"(port));
return data;
}
-static inline unsigned long _outpd(unsigned short port,
- unsigned long data) {
+static inline unsigned long _outpd(unsigned short port, unsigned long data) {
__asm__ volatile("outl %k0, %w1" : : "a"(data), "Nd"(port));
return data;
}
+#endif
+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
__asm__ volatile("nop");
}
diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
index 79fa7028d8e05..c5b743759c4b6 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -63,6 +63,7 @@ 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);
}
@@ -91,24 +92,27 @@ int test_outp(unsigned short port, int data) {
return _outp(port, data);
}
// CHECK-LABEL: i32 @test_outp(
-// CHECK-SAME: [[PORT:%.*]], i32 noundef returned [[DATA:%.*]])
-// CHECK-NEXT: tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]]
+// CHECK-SAME: [[PORT:%.*]],
+// CHECK-SAME: [[DATA:%.*]])
+// CHECK: tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]])
// CHECK-NEXT: ret i32 [[DATA]]
unsigned short test_outpw(unsigned short port, unsigned short data) {
return _outpw(port, data);
}
// CHECK-LABEL: i16 @test_outpw(
-// CHECK-SAME: [[PORT:%.*]], i16 noundef returned zeroext [[DATA:%.*]])
-// CHECK-NEXT: tail call void asm sideeffect "outw ${0:w}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i16 [[DATA]], i16 [[PORT]])
+// 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]])
// CHECK-NEXT: ret i16 [[DATA]]
unsigned long test_outpd(unsigned short port, unsigned long data) {
return _outpd(port, data);
}
// CHECK-LABEL: i32 @test_outpd(
-// CHECK-SAME: [[PORT:%.*]], i32 noundef returned [[DATA:%.*]])
-// CHECK-NEXT: tail call void asm sideeffect "outl ${0:k}, ${1:w}", "{ax},N{dx},~{memory},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]])
+// 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]])
// CHECK-NEXT: ret i32 [[DATA]]
#if defined(__x86_64__)
>From 4534c726865ef0271110c8407fda8fe63b478405 Mon Sep 17 00:00:00 2001
From: Malay Sanghi <malay.sanghi at intel.com>
Date: Wed, 19 Jun 2024 23:16:38 -0700
Subject: [PATCH 4/5] implement byte/word/dword versions
---
clang/lib/Headers/intrin.h | 17 ++++----
clang/test/CodeGen/X86/ms-x86-intrinsics.c | 45 ++++++++++------------
2 files changed, 28 insertions(+), 34 deletions(-)
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index f928ca5cdcf5c..2105a6f0b617f 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -330,37 +330,34 @@ static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
__asm__ volatile("hlt");
}
-static inline int _inp(unsigned short port) {
- int ret;
+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));
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));
return ret;
}
-static inline int _outp(unsigned short port, int data) {
+static inline void __outbyte(unsigned short port, unsigned char data) {
__asm__ volatile("outb %b0, %w1" : : "a"(data), "Nd"(port));
- return data;
}
-static inline unsigned short _outpw(unsigned short port, unsigned short data) {
+static inline void __outword(unsigned short port, unsigned short data) {
__asm__ volatile("outw %w0, %w1" : : "a"(data), "Nd"(port));
- return data;
}
-static inline unsigned long _outpd(unsigned short port, unsigned long data) {
+static inline void __outdword(unsigned short port, unsigned long data) {
__asm__ volatile("outl %k0, %w1" : : "a"(data), "Nd"(port));
- return data;
}
#endif
diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
index c5b743759c4b6..b90e2679e26d2 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -64,56 +64,53 @@ 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]]
-int test_outp(unsigned short port, int data) {
- return _outp(port, data);
+void test_outbyte(unsigned short port, unsigned char data) {
+ return __outbyte(port, data);
}
-// CHECK-LABEL: i32 @test_outp(
+// 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}"(i32 [[DATA]], i16 [[PORT]])
-// CHECK-NEXT: ret i32 [[DATA]]
+// CHECK: tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i8 [[DATA]], i16 [[PORT]])
-unsigned short test_outpw(unsigned short port, unsigned short data) {
- return _outpw(port, data);
+void test_outword(unsigned short port, unsigned short data) {
+ return __outword(port, data);
}
-// CHECK-LABEL: i16 @test_outpw(
+// 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]])
-// CHECK-NEXT: ret i16 [[DATA]]
-unsigned long test_outpd(unsigned short port, unsigned long data) {
- return _outpd(port, data);
+void test_outdword(unsigned short port, unsigned long data) {
+ return __outdword(port, data);
}
-// CHECK-LABEL: i32 @test_outpd(
+// 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]])
-// CHECK-NEXT: ret i32 [[DATA]]
#if defined(__x86_64__)
>From b438d3f79cd1e5967fb5539c8acd695df6bf885e Mon Sep 17 00:00:00 2001
From: Malay Sanghi <malay.sanghi at intel.com>
Date: Thu, 20 Jun 2024 00:03:15 -0700
Subject: [PATCH 5/5] replace volatile with __volatile__
---
clang/lib/Headers/intrin.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 2105a6f0b617f..d2250926ce5e1 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -332,32 +332,32 @@ static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
static inline unsigned char __inbyte(unsigned short port) {
unsigned char ret;
- __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
+ __asm__ __volatile__("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
return ret;
}
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 __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));
+ __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));
+ __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));
+ __asm__ __volatile__("outl %k0, %w1" : : "a"(data), "Nd"(port));
}
#endif
More information about the cfe-commits
mailing list