From 2898e5cac36af39ee3b3266b8a665f1e7b74002e Mon Sep 17 00:00:00 2001 From: kai Date: Sun, 30 Dec 2012 17:18:36 +0100 Subject: [PATCH] Add support for PPC 128bit doubledouble type. On a PowerPC target the datatype real is mapped to PPC 128bit doubledouble type. Please note that this yet does not work if you cross compile from a different architecture. --- gen/complex.cpp | 2 ++ gen/llvmhelpers.cpp | 8 +++++++- gen/tollvm.cpp | 5 +++++ ir/irtype.cpp | 7 ++++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gen/complex.cpp b/gen/complex.cpp index 14e11a58..37d74556 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -40,6 +40,8 @@ LLType* DtoComplexBaseType(Type* t) case Tcomplex80: if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64)) return LLType::getX86_FP80Ty(gIR->context()); + else if (global.params.cpu == ARCHppc || global.params.cpu == ARCHppc_64) + return LLType::getPPC_FP128Ty(gIR->context()); else return LLType::getDoubleTy(gIR->context()); } diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index aad156bd..f458ff89 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1585,8 +1585,9 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s fatal(); // or LLVM asserts } + llvm::Type *dtype(DtoType(T)); char tmp[21]; // probably excessive, but covers a uint64_t - sprintf(tmp, "%lu", static_cast(gDataLayout->getTypeSizeInBits(DtoType(T)))); + sprintf(tmp, "%lu", static_cast(gDataLayout->getTypeSizeInBits(dtype))); // replace # in name with bitsize name = td->intrinsicName; @@ -1595,6 +1596,11 @@ void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, s size_t pos; while(std::string::npos != (pos = name.find(needle))) { if (pos > 0 && name[pos-1] == prefix) { + // Check for special PPC128 double + if (dtype->isPPC_FP128Ty()) { + name.insert(pos-1, "ppc"); + pos += 3; + } // Properly prefixed, insert bitwidth. name.replace(pos, 1, tmp); } else { diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index cb9526c3..d8d3e86d 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -676,6 +676,11 @@ LLConstant* DtoConstFP(Type* t, longdouble value) bits[0] = *reinterpret_cast(&value); bits[1] = *reinterpret_cast(reinterpret_cast(&value) + 1); return LLConstantFP::get(gIR->context(), APFloat(APInt(80, 2, bits))); + } else if(llty == LLType::getPPC_FP128Ty(gIR->context())) { + uint64_t bits[] = {0, 0}; + bits[0] = *reinterpret_cast(&value); + bits[1] = *reinterpret_cast(reinterpret_cast(&value) + 1); + return LLConstantFP::get(gIR->context(), APFloat(APInt(128, 2, bits))); } else { assert(0 && "Unknown floating point type encountered"); } diff --git a/ir/irtype.cpp b/ir/irtype.cpp index 78ebf4b0..4d92eb47 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -109,6 +109,9 @@ llvm::Type * IrTypeBasic::basic2llvm(Type* t) // only x86 has 80bit float if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) return llvm::Type::getX86_FP80Ty(ctx); + // PPC has a special 128bit float + else if (global.params.cpu == ARCHppc || global.params.cpu == ARCHppc_64) + return llvm::Type::getPPC_FP128Ty(ctx); // other platforms use 64bit reals else return llvm::Type::getDoubleTy(ctx); @@ -125,7 +128,9 @@ llvm::Type * IrTypeBasic::basic2llvm(Type* t) case Tcomplex80: t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) ? llvm::Type::getX86_FP80Ty(ctx) - : llvm::Type::getDoubleTy(ctx); + : (global.params.cpu == ARCHppc || global.params.cpu == ARCHppc_64) + ? llvm::Type::getPPC_FP128Ty(ctx) + : llvm::Type::getDoubleTy(ctx); return getComplexType(ctx, t2); case Tbool: