Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -58,6 +58,7 @@ bool BigEndian; bool TLSSupported; bool NoAsmVariants; // True if {|} are normal characters. + bool HasFloat128; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; @@ -329,9 +330,7 @@ } // FIXME /// \brief Determine whether the __float128 type is supported on this target. - virtual bool hasFloat128Type() const { - return false; - } + virtual bool hasFloat128Type() const { return HasFloat128; } /// \brief Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. Index: lib/Basic/TargetInfo.cpp =================================================================== --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -30,6 +30,7 @@ BigEndian = true; TLSSupported = true; NoAsmVariants = false; + HasFloat128 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -434,6 +434,11 @@ case llvm::Triple::ppc64le: this->MCountName = "_mcount"; break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::systemz: + this->HasFloat128 = true; + break; } } @@ -806,7 +811,6 @@ bool HasHTM; bool HasBPERMD; bool HasExtDiv; - bool HasFloat128; protected: std::string ABI; @@ -815,7 +819,7 @@ PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), HasVSX(false), HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false), - HasBPERMD(false), HasExtDiv(false), HasFloat128(false) { + HasBPERMD(false), HasExtDiv(false) { BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; @@ -1059,9 +1063,6 @@ LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble && getTriple().isOSBinFormatELF(); } - bool hasFloat128Type() const override { - return HasFloat128; - } }; const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { Index: test/CodeGenCXX/float128-declarations.cpp =================================================================== --- test/CodeGenCXX/float128-declarations.cpp +++ test/CodeGenCXX/float128-declarations.cpp @@ -2,8 +2,16 @@ // RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s // RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \ // RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple i386-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86 +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86 +// RUN: %clang_cc1 -emit-llvm -triple systemz-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-SYSZ // -/* Various contexts where type __float128 can appear. */ +/* Various contexts where type __float128 can appear. The different check + prefixes are due to different mangling on X86 and different calling + convention on SystemZ. */ /* Namespace */ namespace { @@ -84,3 +92,47 @@ // CHECK-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l // CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 // CHECK-DAG: store fp128 [[INC]], fp128* %f4l + +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000 +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000 +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128] +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000] +// CHECK-X86-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKg(fp128* +// CHECK-X86-DAG: @f1f = global fp128 0xL00000000000000000000000000000000 +// CHECK-X86-DAG: @f2f = global fp128 0xL33333333333333334004033333333333 +// CHECK-X86-DAG: @arr1f = global [10 x fp128] +// CHECK-X86-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000] +// CHECK-X86-DAG: declare fp128 @_Z6func1fg(fp128) +// CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg) +// CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg) +// CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg) +// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 } +// CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16 +// CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16 +// CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16 +// CHECK-X86-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16 +// CHECK-X86-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l +// CHECK-X86-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 +// CHECK-X86-DAG: store fp128 [[INC]], fp128* %f4l + +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000 +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000 +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128] +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000] +// CHECK-SYSZ-DAG: define internal void @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128* +// CHECK-SYSZ-DAG: @f1f = global fp128 0xL00000000000000000000000000000000 +// CHECK-SYSZ-DAG: @f2f = global fp128 0xL33333333333333334004033333333333 +// CHECK-SYSZ-DAG: @arr1f = global [10 x fp128] +// CHECK-SYSZ-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000] +// CHECK-SYSZ-DAG: declare void @_Z6func1fU10__float128(fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C16func2cEU10__float128(fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_Z6func1tIU10__float128ET_S0_(fp128* +// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 } +// CHECK-SYSZ-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16 +// CHECK-SYSZ-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l +// CHECK-SYSZ-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 +// CHECK-SYSZ-DAG: store fp128 [[INC]], fp128* %f4l Index: test/Sema/128bitfloat.cpp =================================================================== --- test/Sema/128bitfloat.cpp +++ test/Sema/128bitfloat.cpp @@ -1,6 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +#ifdef __x86_64__ +__float128 f; +template struct __is_floating_point_helper {}; +template<> struct __is_floating_point_helper<__float128> {}; +int g(int x, __float128 *y) { + return x + *y; +} + +// expected-no-diagnostics +#else #if !defined(__STRICT_ANSI__) __float128 f; // expected-error {{__float128 is not supported on this target}} // But this should work: @@ -22,3 +32,4 @@ } #endif +#endif Index: test/Sema/attr-mode.c =================================================================== --- test/Sema/attr-mode.c +++ test/Sema/attr-mode.c @@ -76,7 +76,7 @@ void test_long_to_i64(long* y) { f_i64_arg(y); } void test_long_to_ui64(unsigned long* y) { f_ui64_arg(y); } #endif -typedef float f128ibm __attribute__ ((mode (TF))); // expected-error{{unsupported machine mode 'TF'}} +typedef float f128ibm __attribute__ ((mode (TF))); #elif TEST_64BIT_PPC64 typedef float f128ibm __attribute__ ((mode (TF))); typedef _Complex float c128ibm __attribute__ ((mode (TC)));