mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-10 14:10:58 +00:00
Implement ppc long double->uint conversion.
Make ppc long double constants print. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42882 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f96e4de403
commit
fcf4d24ffb
@ -917,6 +917,39 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
|
||||
<< " long double most significant halfword\n";
|
||||
}
|
||||
return;
|
||||
} else if (CFP->getType() == Type::PPC_FP128Ty) {
|
||||
// all long double variants are printed as hex
|
||||
// api needed to prevent premature destruction
|
||||
APInt api = CFP->getValueAPF().convertToAPInt();
|
||||
const uint64_t *p = api.getRawData();
|
||||
if (TD->isBigEndian()) {
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double most significant word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[0])
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double next word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double next word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[1])
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double least significant word\n";
|
||||
} else {
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[1])
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double least significant word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double next word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[0])
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double next word\n";
|
||||
O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
|
||||
<< "\t" << TAI->getCommentString()
|
||||
<< " long double most significant word\n";
|
||||
}
|
||||
return;
|
||||
} else assert(0 && "Floating point constant type not handled");
|
||||
} else if (CV->getType() == Type::Int64Ty) {
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
|
@ -3322,17 +3322,35 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
}
|
||||
break;
|
||||
case Expand: {
|
||||
// Convert f32 / f64 to i32 / i64.
|
||||
MVT::ValueType VT = Op.getValueType();
|
||||
MVT::ValueType OVT = Node->getOperand(0).getValueType();
|
||||
// Convert ppcf128 to i32
|
||||
if (OVT == MVT::ppcf128 && VT == MVT::i32) {
|
||||
Result = DAG.getNode(ISD::FP_TO_SINT, VT,
|
||||
if (Node->getOpcode()==ISD::FP_TO_SINT)
|
||||
Result = DAG.getNode(ISD::FP_TO_SINT, VT,
|
||||
DAG.getNode(ISD::FP_ROUND, MVT::f64,
|
||||
(DAG.getNode(ISD::FP_ROUND_INREG,
|
||||
MVT::ppcf128, Node->getOperand(0),
|
||||
DAG.getValueType(MVT::f64)))));
|
||||
else {
|
||||
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
|
||||
APFloat apf = APFloat(APInt(128, 2, TwoE31));
|
||||
Tmp2 = DAG.getConstantFP(apf, OVT);
|
||||
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
|
||||
// FIXME: generated code sucks.
|
||||
Result = DAG.getNode(ISD::SELECT_CC, VT, Node->getOperand(0), Tmp2,
|
||||
DAG.getNode(ISD::ADD, MVT::i32,
|
||||
DAG.getNode(ISD::FP_TO_SINT, VT,
|
||||
DAG.getNode(ISD::FSUB, OVT,
|
||||
Node->getOperand(0), Tmp2)),
|
||||
DAG.getConstant(0x80000000, MVT::i32)),
|
||||
DAG.getNode(ISD::FP_TO_SINT, VT,
|
||||
Node->getOperand(0)),
|
||||
DAG.getCondCode(ISD::SETGE));
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Convert f32 / f64 to i32 / i64.
|
||||
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
||||
switch (Node->getOpcode()) {
|
||||
case ISD::FP_TO_SINT: {
|
||||
@ -5170,7 +5188,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
if (VT == MVT::ppcf128 &&
|
||||
TLI.getOperationAction(ISD::FP_ROUND_INREG, VT) ==
|
||||
TargetLowering::Custom) {
|
||||
SDOperand Result = TLI.LowerOperation(Op, DAG);
|
||||
SDOperand SrcLo, SrcHi, Src;
|
||||
ExpandOp(Op.getOperand(0), SrcLo, SrcHi);
|
||||
Src = DAG.getNode(ISD::BUILD_PAIR, VT, SrcLo, SrcHi);
|
||||
SDOperand Result = TLI.LowerOperation(
|
||||
DAG.getNode(ISD::FP_ROUND_INREG, VT, Src, Op.getOperand(1)), DAG);
|
||||
assert(Result.Val->getOpcode() == ISD::BUILD_PAIR);
|
||||
Lo = Result.Val->getOperand(0);
|
||||
Hi = Result.Val->getOperand(1);
|
||||
|
Loading…
Reference in New Issue
Block a user