[llvm-commits] [llvm] r42019 - /llvm/trunk/lib/Target/CBackend/CBackend.cpp
Dale Johannesen
dalej at apple.com
Sun Sep 16 17:38:27 PDT 2007
Author: johannes
Date: Sun Sep 16 19:38:27 2007
New Revision: 42019
URL: http://llvm.org/viewvc/llvm-project?rev=42019&view=rev
Log:
Implement x86 long double (uses host long double,
so only works on x86 target).
Modified:
llvm/trunk/lib/Target/CBackend/CBackend.cpp
Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=42019&r1=42018&r2=42019&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sun Sep 16 19:38:27 2007
@@ -406,6 +406,11 @@
}
case Type::FloatTyID: return Out << "float " << NameSoFar;
case Type::DoubleTyID: return Out << "double " << NameSoFar;
+ // Lacking emulation of FP80 on PPC, etc., we assume whichever of these is
+ // present matches host 'long double'.
+ case Type::X86_FP80TyID:
+ case Type::PPC_FP128TyID:
+ case Type::FP128TyID: return Out << "long double " << NameSoFar;
default :
cerr << "Unknown primitive type: " << *Ty << "\n";
abort();
@@ -604,7 +609,7 @@
// only deal in IEEE FP).
//
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
- // Do long doubles the hard way for now.
+ // Do long doubles in hex for now.
if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
return false;
APFloat APF = APFloat(CFP->getValueAPF()); // copy
@@ -878,15 +883,22 @@
switch (CPV->getType()->getTypeID()) {
case Type::FloatTyID:
- case Type::DoubleTyID: {
+ case Type::DoubleTyID:
+ case Type::X86_FP80TyID:
+ case Type::PPC_FP128TyID:
+ case Type::FP128TyID: {
ConstantFP *FPC = cast<ConstantFP>(CPV);
std::map<const ConstantFP*, unsigned>::iterator I = FPConstantMap.find(FPC);
if (I != FPConstantMap.end()) {
// Because of FP precision problems we must load from a stack allocated
// value that holds the value in hex.
- Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
+ Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" :
+ FPC->getType() == Type::DoubleTy ? "double" :
+ "long double")
<< "*)&FPConstant" << I->second << ')';
} else {
+ assert(FPC->getType() == Type::FloatTy ||
+ FPC->getType() == Type::DoubleTy);
double V = FPC->getType() == Type::FloatTy ?
FPC->getValueAPF().convertToFloat() :
FPC->getValueAPF().convertToDouble();
@@ -1490,7 +1502,10 @@
<< "\n\n/* Support for floating point constants */\n"
<< "typedef unsigned long long ConstantDoubleTy;\n"
<< "typedef unsigned int ConstantFloatTy;\n"
-
+ << "typedef struct { unsigned long long f1; unsigned short f2; "
+ "unsigned short pad[3]; } ConstantFP80Ty;\n"
+ << "typedef struct { unsigned long long f1; unsigned long long f2; }"
+ " ConstantFP128Ty;\n"
<< "\n\n/* Global Declarations */\n";
// First output all the declarations for the program, because C requires
@@ -1529,6 +1544,7 @@
Out << "\n/* Function Declarations */\n";
Out << "double fmod(double, double);\n"; // Support for FP rem
Out << "float fmodf(float, float);\n";
+ Out << "long double fmodl(long double, long double);\n";
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
// Don't print declarations for intrinsic functions.
@@ -1711,6 +1727,13 @@
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
<< " = 0x" << std::hex << i << std::dec
<< "U; /* " << Val << " */\n";
+ } else if (FPC->getType() == Type::X86_FP80Ty) {
+ const uint64_t *p = FPC->getValueAPF().convertToAPInt().getRawData();
+ Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
+ << " = { 0x" << std::hex
+ << ((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16)
+ << ", 0x" << (uint16_t)(p[0] >> 48) << ",0,0,0"
+ << "}; /* Long double constant */\n" << std::dec;
} else
assert(0 && "Unknown float type!");
}
@@ -2190,8 +2213,10 @@
// Output a call to fmod/fmodf instead of emitting a%b
if (I.getType() == Type::FloatTy)
Out << "fmodf(";
- else
+ else if (I.getType() == Type::DoubleTy)
Out << "fmod(";
+ else // all 3 flavors of long double
+ Out << "fmodl(";
writeOperand(I.getOperand(0));
Out << ", ";
writeOperand(I.getOperand(1));
More information about the llvm-commits
mailing list