forked from OSchip/llvm-project
CodeGen: add __readfsdword builtin
The Windows NT SDK uses __readfsdword and declares it as a compiler provided builtin (#pragma intrinsic(__readfsword). Because intrin.h is not referenced by winnt.h, it is not possible to provide an out-of-line definition for the intrinsic. Provide a proper compiler builtin definition. llvm-svn: 220859
This commit is contained in:
parent
595e598869
commit
a25fbef088
|
@ -703,6 +703,7 @@ LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
|
|||
LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
|
||||
|
||||
// C99 library functions
|
||||
// C99 stdlib.h
|
||||
|
|
|
@ -1624,6 +1624,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
RMWI->setVolatile(true);
|
||||
return RValue::get(RMWI);
|
||||
}
|
||||
case Builtin::BI__readfsdword: {
|
||||
Value *IntToPtr =
|
||||
Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
|
||||
llvm::PointerType::get(CGM.Int32Ty, 257));
|
||||
LoadInst *Load =
|
||||
Builder.CreateAlignedLoad(IntToPtr, /*Align=*/4, /*isVolatile=*/true);
|
||||
return RValue::get(Load);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an alias for a lib function (e.g. __builtin_sin), emit
|
||||
|
|
|
@ -861,10 +861,6 @@ static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
|
|||
__readfsbyte(unsigned long __offset) {
|
||||
return *__ptr_to_addr_space(257, unsigned char, __offset);
|
||||
}
|
||||
static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
|
||||
__readfsdword(unsigned long __offset) {
|
||||
return *__ptr_to_addr_space(257, unsigned long, __offset);
|
||||
}
|
||||
static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
|
||||
__readfsqword(unsigned long __offset) {
|
||||
return *__ptr_to_addr_space(257, unsigned __int64, __offset);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK -check-prefix CHECK-I386
|
||||
// RUN: %clang_cc1 -triple thumbv7--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {
|
||||
|
@ -36,3 +36,16 @@ long test_InterlockedExchange(long *Target, long Value) {
|
|||
// CHECK: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %Target, i32 %Value seq_cst
|
||||
// CHECK: ret i32 %[[EXCHANGE:[0-9]+]]
|
||||
// CHECK: }
|
||||
|
||||
#if defined(__i386__)
|
||||
long test__readfsdword(unsigned long Offset) {
|
||||
return __readfsdword(Offset);
|
||||
}
|
||||
|
||||
// CHECK-I386: define i32 @test__readfsdword(i32 %Offset){{.*}}{
|
||||
// CHECK-I386: %0 = inttoptr i32 %Offset to i32 addrspace(257)*
|
||||
// CHECK-I386: %1 = load volatile i32 addrspace(257)* %0, align 4
|
||||
// CHECK-I386: ret i32 %1
|
||||
// CHECK-I386: }
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue