From a471c2ecda37cd1bae0d94e832f002caa7b63216 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Thu, 11 Oct 2007 18:07:22 +0000 Subject: [PATCH] Next PPC long double bits. First cut at constants. No compile-time support for constant operations yet, just format transformations. Make readers and writers work. Split constants into 2 doubles in Legalize. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42865 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/APFloat.h | 14 +- lib/AsmParser/Lexer.cpp.cvs | 2 +- lib/AsmParser/Lexer.l | 2 +- lib/AsmParser/Lexer.l.cvs | 2 +- lib/Bitcode/Reader/BitcodeReader.cpp | 4 +- lib/Bitcode/Writer/BitcodeWriter.cpp | 4 +- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 8 ++ lib/Support/APFloat.cpp | 163 ++++++++++++++++++++++- lib/VMCore/AsmWriter.cpp | 6 +- lib/VMCore/Constants.cpp | 9 ++ 10 files changed, 196 insertions(+), 18 deletions(-) diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index f5511f42805..38d110d6e14 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -126,6 +126,7 @@ namespace llvm { static const fltSemantics IEEEsingle; static const fltSemantics IEEEdouble; static const fltSemantics IEEEquad; + static const fltSemantics PPCDoubleDouble; static const fltSemantics x87DoubleExtended; /* And this psuedo, used to construct APFloats that cannot conflict with anything real. */ @@ -175,7 +176,7 @@ namespace llvm { APFloat(const fltSemantics &, fltCategory, bool negative); explicit APFloat(double d); explicit APFloat(float f); - explicit APFloat(const APInt &); + explicit APFloat(const APInt &, bool isIEEE = false); APFloat(const APFloat &); ~APFloat(); @@ -276,10 +277,12 @@ namespace llvm { APInt convertFloatAPFloatToAPInt() const; APInt convertDoubleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; - void initFromAPInt(const APInt& api); + APInt convertPPCDoubleDoubleAPFloatToAPInt() const; + void initFromAPInt(const APInt& api, bool isIEEE = false); void initFromFloatAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api); void initFromF80LongDoubleAPInt(const APInt& api); + void initFromPPCDoubleDoubleAPInt(const APInt& api); void assign(const APFloat &); void copySignificand(const APFloat &); @@ -306,6 +309,13 @@ namespace llvm { /* The sign bit of this number. */ unsigned int sign: 1; + + /* For PPCDoubleDouble, we have a second exponent and sign (the second + significand is appended to the first one, although it would be wrong to + regard these as a single number for arithmetic purposes). These fields + are not meaningful for any other type. */ + exponent_t exponent2 : 11; + unsigned int sign2: 1; }; } /* namespace llvm */ diff --git a/lib/AsmParser/Lexer.cpp.cvs b/lib/AsmParser/Lexer.cpp.cvs index 6e2819f3f55..536d5696482 100644 --- a/lib/AsmParser/Lexer.cpp.cvs +++ b/lib/AsmParser/Lexer.cpp.cvs @@ -2199,7 +2199,7 @@ YY_RULE_SETUP #line 488 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } YY_BREAK diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 73e9c547712..0591cd99f3f 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -487,7 +487,7 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } } {HexFP128Constant} { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } {HexPPC128Constant} { uint64_t Pair[2]; diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs index 73e9c547712..0591cd99f3f 100644 --- a/lib/AsmParser/Lexer.l.cvs +++ b/lib/AsmParser/Lexer.l.cvs @@ -487,7 +487,7 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } } {HexFP128Constant} { uint64_t Pair[2]; HexToIntPair(yytext+3, Pair); - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); return FPVAL; } {HexPPC128Constant} { uint64_t Pair[2]; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 9e4a3dee60f..72785579967 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -632,9 +632,9 @@ bool BitcodeReader::ParseConstants() { else if (CurTy == Type::X86_FP80Ty) V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0]))); else if (CurTy == Type::FP128Ty) - V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]))); + V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]), true)); else if (CurTy == Type::PPC_FP128Ty) - assert(0 && "PowerPC long double constants not handled yet."); + V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]))); else V = UndefValue::get(CurTy); break; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 7999907c185..6bf27123c96 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -534,13 +534,11 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back((uint16_t)p[1]); - } else if (Ty == Type::FP128Ty) { + } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { APInt api = CFP->getValueAPF().convertToAPInt(); const uint64_t *p = api.getRawData(); Record.push_back(p[0]); Record.push_back(p[1]); - } else if (Ty == Type::PPC_FP128Ty) { - assert(0 && "PowerPC long double constants not handled yet."); } else { assert (0 && "Unknown FP type!"); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index ce28c79dc9c..87f39483cf6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -5196,6 +5196,14 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } case ISD::ConstantFP: { ConstantFPSDNode *CFP = cast(Node); + if (CFP->getValueType(0) == MVT::ppcf128) { + APInt api = CFP->getValueAPF().convertToAPInt(); + Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[1])), + MVT::f64); + Hi = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[0])), + MVT::f64); + break; + } Lo = ExpandConstantFP(CFP, false, DAG, TLI); if (getTypeAction(Lo.getValueType()) == Expand) ExpandOp(Lo, Lo, Hi); diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index d05c24e2e15..ab30a030a2b 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -50,6 +50,11 @@ namespace llvm { const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false }; const fltSemantics APFloat::Bogus = { 0, 0, 0, false }; + + // The PowerPC format consists of two doubles. It does not map cleanly + // onto the usual format above. For now only storage of constants of + // this type is supported, no arithmetic. + const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, true }; } /* Put a bunch of private, handy routines in an anonymous namespace. */ @@ -325,6 +330,8 @@ APFloat::assign(const APFloat &rhs) sign = rhs.sign; category = rhs.category; exponent = rhs.exponent; + sign2 = rhs.sign2; + exponent2 = rhs.exponent2; if(category == fcNormal || category == fcNaN) copySignificand(rhs); } @@ -361,10 +368,16 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { category != rhs.category || sign != rhs.sign) return false; + if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + sign2 != rhs.sign2) + return false; if (category==fcZero || category==fcInfinity) return true; else if (category==fcNormal && exponent!=rhs.exponent) return false; + else if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + exponent2!=rhs.exponent2) + return false; else { int i= partCount(); const integerPart* p=significandParts(); @@ -379,6 +392,8 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); sign = 0; zeroSignificand(); @@ -390,6 +405,8 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) APFloat::APFloat(const fltSemantics &ourSemantics, fltCategory ourCategory, bool negative) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); category = ourCategory; sign = negative; @@ -399,6 +416,8 @@ APFloat::APFloat(const fltSemantics &ourSemantics, APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); } @@ -1181,6 +1200,8 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, APFloat::opStatus APFloat::add(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, false); } @@ -1188,6 +1209,8 @@ APFloat::add(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, true); } @@ -1195,6 +1218,8 @@ APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; sign ^= rhs.sign; @@ -1214,6 +1239,8 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; sign ^= rhs.sign; @@ -1233,6 +1260,8 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; APFloat V = *this; unsigned int origSign = sign; @@ -1269,6 +1298,8 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, const APFloat &addend, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; /* Post-multiplication sign, before addition. */ @@ -1312,6 +1343,8 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, APFloat::cmpResult APFloat::compare(const APFloat &rhs) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); cmpResult result; assert(semantics == rhs.semantics); @@ -1385,6 +1418,8 @@ APFloat::opStatus APFloat::convert(const fltSemantics &toSemantics, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; @@ -1462,6 +1497,8 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width, bool isSigned, roundingMode rounding_mode) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; unsigned int msb, partsCount; int bits; @@ -1591,6 +1628,8 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src, bool isSigned, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); opStatus status; if (isSigned @@ -1618,6 +1657,8 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, unsigned int width, bool isSigned, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); unsigned int partCount = partCountForBits(width); APInt api = APInt(width, partCount, parts); @@ -1634,6 +1675,8 @@ APFloat::opStatus APFloat::convertFromHexadecimalString(const char *p, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; integerPart *significand; unsigned int bitPos, partsCount; @@ -1713,6 +1756,8 @@ APFloat::convertFromHexadecimalString(const char *p, APFloat::opStatus APFloat::convertFromString(const char *p, roundingMode rounding_mode) { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); /* Handle a leading minus sign. */ if(*p == '-') sign = 1, p++; @@ -1754,6 +1799,8 @@ unsigned int APFloat::convertToHexString(char *dst, unsigned int hexDigits, bool upperCase, roundingMode rounding_mode) const { + assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && + "Compile-time arithmetic on PPC long double not supported yet"); char *p; p = dst; @@ -1961,6 +2008,51 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const return APInt(80, 2, words); } +APInt +APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const +{ + assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble); + assert (partCount()==2); + + uint64_t myexponent, mysignificand, myexponent2, mysignificand2; + + if (category==fcNormal) { + myexponent = exponent + 1023; //bias + myexponent2 = exponent2 + 1023; + mysignificand = significandParts()[0]; + mysignificand2 = significandParts()[1]; + if (myexponent==1 && !(mysignificand & 0x10000000000000LL)) + myexponent = 0; // denormal + if (myexponent2==1 && !(mysignificand2 & 0x10000000000000LL)) + myexponent2 = 0; // denormal + } else if (category==fcZero) { + myexponent = 0; + mysignificand = 0; + myexponent2 = 0; + mysignificand2 = 0; + } else if (category==fcInfinity) { + myexponent = 0x7ff; + myexponent2 = 0; + mysignificand = 0; + mysignificand2 = 0; + } else { + assert(category == fcNaN && "Unknown category"); + myexponent = 0x7ff; + mysignificand = significandParts()[0]; + myexponent2 = exponent2; + mysignificand2 = significandParts()[1]; + } + + uint64_t words[2]; + words[0] = (((uint64_t)sign & 1) << 63) | + ((myexponent & 0x7ff) << 52) | + (mysignificand & 0xfffffffffffffLL); + words[1] = (((uint64_t)sign2 & 1) << 63) | + ((myexponent2 & 0x7ff) << 52) | + (mysignificand2 & 0xfffffffffffffLL); + return APInt(128, 2, words); +} + APInt APFloat::convertDoubleAPFloatToAPInt() const { @@ -2020,6 +2112,10 @@ APFloat::convertFloatAPFloatToAPInt() const (mysignificand & 0x7fffff))); } +// This function creates an APInt that is just a bit map of the floating +// point constant as it would appear in memory. It is not a conversion, +// and treating the result as a normal integer is unlikely to be useful. + APInt APFloat::convertToAPInt() const { @@ -2029,6 +2125,9 @@ APFloat::convertToAPInt() const if (semantics == (const llvm::fltSemantics* const)&IEEEdouble) return convertDoubleAPFloatToAPInt(); + if (semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble) + return convertPPCDoubleDoubleAPFloatToAPInt(); + assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended && "unknown format!"); return convertF80LongDoubleAPFloatToAPInt(); @@ -2090,6 +2189,56 @@ APFloat::initFromF80LongDoubleAPInt(const APInt &api) } } +void +APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) +{ + assert(api.getBitWidth()==128); + uint64_t i1 = api.getRawData()[0]; + uint64_t i2 = api.getRawData()[1]; + uint64_t myexponent = (i1 >> 52) & 0x7ff; + uint64_t mysignificand = i1 & 0xfffffffffffffLL; + uint64_t myexponent2 = (i2 >> 52) & 0x7ff; + uint64_t mysignificand2 = i2 & 0xfffffffffffffLL; + + initialize(&APFloat::PPCDoubleDouble); + assert(partCount()==2); + + sign = i1>>63; + sign2 = i2>>63; + if (myexponent==0 && mysignificand==0) { + // exponent, significand meaningless + // exponent2 and significand2 are required to be 0; we don't check + category = fcZero; + } else if (myexponent==0x7ff && mysignificand==0) { + // exponent, significand meaningless + // exponent2 and significand2 are required to be 0; we don't check + category = fcInfinity; + } else if (myexponent==0x7ff && mysignificand!=0) { + // exponent meaningless. So is the whole second word, but keep it + // for determinism. + category = fcNaN; + exponent2 = myexponent2; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + } else { + category = fcNormal; + // Note there is no category2; the second word is treated as if it is + // fcNormal, although it might be something else considered by itself. + exponent = myexponent - 1023; + exponent2 = myexponent2 - 1023; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + if (myexponent==0) // denormal + exponent = -1022; + else + significandParts()[0] |= 0x10000000000000LL; // integer bit + if (myexponent2==0) + exponent2 = -1022; + else + significandParts()[1] |= 0x10000000000000LL; // integer bit + } +} + void APFloat::initFromDoubleAPInt(const APInt &api) { @@ -2157,11 +2306,11 @@ APFloat::initFromFloatAPInt(const APInt & api) } /// Treat api as containing the bits of a floating point number. Currently -/// we infer the floating point type from the size of the APInt. FIXME: This -/// breaks when we get to PPC128 and IEEE128 (but both cannot exist in the -/// same compile...) +/// we infer the floating point type from the size of the APInt. The +/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful +/// when the size is anything else). void -APFloat::initFromAPInt(const APInt& api) +APFloat::initFromAPInt(const APInt& api, bool isIEEE) { if (api.getBitWidth() == 32) return initFromFloatAPInt(api); @@ -2169,13 +2318,15 @@ APFloat::initFromAPInt(const APInt& api) return initFromDoubleAPInt(api); else if (api.getBitWidth()==80) return initFromF80LongDoubleAPInt(api); + else if (api.getBitWidth()==128 && !isIEEE) + return initFromPPCDoubleDoubleAPInt(api); else assert(0); } -APFloat::APFloat(const APInt& api) +APFloat::APFloat(const APInt& api, bool isIEEE) { - initFromAPInt(api); + initFromAPInt(api, isIEEE); } APFloat::APFloat(float f) diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 6fb55165be7..9592151c6d9 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -519,6 +519,8 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << 'K'; else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) Out << 'L'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) + Out << 'M'; else assert(0 && "Unsupported floating point type"); // api needed to prevent premature destruction @@ -526,7 +528,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, const uint64_t* p = api.getRawData(); uint64_t word = *p; int shiftcount=60; - int width = CFP->getValueAPF().convertToAPInt().getBitWidth(); + int width = api.getBitWidth(); for (int j=0; j>shiftcount) & 15; if (nibble < 10) @@ -535,7 +537,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << (unsigned char)(nibble - 10 + 'A'); if (shiftcount == 0) { word = *(++p); - shiftcount = 60; + shiftcount = 64; if (width-j-4 < 64) shiftcount = width-j-4; } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 7de823b1ba5..350a306d797 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -114,6 +114,7 @@ Constant *Constant::getNullValue(const Type *Ty) { case Type::X86_FP80TyID: return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero))); case Type::FP128TyID: + return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero), true)); case Type::PPC_FP128TyID: return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero))); case Type::PointerTyID: @@ -256,6 +257,8 @@ ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) assert(&V.getSemantics()==&APFloat::x87DoubleExtended); else if (Ty==Type::FP128Ty) assert(&V.getSemantics()==&APFloat::IEEEquad); + else if (Ty==Type::PPC_FP128Ty) + assert(&V.getSemantics()==&APFloat::PPCDoubleDouble); else assert(0); } @@ -320,6 +323,8 @@ ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) { assert(&V.getSemantics()==&APFloat::x87DoubleExtended); else if (Ty==Type::FP128Ty) assert(&V.getSemantics()==&APFloat::IEEEquad); + else if (Ty==Type::PPC_FP128Ty) + assert(&V.getSemantics()==&APFloat::PPCDoubleDouble); else assert(0); @@ -747,6 +752,10 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { return &Val2.getSemantics() == &APFloat::IEEEsingle || &Val2.getSemantics() == &APFloat::IEEEdouble || &Val2.getSemantics() == &APFloat::IEEEquad; + case Type::PPC_FP128TyID: + return &Val2.getSemantics() == &APFloat::IEEEsingle || + &Val2.getSemantics() == &APFloat::IEEEdouble || + &Val2.getSemantics() == &APFloat::PPCDoubleDouble; } } -- 2.34.1