forked from OSchip/llvm-project
[PowerPC] Support -mabi=ieeelongdouble and -mabi=ibmlongdouble
gcc PowerPC supports 3 representations of long double: * -mlong-double-64 long double has the same representation of double but is mangled as `e`. In clang, this is the default on AIX, FreeBSD and Linux musl. * -mlong-double-128 2 possible 128-bit floating point representations: + -mabi=ibmlongdouble IBM extended double format. Mangled as `g` In clang, this is the default on Linux glibc. + -mabi=ieeelongdouble IEEE 754 quadruple-precision format. Mangled as `u9__ieee128` (`U10__float128` before gcc 8.2) This is currently unavailable. This patch adds -mabi=ibmlongdouble and -mabi=ieeelongdouble, and thus makes the IEEE 754 quadruple-precision long double available for languages supported by clang. Reviewed By: hfinkel Differential Revision: https://reviews.llvm.org/D64283 llvm-svn: 366044
This commit is contained in:
parent
54869ec907
commit
6bd02a442c
|
@ -172,6 +172,7 @@ VALUE_LANGOPT(MaxTypeAlign , 32, 0,
|
||||||
"default maximum alignment for types")
|
"default maximum alignment for types")
|
||||||
VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)")
|
VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)")
|
||||||
VALUE_LANGOPT(LongDoubleSize , 32, 0, "width of long double")
|
VALUE_LANGOPT(LongDoubleSize , 32, 0, "width of long double")
|
||||||
|
LANGOPT(PPCIEEELongDouble , 1, 0, "use IEEE 754 quadruple-precision for long double")
|
||||||
COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
|
COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
|
||||||
COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie")
|
COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie")
|
||||||
LANGOPT(ROPI , 1, 0, "Read-only position independence")
|
LANGOPT(ROPI , 1, 0, "Read-only position independence")
|
||||||
|
|
|
@ -298,6 +298,8 @@ def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">,
|
||||||
"precision">;
|
"precision">;
|
||||||
def mreassociate : Flag<["-"], "mreassociate">,
|
def mreassociate : Flag<["-"], "mreassociate">,
|
||||||
HelpText<"Allow reassociation transformations for floating-point instructions">;
|
HelpText<"Allow reassociation transformations for floating-point instructions">;
|
||||||
|
def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
|
||||||
|
HelpText<"Use IEEE 754 quadruple-precision for long double">;
|
||||||
def mfloat_abi : Separate<["-"], "mfloat-abi">,
|
def mfloat_abi : Separate<["-"], "mfloat-abi">,
|
||||||
HelpText<"The float ABI to use">;
|
HelpText<"The float ABI to use">;
|
||||||
def mtp : Separate<["-"], "mtp">,
|
def mtp : Separate<["-"], "mtp">,
|
||||||
|
|
|
@ -466,7 +466,9 @@ void PPCTargetInfo::adjust(LangOptions &Opts) {
|
||||||
Opts.AltiVec = 1;
|
Opts.AltiVec = 1;
|
||||||
TargetInfo::adjust(Opts);
|
TargetInfo::adjust(Opts);
|
||||||
if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
|
if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
|
||||||
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
|
LongDoubleFormat = Opts.PPCIEEELongDouble
|
||||||
|
? &llvm::APFloat::IEEEquad()
|
||||||
|
: &llvm::APFloat::PPCDoubleDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
|
ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
|
||||||
|
|
|
@ -1803,12 +1803,21 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
|
bool IEEELongDouble = false;
|
||||||
// The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
|
for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) {
|
||||||
// the option if given as we don't have backend support for any targets
|
StringRef V = A->getValue();
|
||||||
// that don't use the altivec abi.
|
if (V == "ieeelongdouble")
|
||||||
if (StringRef(A->getValue()) != "altivec")
|
IEEELongDouble = true;
|
||||||
|
else if (V == "ibmlongdouble")
|
||||||
|
IEEELongDouble = false;
|
||||||
|
else if (V != "altivec")
|
||||||
|
// The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
|
||||||
|
// the option if given as we don't have backend support for any targets
|
||||||
|
// that don't use the altivec abi.
|
||||||
ABIName = A->getValue();
|
ABIName = A->getValue();
|
||||||
|
}
|
||||||
|
if (IEEELongDouble)
|
||||||
|
CmdArgs.push_back("-mabi=ieeelongdouble");
|
||||||
|
|
||||||
ppc::FloatABI FloatABI =
|
ppc::FloatABI FloatABI =
|
||||||
ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
|
ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
|
||||||
|
|
|
@ -2745,6 +2745,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
||||||
Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
|
Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
|
||||||
? 128
|
? 128
|
||||||
: Args.hasArg(OPT_mlong_double_64) ? 64 : 0;
|
: Args.hasArg(OPT_mlong_double_64) ? 64 : 0;
|
||||||
|
Opts.PPCIEEELongDouble = Args.hasArg(OPT_mabi_EQ_ieeelongdouble);
|
||||||
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
||||||
Opts.ROPI = Args.hasArg(OPT_fropi);
|
Opts.ROPI = Args.hasArg(OPT_fropi);
|
||||||
Opts.RWPI = Args.hasArg(OPT_frwpi);
|
Opts.RWPI = Args.hasArg(OPT_frwpi);
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s -mlong-double-64 | \
|
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s -mlong-double-64 | \
|
||||||
// RUN: FileCheck --check-prefix=FP64 %s
|
// RUN: FileCheck --check-prefix=FP64 %s
|
||||||
|
|
||||||
|
// musl defaults to -mlong-double-64, so -mlong-double-128 is needed to make
|
||||||
|
// -mabi=ieeelongdouble effective.
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64-linux-musl -emit-llvm -o - %s -mlong-double-128 \
|
||||||
|
// RUN: -mabi=ieeelongdouble | FileCheck --check-prefix=FP128 %s
|
||||||
|
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s \
|
||||||
|
// RUN: -mabi=ieeelongdouble | FileCheck --check-prefix=FP128 %s
|
||||||
|
|
||||||
|
// IBM extended double is the default.
|
||||||
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s | \
|
// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s | \
|
||||||
// RUN: FileCheck --check-prefix=IBM128 %s
|
// RUN: FileCheck --check-prefix=IBM128 %s
|
||||||
// RUN: %clang_cc1 -triple powerpc64-linux-musl -emit-llvm -o - -mlong-double-128 %s | \
|
// RUN: %clang_cc1 -triple powerpc64-linux-musl -emit-llvm -o - -mlong-double-128 %s | \
|
||||||
|
@ -13,10 +21,13 @@ int size = sizeof(x);
|
||||||
|
|
||||||
// FP64: @x = global double {{.*}}, align 8
|
// FP64: @x = global double {{.*}}, align 8
|
||||||
// FP64: @size = global i32 8
|
// FP64: @size = global i32 8
|
||||||
|
// FP128: @x = global fp128 {{.*}}, align 16
|
||||||
|
// FP128: @size = global i32 16
|
||||||
// IBM128: @x = global ppc_fp128 {{.*}}, align 16
|
// IBM128: @x = global ppc_fp128 {{.*}}, align 16
|
||||||
// IBM128: @size = global i32 16
|
// IBM128: @size = global i32 16
|
||||||
|
|
||||||
long double foo(long double d) { return d; }
|
long double foo(long double d) { return d; }
|
||||||
|
|
||||||
// FP64: double @_Z3fooe(double %d)
|
// FP64: double @_Z3fooe(double %d)
|
||||||
|
// FP128: fp128 @_Z3foou9__ieee128(fp128 %d)
|
||||||
// IBM128: ppc_fp128 @_Z3foog(ppc_fp128 %d)
|
// IBM128: ppc_fp128 @_Z3foog(ppc_fp128 %d)
|
||||||
|
|
|
@ -66,4 +66,22 @@
|
||||||
// CHECK-ELFv2-PIC: "-mrelocation-model" "pic" "-pic-level" "2"
|
// CHECK-ELFv2-PIC: "-mrelocation-model" "pic" "-pic-level" "2"
|
||||||
// CHECK-ELFv2-PIC: "-target-abi" "elfv2"
|
// CHECK-ELFv2-PIC: "-target-abi" "elfv2"
|
||||||
|
|
||||||
|
// Check -mabi=ieeelongdouble is passed through but it does not change -target-abi.
|
||||||
|
// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=ieeelongdouble -mabi=elfv1 -### 2>&1 \
|
||||||
|
// RUN: | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
|
||||||
|
// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=elfv1 -mabi=ieeelongdouble -### 2>&1 \
|
||||||
|
// RUN: | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
|
||||||
|
// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=elfv2 -mabi=elfv1 -mabi=ibmlongdouble -mabi=ieeelongdouble -### 2>&1 \
|
||||||
|
// RUN: | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
|
||||||
|
|
||||||
|
// CHECK-ELFv1-IEEE: "-mabi=ieeelongdouble"
|
||||||
|
// CHECK-ELFv1-IEEE: "-target-abi" "elfv1"
|
||||||
|
|
||||||
|
// Check -mabi=ibmlongdouble is the default.
|
||||||
|
// RUN: %clang -target powerpc64le-linux-gnu %s -### 2>&1 \
|
||||||
|
// RUN: | FileCheck -check-prefix=CHECK-ELFv2-IBM128 %s
|
||||||
|
// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=ibmlongdouble -### 2>&1 \
|
||||||
|
// RUN: | FileCheck -check-prefix=CHECK-ELFv2-IBM128 %s
|
||||||
|
|
||||||
|
// CHECK-ELFv2-IBM128-NOT: "-mabi=ieeelongdouble"
|
||||||
|
// CHECK-ELFv2-IBM128: "-target-abi" "elfv2"
|
||||||
|
|
Loading…
Reference in New Issue