summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-03-22 19:13:13 +0000
committerHans Wennborg <hans@hanshq.net>2017-03-22 19:13:13 +0000
commit043f40258649bab71af75472e54b9fa08bd1da51 (patch)
tree5f92e49c7b0a7615c009d8bd725c0c9ecb371d19
parentdc13921fbc19bb9455a582e25bf520ab3eb1b991 (diff)
downloadbcm5719-llvm-043f40258649bab71af75472e54b9fa08bd1da51.tar.gz
bcm5719-llvm-043f40258649bab71af75472e54b9fa08bd1da51.zip
[X86] Implement __readgsqword (and the rest) as builtins (PR32373)
It seems MS headers have started using __readgsqword, and since it's used in a header that doesn't include intrin.h, we can't implement it as an inline function anymore. That was already the case for __readfsdword, which Saleem added support for in r220859. This patch reuses that codegen to implement all of __read[fg]s{byte,word,dword,qword}. Differential Revision: https://reviews.llvm.org/D31248 llvm-svn: 298538
-rw-r--r--clang/include/clang/Basic/Builtins.def1
-rw-r--r--clang/include/clang/Basic/BuiltinsX86.def10
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp34
-rw-r--r--clang/lib/Headers/intrin.h43
-rw-r--r--clang/test/CodeGen/ms-x86-intrinsics.c65
5 files changed, 96 insertions, 57 deletions
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 9174d391034..6a83c1a3b7d 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -766,7 +766,6 @@ LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def
index 2400b4458cc..e2461758844 100644
--- a/clang/include/clang/Basic/BuiltinsX86.def
+++ b/clang/include/clang/Basic/BuiltinsX86.def
@@ -1832,6 +1832,16 @@ TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, ""
TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__readgsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 817589064a3..463dda4213a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2238,16 +2238,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BI_InterlockedXor16:
case Builtin::BI_InterlockedXor:
return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
- case Builtin::BI__readfsdword: {
- llvm::Type *IntTy = ConvertType(E->getType());
- Value *IntToPtr =
- Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
- llvm::PointerType::get(IntTy, 257));
- LoadInst *Load = Builder.CreateAlignedLoad(
- IntTy, IntToPtr, getContext().getTypeAlignInChars(E->getType()));
- Load->setVolatile(true);
- return RValue::get(Load);
- }
case Builtin::BI__exception_code:
case Builtin::BI_exception_code:
@@ -8005,6 +7995,30 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
CS.setAttributes(NoReturnAttr);
return CS.getInstruction();
}
+ case X86::BI__readfsbyte:
+ case X86::BI__readfsword:
+ case X86::BI__readfsdword:
+ case X86::BI__readfsqword: {
+ llvm::Type *IntTy = ConvertType(E->getType());
+ Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
+ llvm::PointerType::get(IntTy, 257));
+ LoadInst *Load = Builder.CreateAlignedLoad(
+ IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
+ Load->setVolatile(true);
+ return Load;
+ }
+ case X86::BI__readgsbyte:
+ case X86::BI__readgsword:
+ case X86::BI__readgsdword:
+ case X86::BI__readgsqword: {
+ llvm::Type *IntTy = ConvertType(E->getType());
+ Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
+ llvm::PointerType::get(IntTy, 256));
+ LoadInst *Load = Builder.CreateAlignedLoad(
+ IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
+ Load->setVolatile(true);
+ return Load;
+ }
}
}
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index af87914a9a0..16028d5c6b0 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -869,50 +869,7 @@ _InterlockedCompareExchange64_rel(__int64 volatile *_Destination,
return _Comparand;
}
#endif
-/*----------------------------------------------------------------------------*\
-|* readfs, readgs
-|* (Pointers in address space #256 and #257 are relative to the GS and FS
-|* segment registers, respectively.)
-\*----------------------------------------------------------------------------*/
-#define __ptr_to_addr_space(__addr_space_nbr, __type, __offset) \
- ((volatile __type __attribute__((__address_space__(__addr_space_nbr)))*) \
- (__offset))
-#ifdef __i386__
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-__readfsbyte(unsigned long __offset) {
- return *__ptr_to_addr_space(257, unsigned char, __offset);
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-__readfsword(unsigned long __offset) {
- return *__ptr_to_addr_space(257, unsigned short, __offset);
-}
-static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-__readfsqword(unsigned long __offset) {
- return *__ptr_to_addr_space(257, unsigned __int64, __offset);
-}
-#endif
-#ifdef __x86_64__
-static __inline__ unsigned char __DEFAULT_FN_ATTRS
-__readgsbyte(unsigned long __offset) {
- return *__ptr_to_addr_space(256, unsigned char, (unsigned long long)__offset);
-}
-static __inline__ unsigned short __DEFAULT_FN_ATTRS
-__readgsword(unsigned long __offset) {
- return *__ptr_to_addr_space(256, unsigned short,
- (unsigned long long)__offset);
-}
-static __inline__ unsigned long __DEFAULT_FN_ATTRS
-__readgsdword(unsigned long __offset) {
- return *__ptr_to_addr_space(256, unsigned long, (unsigned long long)__offset);
-}
-static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
-__readgsqword(unsigned long __offset) {
- return *__ptr_to_addr_space(256, unsigned __int64,
- (unsigned long long)__offset);
-}
-#endif
-#undef __ptr_to_addr_space
/*----------------------------------------------------------------------------*\
|* movs, stos
\*----------------------------------------------------------------------------*/
diff --git a/clang/test/CodeGen/ms-x86-intrinsics.c b/clang/test/CodeGen/ms-x86-intrinsics.c
index e635220e8c1..51520d1f658 100644
--- a/clang/test/CodeGen/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/ms-x86-intrinsics.c
@@ -6,15 +6,37 @@
// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X64
#if defined(__i386__)
+char test__readfsbyte(unsigned long Offset) {
+ return __readfsbyte(Offset);
+}
+// CHECK-I386-LABEL: define signext i8 @test__readfsbyte(i32 %Offset)
+// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i8 addrspace(257)*
+// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(257)* [[PTR]], align 1
+// CHECK-I386: ret i8 [[VALUE:%[0-9]+]]
+
+short test__readfsword(unsigned long Offset) {
+ return __readfsword(Offset);
+}
+// CHECK-I386-LABEL: define signext i16 @test__readfsword(i32 %Offset)
+// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i16 addrspace(257)*
+// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(257)* [[PTR]], align 2
+// CHECK-I386: ret i16 [[VALUE:%[0-9]+]]
+
long test__readfsdword(unsigned long Offset) {
return __readfsdword(Offset);
}
-
-// CHECK-I386-LABEL: define i32 @test__readfsdword(i32 %Offset){{.*}}{
+// CHECK-I386-LABEL: define i32 @test__readfsdword(i32 %Offset)
// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i32 addrspace(257)*
// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(257)* [[PTR]], align 4
// CHECK-I386: ret i32 [[VALUE:%[0-9]+]]
-// CHECK-I386: }
+
+long long test__readfsqword(unsigned long Offset) {
+ return __readfsqword(Offset);
+}
+// CHECK-I386-LABEL: define i64 @test__readfsqword(i32 %Offset)
+// CHECK-I386: [[PTR:%[0-9]+]] = inttoptr i32 %Offset to i64 addrspace(257)*
+// CHECK-I386: [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(257)* [[PTR]], align 8
+// CHECK-I386: ret i64 [[VALUE:%[0-9]+]]
#endif
__int64 test__emul(int a, int b) {
@@ -36,6 +58,43 @@ unsigned __int64 test__emulu(unsigned int a, unsigned int b) {
// CHECK: ret i64 [[RES]]
#if defined(__x86_64__)
+
+char test__readgsbyte(unsigned long Offset) {
+ return __readgsbyte(Offset);
+}
+// CHECK-X64-LABEL: define i8 @test__readgsbyte(i32 %Offset)
+// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i8 addrspace(256)*
+// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i8, i8 addrspace(256)* [[PTR]], align 1
+// CHECK-X64: ret i8 [[VALUE:%[0-9]+]]
+
+short test__readgsword(unsigned long Offset) {
+ return __readgsword(Offset);
+}
+// CHECK-X64-LABEL: define i16 @test__readgsword(i32 %Offset)
+// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i16 addrspace(256)*
+// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i16, i16 addrspace(256)* [[PTR]], align 2
+// CHECK-X64: ret i16 [[VALUE:%[0-9]+]]
+
+long test__readgsdword(unsigned long Offset) {
+ return __readgsdword(Offset);
+}
+// CHECK-X64-LABEL: define i32 @test__readgsdword(i32 %Offset)
+// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i32 addrspace(256)*
+// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i32, i32 addrspace(256)* [[PTR]], align 4
+// CHECK-X64: ret i32 [[VALUE:%[0-9]+]]
+
+long long test__readgsqword(unsigned long Offset) {
+ return __readgsqword(Offset);
+}
+// CHECK-X64-LABEL: define i64 @test__readgsqword(i32 %Offset)
+// CHECK-X64: [[ZEXT:%[0-9]+]] = zext i32 %Offset to i64
+// CHECK-X64: [[PTR:%[0-9]+]] = inttoptr i64 [[ZEXT]] to i64 addrspace(256)*
+// CHECK-X64: [[VALUE:%[0-9]+]] = load volatile i64, i64 addrspace(256)* [[PTR]], align 8
+// CHECK-X64: ret i64 [[VALUE:%[0-9]+]]
+
__int64 test__mulh(__int64 a, __int64 b) {
return __mulh(a, b);
}
OpenPOWER on IntegriCloud