mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-30 02:25:19 +00:00
Implement x86 long double (uses host long double,
so only works on x86 target). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42019 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -406,6 +406,11 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
|
|||||||
}
|
}
|
||||||
case Type::FloatTyID: return Out << "float " << NameSoFar;
|
case Type::FloatTyID: return Out << "float " << NameSoFar;
|
||||||
case Type::DoubleTyID: return Out << "double " << 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 :
|
default :
|
||||||
cerr << "Unknown primitive type: " << *Ty << "\n";
|
cerr << "Unknown primitive type: " << *Ty << "\n";
|
||||||
abort();
|
abort();
|
||||||
@@ -604,7 +609,7 @@ void CWriter::printConstantVector(ConstantVector *CP) {
|
|||||||
// only deal in IEEE FP).
|
// only deal in IEEE FP).
|
||||||
//
|
//
|
||||||
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
|
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)
|
if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
|
||||||
return false;
|
return false;
|
||||||
APFloat APF = APFloat(CFP->getValueAPF()); // copy
|
APFloat APF = APFloat(CFP->getValueAPF()); // copy
|
||||||
@@ -878,15 +883,22 @@ void CWriter::printConstant(Constant *CPV) {
|
|||||||
|
|
||||||
switch (CPV->getType()->getTypeID()) {
|
switch (CPV->getType()->getTypeID()) {
|
||||||
case Type::FloatTyID:
|
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);
|
ConstantFP *FPC = cast<ConstantFP>(CPV);
|
||||||
std::map<const ConstantFP*, unsigned>::iterator I = FPConstantMap.find(FPC);
|
std::map<const ConstantFP*, unsigned>::iterator I = FPConstantMap.find(FPC);
|
||||||
if (I != FPConstantMap.end()) {
|
if (I != FPConstantMap.end()) {
|
||||||
// Because of FP precision problems we must load from a stack allocated
|
// Because of FP precision problems we must load from a stack allocated
|
||||||
// value that holds the value in hex.
|
// 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 << ')';
|
<< "*)&FPConstant" << I->second << ')';
|
||||||
} else {
|
} else {
|
||||||
|
assert(FPC->getType() == Type::FloatTy ||
|
||||||
|
FPC->getType() == Type::DoubleTy);
|
||||||
double V = FPC->getType() == Type::FloatTy ?
|
double V = FPC->getType() == Type::FloatTy ?
|
||||||
FPC->getValueAPF().convertToFloat() :
|
FPC->getValueAPF().convertToFloat() :
|
||||||
FPC->getValueAPF().convertToDouble();
|
FPC->getValueAPF().convertToDouble();
|
||||||
@@ -1490,7 +1502,10 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
<< "\n\n/* Support for floating point constants */\n"
|
<< "\n\n/* Support for floating point constants */\n"
|
||||||
<< "typedef unsigned long long ConstantDoubleTy;\n"
|
<< "typedef unsigned long long ConstantDoubleTy;\n"
|
||||||
<< "typedef unsigned int ConstantFloatTy;\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";
|
<< "\n\n/* Global Declarations */\n";
|
||||||
|
|
||||||
// First output all the declarations for the program, because C requires
|
// First output all the declarations for the program, because C requires
|
||||||
@@ -1529,6 +1544,7 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
Out << "\n/* Function Declarations */\n";
|
Out << "\n/* Function Declarations */\n";
|
||||||
Out << "double fmod(double, double);\n"; // Support for FP rem
|
Out << "double fmod(double, double);\n"; // Support for FP rem
|
||||||
Out << "float fmodf(float, float);\n";
|
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) {
|
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||||
// Don't print declarations for intrinsic functions.
|
// Don't print declarations for intrinsic functions.
|
||||||
@@ -1711,6 +1727,13 @@ void CWriter::printFloatingPointConstants(Function &F) {
|
|||||||
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
||||||
<< " = 0x" << std::hex << i << std::dec
|
<< " = 0x" << std::hex << i << std::dec
|
||||||
<< "U; /* " << Val << " */\n";
|
<< "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
|
} else
|
||||||
assert(0 && "Unknown float type!");
|
assert(0 && "Unknown float type!");
|
||||||
}
|
}
|
||||||
@@ -2190,8 +2213,10 @@ void CWriter::visitBinaryOperator(Instruction &I) {
|
|||||||
// Output a call to fmod/fmodf instead of emitting a%b
|
// Output a call to fmod/fmodf instead of emitting a%b
|
||||||
if (I.getType() == Type::FloatTy)
|
if (I.getType() == Type::FloatTy)
|
||||||
Out << "fmodf(";
|
Out << "fmodf(";
|
||||||
else
|
else if (I.getType() == Type::DoubleTy)
|
||||||
Out << "fmod(";
|
Out << "fmod(";
|
||||||
|
else // all 3 flavors of long double
|
||||||
|
Out << "fmodl(";
|
||||||
writeOperand(I.getOperand(0));
|
writeOperand(I.getOperand(0));
|
||||||
Out << ", ";
|
Out << ", ";
|
||||||
writeOperand(I.getOperand(1));
|
writeOperand(I.getOperand(1));
|
||||||
|
Reference in New Issue
Block a user