Skip to content

Commit 3482403

Browse files
authored
[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.
1 parent cfd2021 commit 3482403

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

clang/lib/Headers/intrin.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,24 +330,35 @@ static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
330330
__asm__ volatile("hlt");
331331
}
332332

333-
static inline int _inp(unsigned short port) {
334-
int ret;
335-
__asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
333+
static inline unsigned char __inbyte(unsigned short port) {
334+
unsigned char ret;
335+
__asm__ __volatile__("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
336336
return ret;
337337
}
338338

339-
static inline unsigned short _inpw(unsigned short port) {
339+
static inline unsigned short __inword(unsigned short port) {
340340
unsigned short ret;
341-
__asm__ volatile("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
341+
__asm__ __volatile__("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
342342
return ret;
343343
}
344344

345-
static inline unsigned long _inpd(unsigned short port) {
345+
static inline unsigned long __indword(unsigned short port) {
346346
unsigned long ret;
347-
__asm__ volatile("inl %w1, %k0" : "=a"(ret) : "Nd"(port));
347+
__asm__ __volatile__("inl %w1, %k0" : "=a"(ret) : "Nd"(port));
348348
return ret;
349349
}
350350

351+
static inline void __outbyte(unsigned short port, unsigned char data) {
352+
__asm__ __volatile__("outb %b0, %w1" : : "a"(data), "Nd"(port));
353+
}
354+
355+
static inline void __outword(unsigned short port, unsigned short data) {
356+
__asm__ __volatile__("outw %w0, %w1" : : "a"(data), "Nd"(port));
357+
}
358+
359+
static inline void __outdword(unsigned short port, unsigned long data) {
360+
__asm__ __volatile__("outl %k0, %w1" : : "a"(data), "Nd"(port));
361+
}
351362
#endif
352363

353364
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)

clang/test/CodeGen/X86/ms-x86-intrinsics.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,30 +64,54 @@ unsigned __int64 test__emulu(unsigned int a, unsigned int b) {
6464
// CHECK: ret i64 [[RES]]
6565

6666

67-
int test_inp(unsigned short port) {
68-
return _inp(port);
67+
unsigned char test_inbyte(unsigned short port) {
68+
return __inbyte(port);
6969
}
70-
// CHECK-LABEL: i32 @test_inp(i16 noundef
70+
// CHECK-LABEL: i8 @test_inbyte(i16 noundef
7171
// CHECK-SAME: [[PORT:%.*]])
72-
// CHECK: [[TMP0:%.*]] = tail call i32 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
73-
// CHECK-NEXT: ret i32 [[TMP0]]
72+
// CHECK: [[TMP0:%.*]] = tail call i8 asm sideeffect "inb ${1:w}, ${0:b}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
73+
// CHECK-NEXT: ret i8 [[TMP0]]
7474

75-
unsigned short test_inpw(unsigned short port) {
76-
return _inpw(port);
75+
unsigned short test_inword(unsigned short port) {
76+
return __inword(port);
7777
}
78-
// CHECK-LABEL: i16 @test_inpw(i16 noundef
78+
// CHECK-LABEL: i16 @test_inword(i16 noundef
7979
// CHECK-SAME: [[PORT:%.*]])
8080
// CHECK: [[TMP0:%.*]] = tail call i16 asm sideeffect "inw ${1:w}, ${0:w}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
8181
// CHECK-NEXT: ret i16 [[TMP0]]
8282

83-
unsigned long test_inpd(unsigned short port) {
84-
return _inpd(port);
83+
unsigned long test_indword(unsigned short port) {
84+
return __indword(port);
8585
}
86-
// CHECK-LABEL: i32 @test_inpd(i16 noundef
86+
// CHECK-LABEL: i32 @test_indword(i16 noundef
8787
// CHECK-SAME: [[PORT:%.*]])
8888
// CHECK: [[TMP0:%.*]] = tail call i32 asm sideeffect "inl ${1:w}, ${0:k}", "={ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[PORT]])
8989
// CHECK-NEXT: ret i32 [[TMP0]]
9090

91+
void test_outbyte(unsigned short port, unsigned char data) {
92+
return __outbyte(port, data);
93+
}
94+
// CHECK-LABEL: void @test_outbyte(
95+
// CHECK-SAME: [[PORT:%.*]],
96+
// CHECK-SAME: [[DATA:%.*]])
97+
// CHECK: tail call void asm sideeffect "outb ${0:b}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i8 [[DATA]], i16 [[PORT]])
98+
99+
void test_outword(unsigned short port, unsigned short data) {
100+
return __outword(port, data);
101+
}
102+
// CHECK-LABEL: void @test_outword(
103+
// CHECK-SAME: [[PORT:%.*]],
104+
// CHECK-SAME: [[DATA:%.*]])
105+
// CHECK: tail call void asm sideeffect "outw ${0:w}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i16 [[DATA]], i16 [[PORT]])
106+
107+
void test_outdword(unsigned short port, unsigned long data) {
108+
return __outdword(port, data);
109+
}
110+
// CHECK-LABEL: void @test_outdword(
111+
// CHECK-SAME: [[PORT:%.*]],
112+
// CHECK-SAME: [[DATA:%.*]])
113+
// CHECK: tail call void asm sideeffect "outl ${0:k}, ${1:w}", "{ax},N{dx},~{dirflag},~{fpsr},~{flags}"(i32 [[DATA]], i16 [[PORT]])
114+
91115
#if defined(__x86_64__)
92116

93117
char test__readgsbyte(unsigned long Offset) {

0 commit comments

Comments
 (0)