Index: cfe/trunk/include/clang/Basic/Builtins.def =================================================================== --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -766,7 +766,6 @@ 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) Index: cfe/trunk/include/clang/Basic/BuiltinsX86.def =================================================================== --- cfe/trunk/include/clang/Basic/BuiltinsX86.def +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def @@ -1832,6 +1832,16 @@ 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 Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp @@ -2238,16 +2238,6 @@ 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 @@ 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; + } } } Index: cfe/trunk/lib/Headers/intrin.h =================================================================== --- cfe/trunk/lib/Headers/intrin.h +++ cfe/trunk/lib/Headers/intrin.h @@ -869,50 +869,7 @@ 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 \*----------------------------------------------------------------------------*/ Index: cfe/trunk/test/CodeGen/ms-x86-intrinsics.c =================================================================== --- cfe/trunk/test/CodeGen/ms-x86-intrinsics.c +++ cfe/trunk/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 @@ // 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); }