LegalizeIntegerTypes.cpp revision 193574
113675Sdyson//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===// 213675Sdyson// 313675Sdyson// The LLVM Compiler Infrastructure 413675Sdyson// 513675Sdyson// This file is distributed under the University of Illinois Open Source 613675Sdyson// License. See LICENSE.TXT for details. 713675Sdyson// 813675Sdyson//===----------------------------------------------------------------------===// 913675Sdyson// 1013675Sdyson// This file implements integer type expansion and promotion for LegalizeTypes. 1113675Sdyson// Promotion is the act of changing a computation in an illegal type into a 1213675Sdyson// computation in a larger type. For example, implementing i8 arithmetic in an 1313675Sdyson// i32 register (often needed on powerpc). 1413675Sdyson// Expansion is the act of changing a computation in an illegal type into a 1513675Sdyson// computation in two identical registers of a smaller type. For example, 1614037Sdyson// implementing i64 arithmetic in two i32 registers (often needed on 32-bit 1713675Sdyson// targets). 1813675Sdyson// 1913675Sdyson//===----------------------------------------------------------------------===// 2013675Sdyson 2113675Sdyson#include "LegalizeTypes.h" 2213675Sdyson#include "llvm/CodeGen/PseudoSourceValue.h" 2313675Sdysonusing namespace llvm; 2413675Sdyson 2513675Sdyson//===----------------------------------------------------------------------===// 2613675Sdyson// Integer Result Promotion 2713907Sdyson//===----------------------------------------------------------------------===// 2813907Sdyson 2913907Sdyson/// PromoteIntegerResult - This method is called when a result of a node is 3013907Sdyson/// found to be in need of promotion to a larger type. At this point, the node 3113907Sdyson/// may also have invalid operands or may have other results that need 3213907Sdyson/// expansion, we just know that (at least) one result needs promotion. 3313907Sdysonvoid DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { 3413907Sdyson DEBUG(cerr << "Promote integer result: "; N->dump(&DAG); cerr << "\n"); 3513907Sdyson SDValue Res = SDValue(); 3613907Sdyson 3713913Sdyson // See if the target wants to custom expand this node. 3813907Sdyson if (CustomLowerNode(N, N->getValueType(ResNo), true)) 3913907Sdyson return; 4013907Sdyson 4113907Sdyson switch (N->getOpcode()) { 4213907Sdyson default: 4313907Sdyson#ifndef NDEBUG 4413907Sdyson cerr << "PromoteIntegerResult #" << ResNo << ": "; 4513907Sdyson N->dump(&DAG); cerr << "\n"; 46118764Ssilby#endif 47117325Ssilby assert(0 && "Do not know how to promote this operator!"); 48118764Ssilby abort(); 49117325Ssilby case ISD::AssertSext: Res = PromoteIntRes_AssertSext(N); break; 50118764Ssilby case ISD::AssertZext: Res = PromoteIntRes_AssertZext(N); break; 51118764Ssilby case ISD::BIT_CONVERT: Res = PromoteIntRes_BIT_CONVERT(N); break; 52118764Ssilby case ISD::BSWAP: Res = PromoteIntRes_BSWAP(N); break; 53118764Ssilby case ISD::BUILD_PAIR: Res = PromoteIntRes_BUILD_PAIR(N); break; 54118764Ssilby case ISD::Constant: Res = PromoteIntRes_Constant(N); break; 55117325Ssilby case ISD::CONVERT_RNDSAT: 56117325Ssilby Res = PromoteIntRes_CONVERT_RNDSAT(N); break; 57117325Ssilby case ISD::CTLZ: Res = PromoteIntRes_CTLZ(N); break; 58117325Ssilby case ISD::CTPOP: Res = PromoteIntRes_CTPOP(N); break; 59118764Ssilby case ISD::CTTZ: Res = PromoteIntRes_CTTZ(N); break; 60117325Ssilby case ISD::EXTRACT_VECTOR_ELT: 61117325Ssilby Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break; 62117325Ssilby case ISD::LOAD: Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break; 63117325Ssilby case ISD::SELECT: Res = PromoteIntRes_SELECT(N); break; 64117325Ssilby case ISD::SELECT_CC: Res = PromoteIntRes_SELECT_CC(N); break; 65117325Ssilby case ISD::SETCC: Res = PromoteIntRes_SETCC(N); break; 6613907Sdyson case ISD::SHL: Res = PromoteIntRes_SHL(N); break; 6713907Sdyson case ISD::SIGN_EXTEND_INREG: 68116182Sobrien Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break; 69116182Sobrien case ISD::SRA: Res = PromoteIntRes_SRA(N); break; 70116182Sobrien case ISD::SRL: Res = PromoteIntRes_SRL(N); break; 71101768Srwatson case ISD::TRUNCATE: Res = PromoteIntRes_TRUNCATE(N); break; 72101768Srwatson case ISD::UNDEF: Res = PromoteIntRes_UNDEF(N); break; 7313675Sdyson case ISD::VAARG: Res = PromoteIntRes_VAARG(N); break; 7413675Sdyson 7524131Sbde case ISD::SIGN_EXTEND: 7613675Sdyson case ISD::ZERO_EXTEND: 7713675Sdyson case ISD::ANY_EXTEND: Res = PromoteIntRes_INT_EXTEND(N); break; 7824206Sbde 7991372Salfred case ISD::FP_TO_SINT: 8076166Smarkm case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break; 81101768Srwatson 8276827Salfred case ISD::AND: 8324206Sbde case ISD::OR: 8413675Sdyson case ISD::XOR: 8591968Salfred case ISD::ADD: 8629356Speter case ISD::SUB: 8770834Swollman case ISD::MUL: Res = PromoteIntRes_SimpleIntBinOp(N); break; 8813675Sdyson 89117325Ssilby case ISD::SDIV: 9013675Sdyson case ISD::SREM: Res = PromoteIntRes_SDIV(N); break; 9113675Sdyson 9276166Smarkm case ISD::UDIV: 9355112Sbde case ISD::UREM: Res = PromoteIntRes_UDIV(N); break; 9434924Sbde 9559288Sjlemon case ISD::SADDO: 9613675Sdyson case ISD::SSUBO: Res = PromoteIntRes_SADDSUBO(N, ResNo); break; 9713675Sdyson case ISD::UADDO: 9813675Sdyson case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break; 9913675Sdyson case ISD::SMULO: 10013675Sdyson case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break; 10113675Sdyson 10213675Sdyson case ISD::ATOMIC_LOAD_ADD: 10313675Sdyson case ISD::ATOMIC_LOAD_SUB: 10413907Sdyson case ISD::ATOMIC_LOAD_AND: 10592751Sjeff case ISD::ATOMIC_LOAD_OR: 10613675Sdyson case ISD::ATOMIC_LOAD_XOR: 10714037Sdyson case ISD::ATOMIC_LOAD_NAND: 10814037Sdyson case ISD::ATOMIC_LOAD_MIN: 10914037Sdyson case ISD::ATOMIC_LOAD_MAX: 11014037Sdyson case ISD::ATOMIC_LOAD_UMIN: 11114037Sdyson case ISD::ATOMIC_LOAD_UMAX: 11214037Sdyson case ISD::ATOMIC_SWAP: 11314037Sdyson Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break; 11414037Sdyson 11514037Sdyson case ISD::ATOMIC_CMP_SWAP: 11614037Sdyson Res = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break; 117108255Sphk } 118108255Sphk 119108255Sphk // If the result is null then the sub-method took care of registering it. 120108255Sphk if (Res.getNode()) 121108255Sphk SetPromotedInteger(SDValue(N, ResNo), Res); 122108255Sphk} 123108255Sphk 12413675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { 12572521Sjlemon // Sign-extend the new bits, and continue the assertion. 126116546Sphk SDValue Op = SExtPromotedInteger(N->getOperand(0)); 127116546Sphk return DAG.getNode(ISD::AssertSext, N->getDebugLoc(), 128116546Sphk Op.getValueType(), Op, N->getOperand(1)); 129116546Sphk} 130116546Sphk 131116546SphkSDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { 132116546Sphk // Zero the new bits, and continue the assertion. 133116546Sphk SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 13472521Sjlemon return DAG.getNode(ISD::AssertZext, N->getDebugLoc(), 13513675Sdyson Op.getValueType(), Op, N->getOperand(1)); 13659288Sjlemon} 13759288Sjlemon 13859288SjlemonSDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { 13959288Sjlemon SDValue Op2 = GetPromotedInteger(N->getOperand(2)); 14072521Sjlemon SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), 14172521Sjlemon N->getMemoryVT(), 14272521Sjlemon N->getChain(), N->getBasePtr(), 14372521Sjlemon Op2, N->getSrcValue(), N->getAlignment()); 14459288Sjlemon // Legalized the chain result - switch anything that used the old chain to 14592305Salfred // use the new one. 14691362Salfred ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 14792305Salfred return Res; 14892305Salfred} 14992305Salfred 15092305SalfredSDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) { 15191362Salfred SDValue Op2 = GetPromotedInteger(N->getOperand(2)); 15291362Salfred SDValue Op3 = GetPromotedInteger(N->getOperand(3)); 15372521Sjlemon SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), 15491362Salfred N->getMemoryVT(), N->getChain(), N->getBasePtr(), 15591362Salfred Op2, Op3, N->getSrcValue(), N->getAlignment()); 15691362Salfred // Legalized the chain result - switch anything that used the old chain to 15792305Salfred // use the new one. 15891362Salfred ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 15991362Salfred return Res; 16013675Sdyson} 16113675Sdyson 16213675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { 16313675Sdyson SDValue InOp = N->getOperand(0); 16413675Sdyson MVT InVT = InOp.getValueType(); 16513675Sdyson MVT NInVT = TLI.getTypeToTransformTo(InVT); 16613907Sdyson MVT OutVT = N->getValueType(0); 16713907Sdyson MVT NOutVT = TLI.getTypeToTransformTo(OutVT); 16813675Sdyson DebugLoc dl = N->getDebugLoc(); 16913907Sdyson 17017163Sdyson switch (getTypeAction(InVT)) { 17117163Sdyson default: 17217163Sdyson assert(false && "Unknown type action!"); 17333181Seivind break; 17417163Sdyson case Legal: 175117325Ssilby break; 17617124Sbde case PromoteInteger: 177117325Ssilby if (NOutVT.bitsEq(NInVT)) 17813907Sdyson // The input promotes to the same size. Convert the promoted value. 179117325Ssilby return DAG.getNode(ISD::BIT_CONVERT, dl, 180117325Ssilby NOutVT, GetPromotedInteger(InOp)); 181118764Ssilby break; 182117325Ssilby case SoftenFloat: 183117325Ssilby // Promote the integer operand by hand. 184117325Ssilby return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp)); 185117325Ssilby case ExpandInteger: 186117364Ssilby case ExpandFloat: 187117364Ssilby break; 188117364Ssilby case ScalarizeVector: 189117325Ssilby // Convert the element to an integer and promote it by hand. 190117325Ssilby return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, 191117325Ssilby BitConvertToInteger(GetScalarizedVector(InOp))); 192117325Ssilby case SplitVector: { 193117325Ssilby // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split 19491413Salfred // pieces of the input into integers and reassemble in the final type. 19591413Salfred SDValue Lo, Hi; 19691413Salfred GetSplitVector(N->getOperand(0), Lo, Hi); 19791413Salfred Lo = BitConvertToInteger(Lo); 19891413Salfred Hi = BitConvertToInteger(Hi); 19991413Salfred 20091413Salfred if (TLI.isBigEndian()) 20114037Sdyson std::swap(Lo, Hi); 20291413Salfred 20391413Salfred InOp = DAG.getNode(ISD::ANY_EXTEND, dl, 20491413Salfred MVT::getIntegerVT(NOutVT.getSizeInBits()), 20591413Salfred JoinIntegers(Lo, Hi)); 20614037Sdyson return DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, InOp); 20791413Salfred } 20813675Sdyson case WidenVector: 20992751Sjeff if (OutVT.bitsEq(NInVT)) 21027899Sdyson // The input is widened to the same size. Convert to the widened value. 21191372Salfred return DAG.getNode(ISD::BIT_CONVERT, dl, OutVT, GetWidenedVector(InOp)); 21291372Salfred } 21391372Salfred 21491372Salfred // Otherwise, lower the bit-convert to a store/load from the stack. 21591372Salfred // Create the stack frame object. Make sure it is aligned for both 21692654Sjeff // the source and destination types. 21792654Sjeff SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT); 21891372Salfred int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex(); 21991372Salfred const Value *SV = PseudoSourceValue::getFixedStack(FI); 22013675Sdyson 22113675Sdyson // Emit a store to the stack slot. 22213675Sdyson SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0); 22313675Sdyson 22413675Sdyson // Result is an extending load from the stack slot. 22513675Sdyson return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, SV, 0, OutVT); 22683366Sjulian} 22783366Sjulian 22813675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) { 22913675Sdyson SDValue Op = GetPromotedInteger(N->getOperand(0)); 23013675Sdyson MVT OVT = N->getValueType(0); 23113675Sdyson MVT NVT = Op.getValueType(); 23283366Sjulian DebugLoc dl = N->getDebugLoc(); 23313675Sdyson 23413675Sdyson unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 23591968Salfred return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op), 23613675Sdyson DAG.getConstant(DiffBits, TLI.getPointerTy())); 23791362Salfred} 23891372Salfred 23927899SdysonSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) { 240111119Simp // The pair element type may be legal, or may not promote to the same type as 24191968Salfred // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases. 24276756Salfred return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), 24376364Salfred TLI.getTypeToTransformTo(N->getValueType(0)), 24476364Salfred JoinIntegers(N->getOperand(0), N->getOperand(1))); 24576364Salfred} 24691968Salfred 24776364SalfredSDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) { 24876364Salfred MVT VT = N->getValueType(0); 24976364Salfred // FIXME there is no actual debug info here 25013907Sdyson DebugLoc dl = N->getDebugLoc(); 25113907Sdyson // Zero extend things like i1, sign extend everything else. It shouldn't 25213675Sdyson // matter in theory which one we pick, but this tends to give better code? 25383366Sjulian unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 25470915Sdwmalone SDValue Result = DAG.getNode(Opc, dl, TLI.getTypeToTransformTo(VT), 25570915Sdwmalone SDValue(N, 0)); 25670915Sdwmalone assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?"); 25791968Salfred return Result; 25870915Sdwmalone} 25970915Sdwmalone 26070915SdwmaloneSDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) { 26183366Sjulian ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 26270915Sdwmalone assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU || 26370803Sdwmalone CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU || 26470803Sdwmalone CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) && 26570803Sdwmalone "can only promote integers"); 26670803Sdwmalone MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0)); 26770803Sdwmalone return DAG.getConvertRndSat(OutVT, N->getDebugLoc(), N->getOperand(0), 26870803Sdwmalone N->getOperand(1), N->getOperand(2), 26989306Salfred N->getOperand(3), N->getOperand(4), CvtCode); 27013675Sdyson} 27113675Sdyson 272109153SdillonSDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) { 27313675Sdyson // Zero extend to the promoted type and do the count there. 27489306Salfred SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 27583366Sjulian DebugLoc dl = N->getDebugLoc(); 27670915Sdwmalone MVT OVT = N->getValueType(0); 27789306Salfred MVT NVT = Op.getValueType(); 27883366Sjulian Op = DAG.getNode(ISD::CTLZ, dl, NVT, Op); 27983366Sjulian // Subtract off the extra leading bits in the bigger type. 28089306Salfred return DAG.getNode(ISD::SUB, dl, NVT, Op, 28183366Sjulian DAG.getConstant(NVT.getSizeInBits() - 28289306Salfred OVT.getSizeInBits(), NVT)); 28389306Salfred} 28483366Sjulian 28570915SdwmaloneSDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) { 28670915Sdwmalone // Zero extend to the promoted type and do the count there. 28791968Salfred SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 28870915Sdwmalone return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op); 28970915Sdwmalone} 29089306Salfred 29113675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { 29213675Sdyson SDValue Op = GetPromotedInteger(N->getOperand(0)); 293109153Sdillon MVT OVT = N->getValueType(0); 29413675Sdyson MVT NVT = Op.getValueType(); 29589306Salfred DebugLoc dl = N->getDebugLoc(); 29683366Sjulian // The count is the same in the promoted type except if the original 29713675Sdyson // value was zero. This can be handled by setting the bit just off 29813675Sdyson // the top of the original type. 299101768Srwatson APInt TopBit(NVT.getSizeInBits(), 0); 300101768Srwatson TopBit.set(OVT.getSizeInBits()); 301101768Srwatson Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT)); 302101768Srwatson return DAG.getNode(ISD::CTTZ, dl, NVT, Op); 303101768Srwatson} 304101768Srwatson 305101768SrwatsonSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { 306101768Srwatson MVT OldVT = N->getValueType(0); 307101768Srwatson SDValue OldVec = N->getOperand(0); 308101768Srwatson if (getTypeAction(OldVec.getValueType()) == WidenVector) 30993818Sjhb OldVec = GetWidenedVector(N->getOperand(0)); 31091968Salfred unsigned OldElts = OldVec.getValueType().getVectorNumElements(); 31183366Sjulian DebugLoc dl = N->getDebugLoc(); 31213675Sdyson 31313675Sdyson if (OldElts == 1) { 31413675Sdyson assert(!isTypeLegal(OldVec.getValueType()) && 31513675Sdyson "Legal one-element vector of a type needing promotion!"); 31613909Sdyson // It is tempting to follow GetScalarizedVector by a call to 31713909Sdyson // GetPromotedInteger, but this would be wrong because the 31876364Salfred // scalarized value may not yet have been processed. 31976364Salfred return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), 32076364Salfred GetScalarizedVector(OldVec)); 32113909Sdyson } 32276364Salfred 32376364Salfred // Convert to a vector half as long with an element type of twice the width, 32413675Sdyson // for example <4 x i16> -> <2 x i32>. 32576364Salfred assert(!(OldElts & 1) && "Odd length vectors not supported!"); 32613675Sdyson MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits()); 32776364Salfred assert(OldVT.isSimple() && NewVT.isSimple()); 32876364Salfred 32913688Sdyson SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, 330117325Ssilby MVT::getVectorVT(NewVT, OldElts / 2), 331117325Ssilby OldVec); 33213675Sdyson 33391412Salfred // Extract the element at OldIdx / 2 from the new vector. 33491412Salfred SDValue OldIdx = N->getOperand(1); 33579224Sdillon SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx, 336118764Ssilby DAG.getConstant(1, TLI.getPointerTy())); 337118764Ssilby SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx); 33813675Sdyson 33913675Sdyson // Select the appropriate half of the element: Lo if OldIdx was even, 34013675Sdyson // Hi if it was odd. 34114037Sdyson SDValue Lo = Elt; 34213675Sdyson SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt, 34376364Salfred DAG.getConstant(OldVT.getSizeInBits(), 344118764Ssilby TLI.getPointerTy())); 34513675Sdyson if (TLI.isBigEndian()) 34613675Sdyson std::swap(Lo, Hi); 34713675Sdyson 34813675Sdyson // Extend to the promoted type. 34914037Sdyson SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx); 35013675Sdyson SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo); 351118764Ssilby return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res); 35276364Salfred} 35313688Sdyson 35413675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { 35576364Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 35676364Salfred unsigned NewOpc = N->getOpcode(); 357118764Ssilby DebugLoc dl = N->getDebugLoc(); 358118764Ssilby 35976364Salfred // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is 36076364Salfred // not Legal, check to see if we can use FP_TO_SINT instead. (If both UINT 36176364Salfred // and SINT conversions are Custom, there is no way to tell which is preferable. 36276364Salfred // We choose SINT because that's the right thing on PPC.) 36376364Salfred if (N->getOpcode() == ISD::FP_TO_UINT && 36476364Salfred !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && 36576364Salfred TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT)) 36676364Salfred NewOpc = ISD::FP_TO_SINT; 36776364Salfred 36876364Salfred SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0)); 36976364Salfred 370117325Ssilby // Assert that the converted value fits in the original type. If it doesn't 371110816Salc // (eg: because the value being converted is too big), then the result of the 37276364Salfred // original operation was undefined anyway, so the assert is still correct. 37313907Sdyson return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ? 37413688Sdyson ISD::AssertZext : ISD::AssertSext, dl, 37513907Sdyson NVT, Res, DAG.getValueType(N->getValueType(0))); 37613907Sdyson} 37713907Sdyson 37876364SalfredSDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { 37976364Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 38076364Salfred DebugLoc dl = N->getDebugLoc(); 38176364Salfred 38213907Sdyson if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) { 38376364Salfred SDValue Res = GetPromotedInteger(N->getOperand(0)); 38413907Sdyson assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!"); 385111119Simp 38676364Salfred // If the result and operand types are the same after promotion, simplify 38776364Salfred // to an in-register extension. 38817163Sdyson if (NVT == Res.getValueType()) { 38976364Salfred // The high bits are not guaranteed to be anything. Insert an extend. 39076364Salfred if (N->getOpcode() == ISD::SIGN_EXTEND) 39176364Salfred return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, 39276364Salfred DAG.getValueType(N->getOperand(0).getValueType())); 39376364Salfred if (N->getOpcode() == ISD::ZERO_EXTEND) 39476364Salfred return DAG.getZeroExtendInReg(Res, dl, N->getOperand(0).getValueType()); 39576364Salfred assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); 39676364Salfred return Res; 39776754Salfred } 39813675Sdyson } 39913675Sdyson 40013675Sdyson // Otherwise, just extend the original operand all the way to the larger type. 40113907Sdyson return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0)); 40214037Sdyson} 40313907Sdyson 40413907SdysonSDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { 40513907Sdyson assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 40613907Sdyson MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 40713907Sdyson ISD::LoadExtType ExtType = 40813907Sdyson ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); 40913907Sdyson DebugLoc dl = N->getDebugLoc(); 41017124Sbde SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(), 41114037Sdyson N->getSrcValue(), N->getSrcValueOffset(), 41276364Salfred N->getMemoryVT(), N->isVolatile(), 41391412Salfred N->getAlignment()); 414117325Ssilby 415117325Ssilby // Legalized the chain result - switch anything that used the old chain to 416117325Ssilby // use the new one. 417118764Ssilby ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 418117325Ssilby return Res; 419117325Ssilby} 420117325Ssilby 42176760Salfred/// Promote the overflow flag of an overflowing arithmetic node. 42276364SalfredSDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) { 42376364Salfred // Simply change the return type of the boolean result. 42476364Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1)); 42576364Salfred MVT ValueVTs[] = { N->getValueType(0), NVT }; 42676364Salfred SDValue Ops[] = { N->getOperand(0), N->getOperand(1) }; 42776364Salfred SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(), 42876364Salfred DAG.getVTList(ValueVTs, 2), Ops, 2); 42913675Sdyson 43013675Sdyson // Modified the sum result - switch anything that used the old sum to use 43113675Sdyson // the new one. 43213675Sdyson ReplaceValueWith(SDValue(N, 0), Res); 43313675Sdyson 43413675Sdyson return SDValue(Res.getNode(), 1); 43513675Sdyson} 43613907Sdyson 43713675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) { 43813907Sdyson if (ResNo == 1) 43913675Sdyson return PromoteIntRes_Overflow(N); 44013776Sdyson 44176364Salfred // The operation overflowed iff the result in the larger type is not the 44291362Salfred // sign extension of its truncation to the original type. 44391362Salfred SDValue LHS = SExtPromotedInteger(N->getOperand(0)); 44413675Sdyson SDValue RHS = SExtPromotedInteger(N->getOperand(1)); 44591362Salfred MVT OVT = N->getOperand(0).getValueType(); 44691362Salfred MVT NVT = LHS.getValueType(); 44776760Salfred DebugLoc dl = N->getDebugLoc(); 44876760Salfred 44976760Salfred // Do the arithmetic in the larger type. 45013675Sdyson unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB; 45191362Salfred SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); 45276760Salfred 45313675Sdyson // Calculate the overflow flag: sign extend the arithmetic result from 45413675Sdyson // the original type. 45513675Sdyson SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, 45613675Sdyson DAG.getValueType(OVT)); 45713675Sdyson // Overflowed if and only if this is not equal to Res. 45813675Sdyson Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); 45913675Sdyson 46013675Sdyson // Use the calculated overflow everywhere. 46113675Sdyson ReplaceValueWith(SDValue(N, 1), Ofl); 46276364Salfred 46391362Salfred return Res; 46491362Salfred} 46513675Sdyson 46613675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) { 46714177Sdyson // Sign extend the input. 46813675Sdyson SDValue LHS = SExtPromotedInteger(N->getOperand(0)); 46913675Sdyson SDValue RHS = SExtPromotedInteger(N->getOperand(1)); 47013675Sdyson return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 47114037Sdyson LHS.getValueType(), LHS, RHS); 47214037Sdyson} 47314037Sdyson 47414037SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) { 47576364Salfred SDValue LHS = GetPromotedInteger(N->getOperand(1)); 47614037Sdyson SDValue RHS = GetPromotedInteger(N->getOperand(2)); 47714037Sdyson return DAG.getNode(ISD::SELECT, N->getDebugLoc(), 47814037Sdyson LHS.getValueType(), N->getOperand(0),LHS,RHS); 47914037Sdyson} 48041086Struckman 48195883SalfredSDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { 48259288Sjlemon SDValue LHS = GetPromotedInteger(N->getOperand(2)); 48314037Sdyson SDValue RHS = GetPromotedInteger(N->getOperand(3)); 48414037Sdyson return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), 48513675Sdyson LHS.getValueType(), N->getOperand(0), 48613675Sdyson N->getOperand(1), LHS, RHS, N->getOperand(4)); 487101941Srwatson} 48813675Sdyson 48913675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { 490101941Srwatson MVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType()); 49183366Sjulian assert(isTypeLegal(SVT) && "Illegal SetCC type!"); 49245311Sdt DebugLoc dl = N->getDebugLoc(); 49313675Sdyson 494109153Sdillon // Get the SETCC result using the canonical SETCC type. 49547748Salc SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0), 49613675Sdyson N->getOperand(1), N->getOperand(2)); 49718863Sdyson 49813675Sdyson // Convert to the expected type. 49991362Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 50013675Sdyson assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); 50147748Salc return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC); 50247748Salc} 50347748Salc 50447748SalcSDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) { 505101768Srwatson return DAG.getNode(ISD::SHL, N->getDebugLoc(), 506102115Srwatson TLI.getTypeToTransformTo(N->getValueType(0)), 507101768Srwatson GetPromotedInteger(N->getOperand(0)), N->getOperand(1)); 508101768Srwatson} 509101768Srwatson 510101768SrwatsonSDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) { 51113675Sdyson SDValue Op = GetPromotedInteger(N->getOperand(0)); 51213907Sdyson return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), 51313907Sdyson Op.getValueType(), Op, N->getOperand(1)); 51413907Sdyson} 51513675Sdyson 51618863SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) { 51713675Sdyson // The input may have strange things in the top bits of the registers, but 51813675Sdyson // these operations don't care. They may have weird bits going out, but 51918863Sdyson // that too is okay if they are integer operations. 52018863Sdyson SDValue LHS = GetPromotedInteger(N->getOperand(0)); 52147748Salc SDValue RHS = GetPromotedInteger(N->getOperand(1)); 52291362Salfred return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 523116127Smux LHS.getValueType(), LHS, RHS); 524116127Smux} 525116127Smux 52691362SalfredSDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) { 52776760Salfred // The input value must be properly sign extended. 52813675Sdyson SDValue Res = SExtPromotedInteger(N->getOperand(0)); 52976760Salfred return DAG.getNode(ISD::SRA, N->getDebugLoc(), 53013675Sdyson Res.getValueType(), Res, N->getOperand(1)); 53113675Sdyson} 53213675Sdyson 53313675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { 53413675Sdyson // The input value must be properly zero extended. 53547748Salc MVT VT = N->getValueType(0); 53647748Salc MVT NVT = TLI.getTypeToTransformTo(VT); 53747748Salc SDValue Res = ZExtPromotedInteger(N->getOperand(0)); 53847748Salc return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1)); 53947748Salc} 54047748Salc 54147748SalcSDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { 54247748Salc MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 54347748Salc SDValue Res; 54447748Salc 54513675Sdyson switch (getTypeAction(N->getOperand(0).getValueType())) { 54614037Sdyson default: assert(0 && "Unknown type action!"); 54713907Sdyson case Legal: 54813907Sdyson case ExpandInteger: 54913907Sdyson Res = N->getOperand(0); 55013907Sdyson break; 55147748Salc case PromoteInteger: 55247748Salc Res = GetPromotedInteger(N->getOperand(0)); 55318863Sdyson break; 55418863Sdyson } 55547748Salc 55676760Salfred // Truncate to NVT instead of VT 55776760Salfred return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res); 55891362Salfred} 55947748Salc 56091362SalfredSDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) { 56113907Sdyson if (ResNo == 1) 56213907Sdyson return PromoteIntRes_Overflow(N); 56313907Sdyson 56413907Sdyson // The operation overflowed iff the result in the larger type is not the 56513907Sdyson // zero extension of its truncation to the original type. 56613907Sdyson SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); 56713907Sdyson SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); 56813907Sdyson MVT OVT = N->getOperand(0).getValueType(); 56913907Sdyson MVT NVT = LHS.getValueType(); 57014037Sdyson DebugLoc dl = N->getDebugLoc(); 57113675Sdyson 57213675Sdyson // Do the arithmetic in the larger type. 57313675Sdyson unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB; 57476760Salfred SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); 57513675Sdyson 57676760Salfred // Calculate the overflow flag: zero extend the arithmetic result from 57713675Sdyson // the original type. 57843623Sdillon SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT); 57913675Sdyson // Overflowed if and only if this is not equal to Res. 58013675Sdyson Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); 58113675Sdyson 58213675Sdyson // Use the calculated overflow everywhere. 58313675Sdyson ReplaceValueWith(SDValue(N, 1), Ofl); 58413675Sdyson 58513675Sdyson return Res; 58643623Sdillon} 58743623Sdillon 58847748SalcSDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { 58943623Sdillon // Zero extend the input. 59047748Salc SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); 59113675Sdyson SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); 59216960Sdyson return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 59343623Sdillon LHS.getValueType(), LHS, RHS); 594116127Smux} 595116127Smux 596116127SmuxSDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) { 59743623Sdillon return DAG.getUNDEF(TLI.getTypeToTransformTo(N->getValueType(0))); 59847748Salc} 59943623Sdillon 60013675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { 60147748Salc SDValue Chain = N->getOperand(0); // Get the chain. 60247748Salc SDValue Ptr = N->getOperand(1); // Get the pointer. 60313675Sdyson MVT VT = N->getValueType(0); 60476760Salfred DebugLoc dl = N->getDebugLoc(); 60547748Salc 60676760Salfred MVT RegVT = TLI.getRegisterType(VT); 60747748Salc unsigned NumRegs = TLI.getNumRegisters(VT); 60891362Salfred // The argument is passed as NumRegs registers of type RegVT. 60991362Salfred 61077140Salfred SmallVector<SDValue, 8> Parts(NumRegs); 61147748Salc for (unsigned i = 0; i < NumRegs; ++i) { 61213675Sdyson Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2)); 61347748Salc Chain = Parts[i].getValue(1); 61447748Salc } 61513675Sdyson 61613675Sdyson // Handle endianness of the load. 617101768Srwatson if (TLI.isBigEndian()) 618101768Srwatson std::reverse(Parts.begin(), Parts.end()); 619101768Srwatson 62047748Salc // Assemble the parts in the promoted type. 62113675Sdyson MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 62291362Salfred SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]); 62324101Sbde for (unsigned i = 1; i < NumRegs; ++i) { 62455112Sbde SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]); 62547748Salc // Shift it to the right position and "or" it in. 62647748Salc Part = DAG.getNode(ISD::SHL, dl, NVT, Part, 62713913Sdyson DAG.getConstant(i * RegVT.getSizeInBits(), 62847748Salc TLI.getPointerTy())); 62947748Salc Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part); 63047748Salc } 63113675Sdyson 63213675Sdyson // Modified the chain result - switch anything that used the old chain to 63313675Sdyson // use the new one. 63413675Sdyson ReplaceValueWith(SDValue(N, 1), Chain); 63513675Sdyson 63647748Salc return Res; 63713675Sdyson} 63813675Sdyson 63913675SdysonSDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) { 64013675Sdyson assert(ResNo == 1 && "Only boolean result promotion currently supported!"); 64113675Sdyson return PromoteIntRes_Overflow(N); 64213675Sdyson} 64314037Sdyson 64414802Sdyson//===----------------------------------------------------------------------===// 64514037Sdyson// Integer Operand Promotion 64614037Sdyson//===----------------------------------------------------------------------===// 64791362Salfred 64876760Salfred/// PromoteIntegerOperand - This method is called when the specified operand of 64913675Sdyson/// the specified node is found to need promotion. At this point, all of the 65013675Sdyson/// result types of the node are known to be legal, but other operands of the 65114037Sdyson/// node may need promotion or expansion as well as the specified one. 65213907Sdysonbool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { 65313907Sdyson DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n"); 65413907Sdyson SDValue Res = SDValue(); 65513907Sdyson 65613675Sdyson if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 65713907Sdyson return false; 65813907Sdyson 65913675Sdyson switch (N->getOpcode()) { 66013675Sdyson default: 66118863Sdyson #ifndef NDEBUG 66294566Stmm cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; 663112569Sjake N->dump(&DAG); cerr << "\n"; 664112569Sjake #endif 66513907Sdyson assert(0 && "Do not know how to promote this operator's operand!"); 66679224Sdillon abort(); 66791412Salfred 66879224Sdillon case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; 66918863Sdyson case ISD::BIT_CONVERT: Res = PromoteIntOp_BIT_CONVERT(N); break; 67013907Sdyson case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; 67113907Sdyson case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; 67213907Sdyson case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; 67340286Sdg case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; 67476760Salfred case ISD::CONVERT_RNDSAT: 67576760Salfred Res = PromoteIntOp_CONVERT_RNDSAT(N); break; 67694566Stmm case ISD::INSERT_VECTOR_ELT: 67794566Stmm Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break; 67899899Salc case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; 67999899Salc case ISD::SCALAR_TO_VECTOR: 68099899Salc Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break; 68199899Salc case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; 68299899Salc case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; 68351474Sdillon case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; 68494608Stmm case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; 68594608Stmm case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; 68613907Sdyson case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N), 68776760Salfred OpNo); break; 68899899Salc case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; 689117325Ssilby case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; 690118757Salc case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; 691117325Ssilby 69299899Salc case ISD::SHL: 69376760Salfred case ISD::SRA: 69413907Sdyson case ISD::SRL: 69513907Sdyson case ISD::ROTL: 69694566Stmm case ISD::ROTR: Res = PromoteIntOp_Shift(N); break; 69799899Salc } 698118757Salc 69999899Salc // If the result is null, the sub-method took care of registering results etc. 70013907Sdyson if (!Res.getNode()) return false; 70113907Sdyson 70213907Sdyson // If the result is N, the sub-method updated N in place. Tell the legalizer 70313907Sdyson // core about this. 70413907Sdyson if (Res.getNode() == N) 70513907Sdyson return true; 70613907Sdyson 70776760Salfred assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 70876760Salfred "Invalid operand expansion"); 70913907Sdyson 71013907Sdyson ReplaceValueWith(SDValue(N, 0), Res); 71113907Sdyson return false; 71213907Sdyson} 71313907Sdyson 71413907Sdyson/// PromoteSetCCOperands - Promote the operands of a comparison. This code is 71513912Sdyson/// shared among BR_CC, SELECT_CC, and SETCC handlers. 71613912Sdysonvoid DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, 71713912Sdyson ISD::CondCode CCCode) { 71813912Sdyson // We have to insert explicit sign or zero extends. Note that we could 719118220Salc // insert sign extends for ALL conditions, but zero extend is cheaper on 72013912Sdyson // many machines (an AND instead of two shifts), so prefer it. 721118764Ssilby switch (CCCode) { 722110816Salc default: assert(0 && "Unknown integer comparison!"); 72313907Sdyson case ISD::SETEQ: 72413907Sdyson case ISD::SETNE: 72513907Sdyson case ISD::SETUGE: 72613907Sdyson case ISD::SETUGT: 72713907Sdyson case ISD::SETULE: 72813907Sdyson case ISD::SETULT: 72913907Sdyson // ALL of these operations will work if we either sign or zero extend 73013907Sdyson // the operands (including the unsigned comparisons!). Zero extend is 73113907Sdyson // usually a simpler/cheaper operation, so prefer it. 732104908Smike NewLHS = ZExtPromotedInteger(NewLHS); 73313907Sdyson NewRHS = ZExtPromotedInteger(NewRHS); 73413907Sdyson break; 73513907Sdyson case ISD::SETGE: 73613907Sdyson case ISD::SETGT: 73776760Salfred case ISD::SETLT: 73813907Sdyson case ISD::SETLE: 73913907Sdyson NewLHS = SExtPromotedInteger(NewLHS); 74013907Sdyson NewRHS = SExtPromotedInteger(NewRHS); 74113907Sdyson break; 74213907Sdyson } 74313907Sdyson} 74413907Sdyson 74576760SalfredSDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { 74613907Sdyson SDValue Op = GetPromotedInteger(N->getOperand(0)); 74713907Sdyson return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); 74876364Salfred} 74979224Sdillon 75091412SalfredSDValue DAGTypeLegalizer::PromoteIntOp_BIT_CONVERT(SDNode *N) { 75179224Sdillon // This should only occur in unusual situations like bitcasting to an 75217163Sdyson // x86_fp80, so just turn it into a store+load 75317163Sdyson return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); 75413907Sdyson} 755118764Ssilby 756118764SsilbySDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { 75713907Sdyson assert(OpNo == 2 && "Don't know how to promote this operand!"); 75813907Sdyson 75913907Sdyson SDValue LHS = N->getOperand(2); 76013912Sdyson SDValue RHS = N->getOperand(3); 761118764Ssilby PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get()); 762110816Salc 76313907Sdyson // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always 76413907Sdyson // legal types. 76599899Salc return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 766117325Ssilby N->getOperand(1), LHS, RHS, N->getOperand(4)); 767118757Salc} 768117325Ssilby 76999899SalcSDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) { 77091653Stanimura assert(OpNo == 1 && "only know how to promote condition"); 77113907Sdyson 77213907Sdyson // Promote all the way up to the canonical SetCC type. 77313907Sdyson MVT SVT = TLI.getSetCCResultType(MVT::Other); 77413907Sdyson SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT); 77513907Sdyson 77613907Sdyson // The chain (Op#0) and basic block destination (Op#2) are always legal types. 77713907Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond, 77813907Sdyson N->getOperand(2)); 77913907Sdyson} 78076364Salfred 78113907SdysonSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) { 78213907Sdyson // Since the result type is legal, the operands must promote to it. 78313907Sdyson MVT OVT = N->getOperand(0).getValueType(); 78413907Sdyson SDValue Lo = ZExtPromotedInteger(N->getOperand(0)); 78591362Salfred SDValue Hi = GetPromotedInteger(N->getOperand(1)); 78613907Sdyson assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?"); 78713907Sdyson DebugLoc dl = N->getDebugLoc(); 78813907Sdyson 78913907Sdyson Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi, 79013907Sdyson DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy())); 79113907Sdyson return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi); 79213907Sdyson} 79313907Sdyson 79491412SalfredSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { 79592959Salfred // The vector type is legal but the element type is not. This implies 796100527Salfred // that the vector is a power-of-two in length and that the element 79713907Sdyson // type does not have a strange size (eg: it is not i1). 79891412Salfred MVT VecVT = N->getValueType(0); 79913907Sdyson unsigned NumElts = VecVT.getVectorNumElements(); 80013907Sdyson assert(!(NumElts & 1) && "Legal vector of one illegal element?"); 80113907Sdyson 80213907Sdyson // Promote the inserted value. The type does not need to match the 80313907Sdyson // vector element type. Check that any extra bits introduced will be 80413907Sdyson // truncated away. 80513907Sdyson assert(N->getOperand(0).getValueType().getSizeInBits() >= 80613907Sdyson N->getValueType(0).getVectorElementType().getSizeInBits() && 80713907Sdyson "Type of inserted value narrower than vector element type!"); 80813907Sdyson 80913907Sdyson SmallVector<SDValue, 16> NewOps; 81013907Sdyson for (unsigned i = 0; i < NumElts; ++i) 81113907Sdyson NewOps.push_back(GetPromotedInteger(N->getOperand(i))); 81213907Sdyson 81313907Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), &NewOps[0], NumElts); 81476364Salfred} 81513951Sdyson 81691362SalfredSDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) { 81713907Sdyson ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 81876760Salfred assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU || 81913951Sdyson CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU || 82013951Sdyson CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) && 82113951Sdyson "can only promote integer arguments"); 82213992Sdyson SDValue InOp = GetPromotedInteger(N->getOperand(0)); 82391362Salfred return DAG.getConvertRndSat(N->getValueType(0), N->getDebugLoc(), InOp, 82491362Salfred N->getOperand(1), N->getOperand(2), 82514802Sdyson N->getOperand(3), N->getOperand(4), CvtCode); 82613907Sdyson} 82714802Sdyson 82814802SdysonSDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, 82914802Sdyson unsigned OpNo) { 83014802Sdyson if (OpNo == 1) { 83113907Sdyson // Promote the inserted value. This is valid because the type does not 83213907Sdyson // have to match the vector element type. 83313951Sdyson 83476760Salfred // Check that any extra bits introduced will be truncated away. 83513951Sdyson assert(N->getOperand(1).getValueType().getSizeInBits() >= 83613951Sdyson N->getValueType(0).getVectorElementType().getSizeInBits() && 83713951Sdyson "Type of inserted value narrower than vector element type!"); 83813951Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 83913992Sdyson GetPromotedInteger(N->getOperand(1)), 84091362Salfred N->getOperand(2)); 84191362Salfred } 84214802Sdyson 84313907Sdyson assert(OpNo == 2 && "Different operand and result vector types?"); 84414802Sdyson 84514802Sdyson // Promote the index. 84614802Sdyson SDValue Idx = ZExtPromotedInteger(N->getOperand(2)); 84713907Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 84813951Sdyson N->getOperand(1), Idx); 84913907Sdyson} 85013907Sdyson 85113951SdysonSDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) { 85213951Sdyson SDValue NewOps[6]; 85392305Salfred DebugLoc dl = N->getDebugLoc(); 85491362Salfred NewOps[0] = N->getOperand(0); 85513907Sdyson for (unsigned i = 1; i < array_lengthof(NewOps); ++i) { 85691362Salfred SDValue Flag = GetPromotedInteger(N->getOperand(i)); 85792305Salfred NewOps[i] = DAG.getZeroExtendInReg(Flag, dl, MVT::i1); 85813907Sdyson } 85913907Sdyson return DAG.UpdateNodeOperands(SDValue (N, 0), NewOps, 86013907Sdyson array_lengthof(NewOps)); 86113907Sdyson} 86213907Sdyson 86313907SdysonSDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) { 86413907Sdyson // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote 86513907Sdyson // the operand in place. 86613907Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), 86791362Salfred GetPromotedInteger(N->getOperand(0))); 86813907Sdyson} 86991362Salfred 870112981ShsuSDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { 87113907Sdyson assert(OpNo == 0 && "Only know how to promote condition"); 87214802Sdyson 87314802Sdyson // Promote all the way up to the canonical SetCC type. 87413907Sdyson MVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType()); 87513992Sdyson SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT); 87613992Sdyson 87713992Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), Cond, 87813992Sdyson N->getOperand(1), N->getOperand(2)); 87914037Sdyson} 88091362Salfred 88191362SalfredSDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { 88213907Sdyson assert(OpNo == 0 && "Don't know how to promote this operand!"); 88313907Sdyson 88413907Sdyson SDValue LHS = N->getOperand(0); 88513907Sdyson SDValue RHS = N->getOperand(1); 88613907Sdyson PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get()); 88713907Sdyson 88813907Sdyson // The CC (#4) and the possible return values (#2 and #3) have legal types. 88913907Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2), 89013907Sdyson N->getOperand(3), N->getOperand(4)); 89113907Sdyson} 89291412Salfred 89313907SdysonSDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) { 89491412Salfred assert(OpNo == 0 && "Don't know how to promote this operand!"); 89513907Sdyson 89613907Sdyson SDValue LHS = N->getOperand(0); 89776760Salfred SDValue RHS = N->getOperand(1); 89813907Sdyson PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get()); 89913907Sdyson 90013907Sdyson // The CC (#2) is always legal. 90176760Salfred return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2)); 90213907Sdyson} 90314037Sdyson 90413907SdysonSDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) { 90516960Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 906101941Srwatson ZExtPromotedInteger(N->getOperand(1))); 90716960Sdyson} 90813907Sdyson 909101941SrwatsonSDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) { 91083366Sjulian SDValue Op = GetPromotedInteger(N->getOperand(0)); 91145311Sdt DebugLoc dl = N->getDebugLoc(); 91213907Sdyson Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op); 91313675Sdyson return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(), 91413913Sdyson Op, DAG.getValueType(N->getOperand(0).getValueType())); 91516960Sdyson} 91616960Sdyson 917109153SdillonSDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) { 91816960Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), 91916960Sdyson SExtPromotedInteger(N->getOperand(0))); 92091395Salfred} 92113675Sdyson 92213675SdysonSDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ 92313675Sdyson assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 92416960Sdyson SDValue Ch = N->getChain(), Ptr = N->getBasePtr(); 92591395Salfred int SVOffset = N->getSrcValueOffset(); 92676760Salfred unsigned Alignment = N->getAlignment(); 92713675Sdyson bool isVolatile = N->isVolatile(); 928101768Srwatson DebugLoc dl = N->getDebugLoc(); 929102115Srwatson 930101768Srwatson SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value. 931101768Srwatson 932101768Srwatson // Truncate the value and store the result. 933101768Srwatson return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(), 934101768Srwatson SVOffset, N->getMemoryVT(), 93577676Sdillon isVolatile, Alignment); 93613675Sdyson} 93717163Sdyson 93817163SdysonSDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) { 93917163Sdyson SDValue Op = GetPromotedInteger(N->getOperand(0)); 94017163Sdyson return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op); 94117163Sdyson} 942118764Ssilby 94317163SdysonSDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) { 94417163Sdyson return DAG.UpdateNodeOperands(SDValue(N, 0), 94517163Sdyson ZExtPromotedInteger(N->getOperand(0))); 94617163Sdyson} 94717163Sdyson 948105009SalfredSDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) { 94992305Salfred DebugLoc dl = N->getDebugLoc(); 95076364Salfred SDValue Op = GetPromotedInteger(N->getOperand(0)); 951117364Ssilby Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op); 95292305Salfred return DAG.getZeroExtendInReg(Op, dl, N->getOperand(0).getValueType()); 95313907Sdyson} 95413907Sdyson 95513907Sdyson 95677676Sdillon//===----------------------------------------------------------------------===// 95777676Sdillon// Integer Result Expansion 95877676Sdillon//===----------------------------------------------------------------------===// 95977676Sdillon 96077676Sdillon/// ExpandIntegerResult - This method is called when the specified result of the 96177676Sdillon/// specified node is found to need expansion. At this point, the node may also 96277676Sdillon/// have invalid operands or may have other results that need promotion, we just 96377676Sdillon/// know that (at least) one result needs expansion. 96477676Sdillonvoid DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { 96577676Sdillon DEBUG(cerr << "Expand integer result: "; N->dump(&DAG); cerr << "\n"); 96677676Sdillon SDValue Lo, Hi; 96777676Sdillon Lo = Hi = SDValue(); 96891395Salfred 96977676Sdillon // See if the target wants to custom expand this node. 97077676Sdillon if (CustomLowerNode(N, N->getValueType(ResNo), true)) 97176364Salfred return; 97213913Sdyson 97377676Sdillon switch (N->getOpcode()) { 97413675Sdyson default: 97513907Sdyson#ifndef NDEBUG 97676760Salfred cerr << "ExpandIntegerResult #" << ResNo << ": "; 97714037Sdyson N->dump(&DAG); cerr << "\n"; 97813907Sdyson#endif 97913907Sdyson assert(0 && "Do not know how to expand the result of this operator!"); 98013907Sdyson abort(); 98116416Sdyson 98216416Sdyson case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 98358505Sdillon case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 98458505Sdillon case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 98558505Sdillon case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 98613907Sdyson 98717163Sdyson case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 98817163Sdyson case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 989118764Ssilby case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 990105009Salfred case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 99176760Salfred case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 99213907Sdyson 99313907Sdyson case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break; 99491362Salfred case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break; 99514037Sdyson case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break; 99613907Sdyson case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break; 99713907Sdyson case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break; 99813907Sdyson case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break; 99913907Sdyson case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break; 100013907Sdyson case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break; 100158505Sdillon case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break; 100258505Sdillon case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break; 100313907Sdyson case ISD::LOAD: ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break; 100413907Sdyson case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break; 100513907Sdyson case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break; 100613992Sdyson case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break; 100713992Sdyson case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break; 100813992Sdyson case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break; 100913992Sdyson case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break; 101091395Salfred case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break; 101191362Salfred case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break; 101258505Sdillon case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break; 101358505Sdillon 101413907Sdyson case ISD::AND: 101513907Sdyson case ISD::OR: 101613907Sdyson case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break; 101758505Sdillon 101858505Sdillon case ISD::ADD: 101958505Sdillon case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break; 102058505Sdillon 102113907Sdyson case ISD::ADDC: 102213907Sdyson case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break; 102314644Sdyson 102414644Sdyson case ISD::ADDE: 102513913Sdyson case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break; 102613913Sdyson 102713907Sdyson case ISD::SHL: 1028118230Spb case ISD::SRA: 102913907Sdyson case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break; 103054534Stegge } 103154534Stegge 103276760Salfred // If Lo/Hi is null, the sub-method took care of registering results etc. 103313907Sdyson if (Lo.getNode()) 103413907Sdyson SetExpandedInteger(SDValue(N, ResNo), Lo, Hi); 103513907Sdyson} 103613907Sdyson 103713907Sdyson/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, 103813907Sdyson/// and the shift amount is a constant 'Amt'. Expand the operation. 103913907Sdysonvoid DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, 104013907Sdyson SDValue &Lo, SDValue &Hi) { 104154534Stegge DebugLoc dl = N->getDebugLoc(); 104254534Stegge // Expand the incoming operand to be shifted, so that we have its parts 104354534Stegge SDValue InL, InH; 104458505Sdillon GetExpandedInteger(N->getOperand(0), InL, InH); 104558505Sdillon 104658505Sdillon MVT NVT = InL.getValueType(); 104754534Stegge unsigned VTBits = N->getValueType(0).getSizeInBits(); 104854534Stegge unsigned NVTBits = NVT.getSizeInBits(); 104954534Stegge MVT ShTy = N->getOperand(1).getValueType(); 105054534Stegge 105154534Stegge if (N->getOpcode() == ISD::SHL) { 105254534Stegge if (Amt > VTBits) { 105354534Stegge Lo = Hi = DAG.getConstant(0, NVT); 105454534Stegge } else if (Amt > NVTBits) { 105554534Stegge Lo = DAG.getConstant(0, NVT); 105654534Stegge Hi = DAG.getNode(ISD::SHL, dl, 105754534Stegge NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); 105854534Stegge } else if (Amt == NVTBits) { 105954534Stegge Lo = DAG.getConstant(0, NVT); 106054534Stegge Hi = InL; 106154534Stegge } else if (Amt == 1 && 106254534Stegge TLI.isOperationLegalOrCustom(ISD::ADDC, 106354534Stegge TLI.getTypeToExpandTo(NVT))) { 106454534Stegge // Emit this X << 1 as X+X. 106554534Stegge SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); 106654534Stegge SDValue LoOps[2] = { InL, InL }; 106754534Stegge Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); 106854534Stegge SDValue HiOps[3] = { InH, InH, Lo.getValue(1) }; 106954534Stegge Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); 107054534Stegge } else { 107154534Stegge Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt, ShTy)); 107254534Stegge Hi = DAG.getNode(ISD::OR, dl, NVT, 107354534Stegge DAG.getNode(ISD::SHL, dl, NVT, InH, 107454534Stegge DAG.getConstant(Amt, ShTy)), 107554534Stegge DAG.getNode(ISD::SRL, dl, NVT, InL, 107691395Salfred DAG.getConstant(NVTBits-Amt, ShTy))); 107754534Stegge } 107854534Stegge return; 107991395Salfred } 108054534Stegge 108154534Stegge if (N->getOpcode() == ISD::SRL) { 108254534Stegge if (Amt > VTBits) { 108354534Stegge Lo = DAG.getConstant(0, NVT); 108454534Stegge Hi = DAG.getConstant(0, NVT); 108554534Stegge } else if (Amt > NVTBits) { 108654534Stegge Lo = DAG.getNode(ISD::SRL, dl, 108754534Stegge NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); 108854534Stegge Hi = DAG.getConstant(0, NVT); 1089116127Smux } else if (Amt == NVTBits) { 1090116127Smux Lo = InH; 109154534Stegge Hi = DAG.getConstant(0, NVT); 109291395Salfred } else { 1093116127Smux Lo = DAG.getNode(ISD::OR, dl, NVT, 1094116127Smux DAG.getNode(ISD::SRL, dl, NVT, InL, 1095116127Smux DAG.getConstant(Amt, ShTy)), 109691395Salfred DAG.getNode(ISD::SHL, dl, NVT, InH, 109754534Stegge DAG.getConstant(NVTBits-Amt, ShTy))); 109854534Stegge Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Amt, ShTy)); 109954534Stegge } 110054534Stegge return; 110154534Stegge } 1102116127Smux 1103116127Smux assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 1104116127Smux if (Amt > VTBits) { 1105116127Smux Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, 1106116127Smux DAG.getConstant(NVTBits-1, ShTy)); 1107116127Smux } else if (Amt > NVTBits) { 1108116127Smux Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, 110954534Stegge DAG.getConstant(Amt-NVTBits, ShTy)); 111054534Stegge Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, 111154534Stegge DAG.getConstant(NVTBits-1, ShTy)); 1112116127Smux } else if (Amt == NVTBits) { 1113116127Smux Lo = InH; 111454534Stegge Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, 111554534Stegge DAG.getConstant(NVTBits-1, ShTy)); 111654534Stegge } else { 111713675Sdyson Lo = DAG.getNode(ISD::OR, dl, NVT, 111813675Sdyson DAG.getNode(ISD::SRL, dl, NVT, InL, 111913675Sdyson DAG.getConstant(Amt, ShTy)), 112013675Sdyson DAG.getNode(ISD::SHL, dl, NVT, InH, 112113675Sdyson DAG.getConstant(NVTBits-Amt, ShTy))); 112213675Sdyson Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Amt, ShTy)); 112313675Sdyson } 112413675Sdyson} 112513675Sdyson 112613675Sdyson/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify 112713675Sdyson/// this shift based on knowledge of the high bit of the shift amount. If we 112813675Sdyson/// can tell this, we know that it is >= 32 or < 32, without knowing the actual 112913675Sdyson/// shift amount. 113014037Sdysonbool DAGTypeLegalizer:: 113113675SdysonExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { 113213675Sdyson SDValue Amt = N->getOperand(1); 113313675Sdyson MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 113416960Sdyson MVT ShTy = Amt.getValueType(); 113513907Sdyson unsigned ShBits = ShTy.getSizeInBits(); 113613675Sdyson unsigned NVTBits = NVT.getSizeInBits(); 113713675Sdyson assert(isPowerOf2_32(NVTBits) && 113813907Sdyson "Expanded integer type size not a power of two!"); 113914037Sdyson DebugLoc dl = N->getDebugLoc(); 114014037Sdyson 114129356Speter APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits)); 114214037Sdyson APInt KnownZero, KnownOne; 114314037Sdyson DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); 114414037Sdyson 114513675Sdyson // If we don't know anything about the high bits, exit. 114691395Salfred if (((KnownZero|KnownOne) & HighBitMask) == 0) 114791362Salfred return false; 114876760Salfred 114913675Sdyson // Get the incoming operand to be shifted. 115013675Sdyson SDValue InL, InH; 115113675Sdyson GetExpandedInteger(N->getOperand(0), InL, InH); 115213675Sdyson 115313675Sdyson // If we know that any of the high bits of the shift amount are one, then we 115413675Sdyson // can do this as a couple of simple shifts. 115513774Sdyson if (KnownOne.intersects(HighBitMask)) { 115613907Sdyson // Mask out the high bit, which we know is set. 115713675Sdyson Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt, 115813675Sdyson DAG.getConstant(~HighBitMask, ShTy)); 115913675Sdyson 116013675Sdyson switch (N->getOpcode()) { 116114644Sdyson default: assert(0 && "Unknown shift"); 116277676Sdillon case ISD::SHL: 116376760Salfred Lo = DAG.getConstant(0, NVT); // Low part is zero. 116476760Salfred Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part. 116513675Sdyson return true; 116613675Sdyson case ISD::SRL: 116713675Sdyson Hi = DAG.getConstant(0, NVT); // Hi part is zero. 116813675Sdyson Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part. 116913675Sdyson return true; 117013675Sdyson case ISD::SRA: 117113675Sdyson Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part. 117213675Sdyson DAG.getConstant(NVTBits-1, ShTy)); 117313675Sdyson Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part. 117413675Sdyson return true; 117513675Sdyson } 117613909Sdyson } 117713909Sdyson 117813909Sdyson#if 0 117913909Sdyson // FIXME: This code is broken for shifts with a zero amount! 118013907Sdyson // If we know that all of the high bits of the shift amount are zero, then we 118177676Sdillon // can do this as a couple of simple shifts. 118277676Sdillon if ((KnownZero & HighBitMask) == HighBitMask) { 118313907Sdyson // Compute 32-amt. 118477676Sdillon SDValue Amt2 = DAG.getNode(ISD::SUB, ShTy, 118513913Sdyson DAG.getConstant(NVTBits, ShTy), 118624101Sbde Amt); 118755112Sbde unsigned Op1, Op2; 118824101Sbde switch (N->getOpcode()) { 118914037Sdyson default: assert(0 && "Unknown shift"); 119014037Sdyson case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break; 119129356Speter case ISD::SRL: 119214037Sdyson case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break; 119314177Sdyson } 119414037Sdyson 119513907Sdyson Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt); 119691395Salfred Hi = DAG.getNode(ISD::OR, NVT, 119776760Salfred DAG.getNode(Op1, NVT, InH, Amt), 119813675Sdyson DAG.getNode(Op2, NVT, InL, Amt2)); 119913675Sdyson return true; 120013675Sdyson } 120113675Sdyson#endif 120213675Sdyson 1203104094Sphk return false; 1204102003Srwatson} 120513675Sdyson 120636735Sdfr/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift 120799009Salfred/// of any size. 1208102003Srwatsonbool DAGTypeLegalizer:: 120983366SjulianExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { 121013675Sdyson SDValue Amt = N->getOperand(1); 1211109153Sdillon MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 1212101768Srwatson MVT ShTy = Amt.getValueType(); 1213101768Srwatson unsigned NVTBits = NVT.getSizeInBits(); 1214104269Srwatson assert(isPowerOf2_32(NVTBits) && 121513675Sdyson "Expanded integer type size not a power of two!"); 1216104269Srwatson DebugLoc dl = N->getDebugLoc(); 1217104269Srwatson 1218104269Srwatson // Get the incoming operand to be shifted. 1219102003Srwatson SDValue InL, InH; 1220101768Srwatson GetExpandedInteger(N->getOperand(0), InL, InH); 1221101768Srwatson 1222101768Srwatson SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy); 1223101768Srwatson SDValue Amt2 = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt); 122413675Sdyson SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy), 122513675Sdyson Amt, NVBitsNode, ISD::SETULT); 122613675Sdyson 1227104269Srwatson SDValue Lo1, Hi1, Lo2, Hi2; 122813675Sdyson switch (N->getOpcode()) { 122913675Sdyson default: assert(0 && "Unknown shift"); 123013675Sdyson case ISD::SHL: 123113675Sdyson // ShAmt < NVTBits 123213675Sdyson Lo1 = DAG.getConstant(0, NVT); // Low part is zero. 123313675Sdyson Hi1 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part. 123413675Sdyson 123513675Sdyson // ShAmt >= NVTBits 123691362Salfred Lo2 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); 123713675Sdyson Hi2 = DAG.getNode(ISD::OR, dl, NVT, 123813675Sdyson DAG.getNode(ISD::SHL, dl, NVT, InH, Amt), 123913675Sdyson DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2)); 124014037Sdyson 124114037Sdyson Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2); 124214037Sdyson Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2); 124314037Sdyson return true; 124491362Salfred case ISD::SRL: 124513675Sdyson // ShAmt < NVTBits 124613675Sdyson Hi1 = DAG.getConstant(0, NVT); // Hi part is zero. 124741086Struckman Lo1 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part. 1248104269Srwatson 124941086Struckman // ShAmt >= NVTBits 125041086Struckman Hi2 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); 125141086Struckman Lo2 = DAG.getNode(ISD::OR, dl, NVT, 1252104269Srwatson DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), 1253104393Struckman DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2)); 125413675Sdyson 125513675Sdyson Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2); 125641086Struckman Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2); 125741086Struckman return true; 1258104269Srwatson case ISD::SRA: 125941086Struckman // ShAmt < NVTBits 126041086Struckman Hi1 = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part. 126141086Struckman DAG.getConstant(NVTBits-1, ShTy)); 126218863Sdyson Lo1 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part. 1263104269Srwatson 1264104393Struckman // ShAmt >= NVTBits 126513675Sdyson Hi2 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); 126613675Sdyson Lo2 = DAG.getNode(ISD::OR, dl, NVT, 126713675Sdyson DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), 1268104269Srwatson DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2)); 126917124Sbde 127013675Sdyson Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2); 127113675Sdyson Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2); 1272104094Sphk return true; 1273101983Srwatson } 127413675Sdyson 127529356Speter return false; 1276101983Srwatson} 127783366Sjulian 127813675Sdysonvoid DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, 1279109153Sdillon SDValue &Lo, SDValue &Hi) { 128013675Sdyson DebugLoc dl = N->getDebugLoc(); 128129356Speter // Expand the subcomponents. 1282101768Srwatson SDValue LHSL, LHSH, RHSL, RHSH; 1283101768Srwatson GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1284101768Srwatson GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 128513675Sdyson 128613675Sdyson MVT NVT = LHSL.getValueType(); 128791362Salfred SDValue LoOps[2] = { LHSL, RHSL }; 1288101768Srwatson SDValue HiOps[3] = { LHSH, RHSH }; 1289102115Srwatson 1290101768Srwatson // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support 1291101768Srwatson // them. TODO: Teach operation legalization how to expand unsupported 1292101768Srwatson // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate 129329356Speter // a carry of type MVT::Flag, but there doesn't seem to be any way to 129429356Speter // generate a value of this type in the expanded code sequence. 129529356Speter bool hasCarry = 129629356Speter TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ? 129729356Speter ISD::ADDC : ISD::SUBC, 129813675Sdyson TLI.getTypeToExpandTo(NVT)); 129929356Speter 130029356Speter if (hasCarry) { 130143311Sdillon SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); 130243311Sdillon if (N->getOpcode() == ISD::ADD) { 130329356Speter Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); 130413675Sdyson HiOps[2] = Lo.getValue(1); 130529356Speter Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); 130629356Speter } else { 130729356Speter Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); 130829356Speter HiOps[2] = Lo.getValue(1); 130929356Speter Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); 131029356Speter } 131129356Speter } else { 131283805Sjhb if (N->getOpcode() == ISD::ADD) { 131329356Speter Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2); 131413675Sdyson Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2); 131513675Sdyson SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0], 131629356Speter ISD::SETULT); 131783805Sjhb SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1, 131830164Speter DAG.getConstant(1, NVT), 131913907Sdyson DAG.getConstant(0, NVT)); 132013675Sdyson SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1], 1321101768Srwatson ISD::SETULT); 1322101768Srwatson SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2, 1323101768Srwatson DAG.getConstant(1, NVT), Carry1); 132491362Salfred Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2); 132529356Speter } else { 132629356Speter Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2); 132713675Sdyson Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2); 132813675Sdyson SDValue Cmp = 132998989Salfred DAG.getSetCC(dl, TLI.getSetCCResultType(LoOps[0].getValueType()), 133098989Salfred LoOps[0], LoOps[1], ISD::SETULT); 133198989Salfred SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, 133298989Salfred DAG.getConstant(1, NVT), 133352983Speter DAG.getConstant(0, NVT)); 1334101983Srwatson Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow); 133552983Speter } 133652983Speter } 1337101983Srwatson} 133883366Sjulian 133913675Sdysonvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, 1340109153Sdillon SDValue &Lo, SDValue &Hi) { 1341101768Srwatson // Expand the subcomponents. 1342101768Srwatson SDValue LHSL, LHSH, RHSL, RHSH; 134352983Speter DebugLoc dl = N->getDebugLoc(); 1344104269Srwatson GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1345102115Srwatson GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 1346104269Srwatson SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); 1347101768Srwatson SDValue LoOps[2] = { LHSL, RHSL }; 1348101768Srwatson SDValue HiOps[3] = { LHSH, RHSH }; 1349101768Srwatson 1350100527Salfred if (N->getOpcode() == ISD::ADDC) { 135117124Sbde Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); 135213907Sdyson HiOps[2] = Lo.getValue(1); 135313675Sdyson Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); 135413675Sdyson } else { 135534901Sphk Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); 135634901Sphk HiOps[2] = Lo.getValue(1); 135734901Sphk Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); 135860404Schris } 135960404Schris 136017124Sbde // Legalized the flag result - switch anything that used the old flag to 136160404Schris // use the new one. 136217124Sbde ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); 136317124Sbde} 136476760Salfred 136513675Sdysonvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, 136613675Sdyson SDValue &Lo, SDValue &Hi) { 136713675Sdyson // Expand the subcomponents. 136813675Sdyson SDValue LHSL, LHSH, RHSL, RHSH; 136983366Sjulian DebugLoc dl = N->getDebugLoc(); 137013675Sdyson GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 137183366Sjulian GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 137213675Sdyson SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); 1373109153Sdillon SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; 137416322Sgpalmer SDValue HiOps[3] = { LHSH, RHSH }; 137549413Sgreen 1376109153Sdillon Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3); 137796122Salfred HiOps[2] = Lo.getValue(1); 137813675Sdyson Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3); 137976760Salfred 138013675Sdyson // Legalized the flag result - switch anything that used the old flag to 138113675Sdyson // use the new one. 138276364Salfred ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); 138376364Salfred} 138476364Salfred 138576364Salfredvoid DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, 138691412Salfred SDValue &Lo, SDValue &Hi) { 138791412Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 138891412Salfred DebugLoc dl = N->getDebugLoc(); 138976364Salfred SDValue Op = N->getOperand(0); 139076364Salfred if (Op.getValueType().bitsLE(NVT)) { 139176364Salfred // The low part is any extension of the input (which degenerates to a copy). 1392117364Ssilby Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op); 1393110816Salc Hi = DAG.getUNDEF(NVT); // The high part is undefined. 1394117325Ssilby } else { 1395118764Ssilby // For example, extension of an i48 to an i64. The operand type necessarily 1396118764Ssilby // promotes to the result type, so will end up being expanded too. 1397118764Ssilby assert(getTypeAction(Op.getValueType()) == PromoteInteger && 139876364Salfred "Only know how to promote this result!"); 139976364Salfred SDValue Res = GetPromotedInteger(Op); 140076364Salfred assert(Res.getValueType() == N->getValueType(0) && 1401102241Sarchie "Operand over promoted?"); 1402118764Ssilby // Split the promoted operand. This will simplify when it is expanded. 1403110816Salc SplitInteger(Res, Lo, Hi); 140476364Salfred } 140576364Salfred} 140676364Salfred 140776364Salfredvoid DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, 140876364Salfred SDValue &Lo, SDValue &Hi) { 140976364Salfred DebugLoc dl = N->getDebugLoc(); 141076364Salfred GetExpandedInteger(N->getOperand(0), Lo, Hi); 141176364Salfred MVT NVT = Lo.getValueType(); 141276364Salfred MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 141376364Salfred unsigned NVTBits = NVT.getSizeInBits(); 141476364Salfred unsigned EVTBits = EVT.getSizeInBits(); 141513675Sdyson 141613675Sdyson if (NVTBits < EVTBits) { 141713675Sdyson Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi, 141813675Sdyson DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits))); 141913675Sdyson } else { 142013675Sdyson Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT)); 142113675Sdyson // The high part replicates the sign bit of Lo, make it explicit. 142213907Sdyson Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 142391968Salfred DAG.getConstant(NVTBits-1, TLI.getPointerTy())); 142476364Salfred } 142591968Salfred} 142691968Salfred 142791968Salfredvoid DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, 142891968Salfred SDValue &Lo, SDValue &Hi) { 142991968Salfred DebugLoc dl = N->getDebugLoc(); 143091968Salfred GetExpandedInteger(N->getOperand(0), Lo, Hi); 143191968Salfred MVT NVT = Lo.getValueType(); 143291362Salfred MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 143313907Sdyson unsigned NVTBits = NVT.getSizeInBits(); 143491968Salfred unsigned EVTBits = EVT.getSizeInBits(); 143513907Sdyson 143691968Salfred if (NVTBits < EVTBits) { 143791968Salfred Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi, 143891968Salfred DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits))); 143991968Salfred } else { 144091968Salfred Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT)); 144191968Salfred // The high part must be zero, make it explicit. 144291968Salfred Hi = DAG.getConstant(0, NVT); 144391968Salfred } 144491968Salfred} 144513675Sdyson 1446101768Srwatsonvoid DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N, 1447101768Srwatson SDValue &Lo, SDValue &Hi) { 1448101768Srwatson DebugLoc dl = N->getDebugLoc(); 1449101768Srwatson GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands. 1450101768Srwatson Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo); 145191968Salfred Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi); 145291968Salfred} 145391968Salfred 145491968Salfredvoid DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, 145591968Salfred SDValue &Lo, SDValue &Hi) { 145691968Salfred MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 145713907Sdyson unsigned NBitWidth = NVT.getSizeInBits(); 145891968Salfred const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue(); 145991968Salfred Lo = DAG.getConstant(APInt(Cst).trunc(NBitWidth), NVT); 146091968Salfred Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT); 146191968Salfred} 146291968Salfred 146391968Salfredvoid DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N, 146491968Salfred SDValue &Lo, SDValue &Hi) { 146591968Salfred DebugLoc dl = N->getDebugLoc(); 146691968Salfred // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32) 146791968Salfred GetExpandedInteger(N->getOperand(0), Lo, Hi); 146891968Salfred MVT NVT = Lo.getValueType(); 146991968Salfred 147091968Salfred SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi, 147113675Sdyson DAG.getConstant(0, NVT), ISD::SETNE); 147213675Sdyson 147391968Salfred SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo); 147492751Sjeff SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi); 147513675Sdyson 147659288Sjlemon Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ, 147772521Sjlemon DAG.getNode(ISD::ADD, dl, NVT, LoLZ, 147859288Sjlemon DAG.getConstant(NVT.getSizeInBits(), NVT))); 147972521Sjlemon Hi = DAG.getConstant(0, NVT); 148059288Sjlemon} 148189306Salfred 148259288Sjlemonvoid DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, 1483109153Sdillon SDValue &Lo, SDValue &Hi) { 148472521Sjlemon DebugLoc dl = N->getDebugLoc(); 148572521Sjlemon // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo) 148672521Sjlemon GetExpandedInteger(N->getOperand(0), Lo, Hi); 148772521Sjlemon MVT NVT = Lo.getValueType(); 148872521Sjlemon Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo), 148972521Sjlemon DAG.getNode(ISD::CTPOP, dl, NVT, Hi)); 149078292Sjlemon Hi = DAG.getConstant(0, NVT); 1491101382Sdes} 1492101382Sdes 1493101382Sdesvoid DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, 149472521Sjlemon SDValue &Lo, SDValue &Hi) { 149572521Sjlemon DebugLoc dl = N->getDebugLoc(); 149672521Sjlemon // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32) 149772521Sjlemon GetExpandedInteger(N->getOperand(0), Lo, Hi); 1498100527Salfred MVT NVT = Lo.getValueType(); 149978292Sjlemon 150091372Salfred SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, 150178292Sjlemon DAG.getConstant(0, NVT), ISD::SETNE); 150291372Salfred 150359288Sjlemon SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo); 150459288Sjlemon SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi); 150559288Sjlemon 150659288Sjlemon Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ, 150759288Sjlemon DAG.getNode(ISD::ADD, dl, NVT, HiLZ, 150859288Sjlemon DAG.getConstant(NVT.getSizeInBits(), NVT))); 150978292Sjlemon Hi = DAG.getConstant(0, NVT); 151059288Sjlemon} 151191372Salfred 151278292Sjlemonvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo, 151391372Salfred SDValue &Hi) { 151459288Sjlemon DebugLoc dl = N->getDebugLoc(); 151559288Sjlemon MVT VT = N->getValueType(0); 151659288Sjlemon SDValue Op = N->getOperand(0); 151759288Sjlemon RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT); 151859288Sjlemon assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!"); 151959288Sjlemon SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi); 1520109153Sdillon} 152159288Sjlemon 152259288Sjlemonvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo, 152391372Salfred SDValue &Hi) { 152459288Sjlemon DebugLoc dl = N->getDebugLoc(); 152559288Sjlemon MVT VT = N->getValueType(0); 152659288Sjlemon SDValue Op = N->getOperand(0); 152759288Sjlemon RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT); 152859288Sjlemon assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!"); 152959288Sjlemon SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi); 153091372Salfred} 153191372Salfred 153259288Sjlemonvoid DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, 153359288Sjlemon SDValue &Lo, SDValue &Hi) { 153491372Salfred if (ISD::isNormalLoad(N)) { 153559288Sjlemon ExpandRes_NormalLoad(N, Lo, Hi); 153659288Sjlemon return; 153759288Sjlemon } 153859288Sjlemon 153959288Sjlemon assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 154059288Sjlemon 154159288Sjlemon MVT VT = N->getValueType(0); 1542109153Sdillon MVT NVT = TLI.getTypeToTransformTo(VT); 154359288Sjlemon SDValue Ch = N->getChain(); 154459288Sjlemon SDValue Ptr = N->getBasePtr(); 154591372Salfred ISD::LoadExtType ExtType = N->getExtensionType(); 154659288Sjlemon int SVOffset = N->getSrcValueOffset(); 154759288Sjlemon unsigned Alignment = N->getAlignment(); 154859288Sjlemon bool isVolatile = N->isVolatile(); 154991372Salfred DebugLoc dl = N->getDebugLoc(); 155059288Sjlemon 155159288Sjlemon assert(NVT.isByteSized() && "Expanded type not byte sized!"); 155259288Sjlemon 155365855Sjlemon if (N->getMemoryVT().bitsLE(NVT)) { 155459288Sjlemon MVT EVT = N->getMemoryVT(); 155559288Sjlemon 155691372Salfred Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, 155759288Sjlemon EVT, isVolatile, Alignment); 155859288Sjlemon 1559 // Remember the chain. 1560 Ch = Lo.getValue(1); 1561 1562 if (ExtType == ISD::SEXTLOAD) { 1563 // The high part is obtained by SRA'ing all but one of the bits of the 1564 // lo part. 1565 unsigned LoSize = Lo.getValueType().getSizeInBits(); 1566 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 1567 DAG.getConstant(LoSize-1, TLI.getPointerTy())); 1568 } else if (ExtType == ISD::ZEXTLOAD) { 1569 // The high part is just a zero. 1570 Hi = DAG.getConstant(0, NVT); 1571 } else { 1572 assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); 1573 // The high part is undefined. 1574 Hi = DAG.getUNDEF(NVT); 1575 } 1576 } else if (TLI.isLittleEndian()) { 1577 // Little-endian - low bits are at low addresses. 1578 Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset, 1579 isVolatile, Alignment); 1580 1581 unsigned ExcessBits = 1582 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); 1583 MVT NEVT = MVT::getIntegerVT(ExcessBits); 1584 1585 // Increment the pointer to the other half. 1586 unsigned IncrementSize = NVT.getSizeInBits()/8; 1587 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1588 DAG.getIntPtrConstant(IncrementSize)); 1589 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), 1590 SVOffset+IncrementSize, NEVT, 1591 isVolatile, MinAlign(Alignment, IncrementSize)); 1592 1593 // Build a factor node to remember that this load is independent of the 1594 // other one. 1595 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1596 Hi.getValue(1)); 1597 } else { 1598 // Big-endian - high bits are at low addresses. Favor aligned loads at 1599 // the cost of some bit-fiddling. 1600 MVT EVT = N->getMemoryVT(); 1601 unsigned EBytes = EVT.getStoreSizeInBits()/8; 1602 unsigned IncrementSize = NVT.getSizeInBits()/8; 1603 unsigned ExcessBits = (EBytes - IncrementSize)*8; 1604 1605 // Load both the high bits and maybe some of the low bits. 1606 Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, 1607 MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits), 1608 isVolatile, Alignment); 1609 1610 // Increment the pointer to the other half. 1611 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1612 DAG.getIntPtrConstant(IncrementSize)); 1613 // Load the rest of the low bits. 1614 Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(), 1615 SVOffset+IncrementSize, 1616 MVT::getIntegerVT(ExcessBits), 1617 isVolatile, MinAlign(Alignment, IncrementSize)); 1618 1619 // Build a factor node to remember that this load is independent of the 1620 // other one. 1621 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1622 Hi.getValue(1)); 1623 1624 if (ExcessBits < NVT.getSizeInBits()) { 1625 // Transfer low bits from the bottom of Hi to the top of Lo. 1626 Lo = DAG.getNode(ISD::OR, dl, NVT, Lo, 1627 DAG.getNode(ISD::SHL, dl, NVT, Hi, 1628 DAG.getConstant(ExcessBits, 1629 TLI.getPointerTy()))); 1630 // Move high bits to the right position in Hi. 1631 Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, 1632 NVT, Hi, 1633 DAG.getConstant(NVT.getSizeInBits() - ExcessBits, 1634 TLI.getPointerTy())); 1635 } 1636 } 1637 1638 // Legalized the chain result - switch anything that used the old chain to 1639 // use the new one. 1640 ReplaceValueWith(SDValue(N, 1), Ch); 1641} 1642 1643void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N, 1644 SDValue &Lo, SDValue &Hi) { 1645 DebugLoc dl = N->getDebugLoc(); 1646 SDValue LL, LH, RL, RH; 1647 GetExpandedInteger(N->getOperand(0), LL, LH); 1648 GetExpandedInteger(N->getOperand(1), RL, RH); 1649 Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL); 1650 Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH); 1651} 1652 1653void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, 1654 SDValue &Lo, SDValue &Hi) { 1655 MVT VT = N->getValueType(0); 1656 MVT NVT = TLI.getTypeToTransformTo(VT); 1657 DebugLoc dl = N->getDebugLoc(); 1658 1659 bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT); 1660 bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT); 1661 bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT); 1662 bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT); 1663 if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { 1664 SDValue LL, LH, RL, RH; 1665 GetExpandedInteger(N->getOperand(0), LL, LH); 1666 GetExpandedInteger(N->getOperand(1), RL, RH); 1667 unsigned OuterBitSize = VT.getSizeInBits(); 1668 unsigned InnerBitSize = NVT.getSizeInBits(); 1669 unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); 1670 unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); 1671 1672 APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize); 1673 if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) && 1674 DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) { 1675 // The inputs are both zero-extended. 1676 if (HasUMUL_LOHI) { 1677 // We can emit a umul_lohi. 1678 Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); 1679 Hi = SDValue(Lo.getNode(), 1); 1680 return; 1681 } 1682 if (HasMULHU) { 1683 // We can emit a mulhu+mul. 1684 Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1685 Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); 1686 return; 1687 } 1688 } 1689 if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) { 1690 // The input values are both sign-extended. 1691 if (HasSMUL_LOHI) { 1692 // We can emit a smul_lohi. 1693 Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); 1694 Hi = SDValue(Lo.getNode(), 1); 1695 return; 1696 } 1697 if (HasMULHS) { 1698 // We can emit a mulhs+mul. 1699 Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1700 Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL); 1701 return; 1702 } 1703 } 1704 if (HasUMUL_LOHI) { 1705 // Lo,Hi = umul LHS, RHS. 1706 SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl, 1707 DAG.getVTList(NVT, NVT), LL, RL); 1708 Lo = UMulLOHI; 1709 Hi = UMulLOHI.getValue(1); 1710 RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); 1711 LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); 1712 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); 1713 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); 1714 return; 1715 } 1716 if (HasMULHU) { 1717 Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1718 Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); 1719 RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); 1720 LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); 1721 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); 1722 Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); 1723 return; 1724 } 1725 } 1726 1727 // If nothing else, we can make a libcall. 1728 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1729 if (VT == MVT::i16) 1730 LC = RTLIB::MUL_I16; 1731 else if (VT == MVT::i32) 1732 LC = RTLIB::MUL_I32; 1733 else if (VT == MVT::i64) 1734 LC = RTLIB::MUL_I64; 1735 else if (VT == MVT::i128) 1736 LC = RTLIB::MUL_I128; 1737 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!"); 1738 1739 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1740 SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi); 1741} 1742 1743void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, 1744 SDValue &Lo, SDValue &Hi) { 1745 MVT VT = N->getValueType(0); 1746 DebugLoc dl = N->getDebugLoc(); 1747 1748 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1749 if (VT == MVT::i16) 1750 LC = RTLIB::SDIV_I16; 1751 else if (VT == MVT::i32) 1752 LC = RTLIB::SDIV_I32; 1753 else if (VT == MVT::i64) 1754 LC = RTLIB::SDIV_I64; 1755 else if (VT == MVT::i128) 1756 LC = RTLIB::SDIV_I128; 1757 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); 1758 1759 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1760 SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); 1761} 1762 1763void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, 1764 SDValue &Lo, SDValue &Hi) { 1765 MVT VT = N->getValueType(0); 1766 DebugLoc dl = N->getDebugLoc(); 1767 1768 // If we can emit an efficient shift operation, do so now. Check to see if 1769 // the RHS is a constant. 1770 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 1771 return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi); 1772 1773 // If we can determine that the high bit of the shift is zero or one, even if 1774 // the low bits are variable, emit this shift in an optimized form. 1775 if (ExpandShiftWithKnownAmountBit(N, Lo, Hi)) 1776 return; 1777 1778 // If this target supports shift_PARTS, use it. First, map to the _PARTS opc. 1779 unsigned PartsOpc; 1780 if (N->getOpcode() == ISD::SHL) { 1781 PartsOpc = ISD::SHL_PARTS; 1782 } else if (N->getOpcode() == ISD::SRL) { 1783 PartsOpc = ISD::SRL_PARTS; 1784 } else { 1785 assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 1786 PartsOpc = ISD::SRA_PARTS; 1787 } 1788 1789 // Next check to see if the target supports this SHL_PARTS operation or if it 1790 // will custom expand it. 1791 MVT NVT = TLI.getTypeToTransformTo(VT); 1792 TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT); 1793 if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || 1794 Action == TargetLowering::Custom) { 1795 // Expand the subcomponents. 1796 SDValue LHSL, LHSH; 1797 GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1798 1799 SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) }; 1800 MVT VT = LHSL.getValueType(); 1801 Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3); 1802 Hi = Lo.getValue(1); 1803 return; 1804 } 1805 1806 // Otherwise, emit a libcall. 1807 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1808 bool isSigned; 1809 if (N->getOpcode() == ISD::SHL) { 1810 isSigned = false; /*sign irrelevant*/ 1811 if (VT == MVT::i16) 1812 LC = RTLIB::SHL_I16; 1813 else if (VT == MVT::i32) 1814 LC = RTLIB::SHL_I32; 1815 else if (VT == MVT::i64) 1816 LC = RTLIB::SHL_I64; 1817 else if (VT == MVT::i128) 1818 LC = RTLIB::SHL_I128; 1819 } else if (N->getOpcode() == ISD::SRL) { 1820 isSigned = false; 1821 if (VT == MVT::i16) 1822 LC = RTLIB::SRL_I16; 1823 else if (VT == MVT::i32) 1824 LC = RTLIB::SRL_I32; 1825 else if (VT == MVT::i64) 1826 LC = RTLIB::SRL_I64; 1827 else if (VT == MVT::i128) 1828 LC = RTLIB::SRL_I128; 1829 } else { 1830 assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 1831 isSigned = true; 1832 if (VT == MVT::i16) 1833 LC = RTLIB::SRA_I16; 1834 else if (VT == MVT::i32) 1835 LC = RTLIB::SRA_I32; 1836 else if (VT == MVT::i64) 1837 LC = RTLIB::SRA_I64; 1838 else if (VT == MVT::i128) 1839 LC = RTLIB::SRA_I128; 1840 } 1841 1842 if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) { 1843 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1844 SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi); 1845 return; 1846 } 1847 1848 if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi)) 1849 assert(0 && "Unsupported shift!"); 1850} 1851 1852void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, 1853 SDValue &Lo, SDValue &Hi) { 1854 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 1855 DebugLoc dl = N->getDebugLoc(); 1856 SDValue Op = N->getOperand(0); 1857 if (Op.getValueType().bitsLE(NVT)) { 1858 // The low part is sign extension of the input (degenerates to a copy). 1859 Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0)); 1860 // The high part is obtained by SRA'ing all but one of the bits of low part. 1861 unsigned LoSize = NVT.getSizeInBits(); 1862 Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 1863 DAG.getConstant(LoSize-1, TLI.getPointerTy())); 1864 } else { 1865 // For example, extension of an i48 to an i64. The operand type necessarily 1866 // promotes to the result type, so will end up being expanded too. 1867 assert(getTypeAction(Op.getValueType()) == PromoteInteger && 1868 "Only know how to promote this result!"); 1869 SDValue Res = GetPromotedInteger(Op); 1870 assert(Res.getValueType() == N->getValueType(0) && 1871 "Operand over promoted?"); 1872 // Split the promoted operand. This will simplify when it is expanded. 1873 SplitInteger(Res, Lo, Hi); 1874 unsigned ExcessBits = 1875 Op.getValueType().getSizeInBits() - NVT.getSizeInBits(); 1876 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, 1877 DAG.getValueType(MVT::getIntegerVT(ExcessBits))); 1878 } 1879} 1880 1881void DAGTypeLegalizer:: 1882ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { 1883 DebugLoc dl = N->getDebugLoc(); 1884 GetExpandedInteger(N->getOperand(0), Lo, Hi); 1885 MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 1886 1887 if (EVT.bitsLE(Lo.getValueType())) { 1888 // sext_inreg the low part if needed. 1889 Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo, 1890 N->getOperand(1)); 1891 1892 // The high part gets the sign extension from the lo-part. This handles 1893 // things like sextinreg V:i64 from i8. 1894 Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo, 1895 DAG.getConstant(Hi.getValueType().getSizeInBits()-1, 1896 TLI.getPointerTy())); 1897 } else { 1898 // For example, extension of an i48 to an i64. Leave the low part alone, 1899 // sext_inreg the high part. 1900 unsigned ExcessBits = 1901 EVT.getSizeInBits() - Lo.getValueType().getSizeInBits(); 1902 Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, 1903 DAG.getValueType(MVT::getIntegerVT(ExcessBits))); 1904 } 1905} 1906 1907void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, 1908 SDValue &Lo, SDValue &Hi) { 1909 MVT VT = N->getValueType(0); 1910 DebugLoc dl = N->getDebugLoc(); 1911 1912 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1913 if (VT == MVT::i16) 1914 LC = RTLIB::SREM_I16; 1915 else if (VT == MVT::i32) 1916 LC = RTLIB::SREM_I32; 1917 else if (VT == MVT::i64) 1918 LC = RTLIB::SREM_I64; 1919 else if (VT == MVT::i128) 1920 LC = RTLIB::SREM_I128; 1921 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); 1922 1923 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1924 SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); 1925} 1926 1927void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, 1928 SDValue &Lo, SDValue &Hi) { 1929 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 1930 DebugLoc dl = N->getDebugLoc(); 1931 Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0)); 1932 Hi = DAG.getNode(ISD::SRL, dl, 1933 N->getOperand(0).getValueType(), N->getOperand(0), 1934 DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy())); 1935 Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi); 1936} 1937 1938void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, 1939 SDValue &Lo, SDValue &Hi) { 1940 MVT VT = N->getValueType(0); 1941 DebugLoc dl = N->getDebugLoc(); 1942 1943 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1944 if (VT == MVT::i16) 1945 LC = RTLIB::UDIV_I16; 1946 else if (VT == MVT::i32) 1947 LC = RTLIB::UDIV_I32; 1948 else if (VT == MVT::i64) 1949 LC = RTLIB::UDIV_I64; 1950 else if (VT == MVT::i128) 1951 LC = RTLIB::UDIV_I128; 1952 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!"); 1953 1954 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1955 SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); 1956} 1957 1958void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, 1959 SDValue &Lo, SDValue &Hi) { 1960 MVT VT = N->getValueType(0); 1961 DebugLoc dl = N->getDebugLoc(); 1962 1963 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1964 if (VT == MVT::i16) 1965 LC = RTLIB::UREM_I16; 1966 else if (VT == MVT::i32) 1967 LC = RTLIB::UREM_I32; 1968 else if (VT == MVT::i64) 1969 LC = RTLIB::UREM_I64; 1970 else if (VT == MVT::i128) 1971 LC = RTLIB::UREM_I128; 1972 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!"); 1973 1974 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1975 SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); 1976} 1977 1978void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, 1979 SDValue &Lo, SDValue &Hi) { 1980 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 1981 DebugLoc dl = N->getDebugLoc(); 1982 SDValue Op = N->getOperand(0); 1983 if (Op.getValueType().bitsLE(NVT)) { 1984 // The low part is zero extension of the input (degenerates to a copy). 1985 Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0)); 1986 Hi = DAG.getConstant(0, NVT); // The high part is just a zero. 1987 } else { 1988 // For example, extension of an i48 to an i64. The operand type necessarily 1989 // promotes to the result type, so will end up being expanded too. 1990 assert(getTypeAction(Op.getValueType()) == PromoteInteger && 1991 "Only know how to promote this result!"); 1992 SDValue Res = GetPromotedInteger(Op); 1993 assert(Res.getValueType() == N->getValueType(0) && 1994 "Operand over promoted?"); 1995 // Split the promoted operand. This will simplify when it is expanded. 1996 SplitInteger(Res, Lo, Hi); 1997 unsigned ExcessBits = 1998 Op.getValueType().getSizeInBits() - NVT.getSizeInBits(); 1999 Hi = DAG.getZeroExtendInReg(Hi, dl, MVT::getIntegerVT(ExcessBits)); 2000 } 2001} 2002 2003 2004//===----------------------------------------------------------------------===// 2005// Integer Operand Expansion 2006//===----------------------------------------------------------------------===// 2007 2008/// ExpandIntegerOperand - This method is called when the specified operand of 2009/// the specified node is found to need expansion. At this point, all of the 2010/// result types of the node are known to be legal, but other operands of the 2011/// node may need promotion or expansion as well as the specified one. 2012bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { 2013 DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n"); 2014 SDValue Res = SDValue(); 2015 2016 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 2017 return false; 2018 2019 switch (N->getOpcode()) { 2020 default: 2021 #ifndef NDEBUG 2022 cerr << "ExpandIntegerOperand Op #" << OpNo << ": "; 2023 N->dump(&DAG); cerr << "\n"; 2024 #endif 2025 assert(0 && "Do not know how to expand this operator's operand!"); 2026 abort(); 2027 2028 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 2029 case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; 2030 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 2031 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 2032 case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break; 2033 case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break; 2034 case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; 2035 case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; 2036 case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; 2037 case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break; 2038 case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; 2039 case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; 2040 2041 case ISD::SHL: 2042 case ISD::SRA: 2043 case ISD::SRL: 2044 case ISD::ROTL: 2045 case ISD::ROTR: Res = ExpandIntOp_Shift(N); break; 2046 } 2047 2048 // If the result is null, the sub-method took care of registering results etc. 2049 if (!Res.getNode()) return false; 2050 2051 // If the result is N, the sub-method updated N in place. Tell the legalizer 2052 // core about this. 2053 if (Res.getNode() == N) 2054 return true; 2055 2056 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 2057 "Invalid operand expansion"); 2058 2059 ReplaceValueWith(SDValue(N, 0), Res); 2060 return false; 2061} 2062 2063/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code 2064/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 2065void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, 2066 SDValue &NewRHS, 2067 ISD::CondCode &CCCode, 2068 DebugLoc dl) { 2069 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 2070 GetExpandedInteger(NewLHS, LHSLo, LHSHi); 2071 GetExpandedInteger(NewRHS, RHSLo, RHSHi); 2072 2073 MVT VT = NewLHS.getValueType(); 2074 2075 if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) { 2076 if (RHSLo == RHSHi) { 2077 if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) { 2078 if (RHSCST->isAllOnesValue()) { 2079 // Equality comparison to -1. 2080 NewLHS = DAG.getNode(ISD::AND, dl, 2081 LHSLo.getValueType(), LHSLo, LHSHi); 2082 NewRHS = RHSLo; 2083 return; 2084 } 2085 } 2086 } 2087 2088 NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo); 2089 NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi); 2090 NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS); 2091 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2092 return; 2093 } 2094 2095 // If this is a comparison of the sign bit, just look at the top part. 2096 // X > -1, x < 0 2097 if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS)) 2098 if ((CCCode == ISD::SETLT && CST->isNullValue()) || // X < 0 2099 (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1 2100 NewLHS = LHSHi; 2101 NewRHS = RHSHi; 2102 return; 2103 } 2104 2105 // FIXME: This generated code sucks. 2106 ISD::CondCode LowCC; 2107 switch (CCCode) { 2108 default: assert(0 && "Unknown integer setcc!"); 2109 case ISD::SETLT: 2110 case ISD::SETULT: LowCC = ISD::SETULT; break; 2111 case ISD::SETGT: 2112 case ISD::SETUGT: LowCC = ISD::SETUGT; break; 2113 case ISD::SETLE: 2114 case ISD::SETULE: LowCC = ISD::SETULE; break; 2115 case ISD::SETGE: 2116 case ISD::SETUGE: LowCC = ISD::SETUGE; break; 2117 } 2118 2119 // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison 2120 // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands 2121 // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; 2122 2123 // NOTE: on targets without efficient SELECT of bools, we can always use 2124 // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) 2125 TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); 2126 SDValue Tmp1, Tmp2; 2127 Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), 2128 LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl); 2129 if (!Tmp1.getNode()) 2130 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), 2131 LHSLo, RHSLo, LowCC); 2132 Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 2133 LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl); 2134 if (!Tmp2.getNode()) 2135 Tmp2 = DAG.getNode(ISD::SETCC, dl, 2136 TLI.getSetCCResultType(LHSHi.getValueType()), 2137 LHSHi, RHSHi, DAG.getCondCode(CCCode)); 2138 2139 ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode()); 2140 ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode()); 2141 if ((Tmp1C && Tmp1C->isNullValue()) || 2142 (Tmp2C && Tmp2C->isNullValue() && 2143 (CCCode == ISD::SETLE || CCCode == ISD::SETGE || 2144 CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) || 2145 (Tmp2C && Tmp2C->getAPIntValue() == 1 && 2146 (CCCode == ISD::SETLT || CCCode == ISD::SETGT || 2147 CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) { 2148 // low part is known false, returns high part. 2149 // For LE / GE, if high part is known false, ignore the low part. 2150 // For LT / GT, if high part is known true, ignore the low part. 2151 NewLHS = Tmp2; 2152 NewRHS = SDValue(); 2153 return; 2154 } 2155 2156 NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 2157 LHSHi, RHSHi, ISD::SETEQ, false, 2158 DagCombineInfo, dl); 2159 if (!NewLHS.getNode()) 2160 NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 2161 LHSHi, RHSHi, ISD::SETEQ); 2162 NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(), 2163 NewLHS, Tmp1, Tmp2); 2164 NewRHS = SDValue(); 2165} 2166 2167SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) { 2168 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 2169 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 2170 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2171 2172 // If ExpandSetCCOperands returned a scalar, we need to compare the result 2173 // against zero to select between true and false values. 2174 if (NewRHS.getNode() == 0) { 2175 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2176 CCCode = ISD::SETNE; 2177 } 2178 2179 // Update N to have the operands specified. 2180 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 2181 DAG.getCondCode(CCCode), NewLHS, NewRHS, 2182 N->getOperand(4)); 2183} 2184 2185SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) { 2186 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 2187 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 2188 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2189 2190 // If ExpandSetCCOperands returned a scalar, we need to compare the result 2191 // against zero to select between true and false values. 2192 if (NewRHS.getNode() == 0) { 2193 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2194 CCCode = ISD::SETNE; 2195 } 2196 2197 // Update N to have the operands specified. 2198 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 2199 N->getOperand(2), N->getOperand(3), 2200 DAG.getCondCode(CCCode)); 2201} 2202 2203SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) { 2204 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 2205 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 2206 IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2207 2208 // If ExpandSetCCOperands returned a scalar, use it. 2209 if (NewRHS.getNode() == 0) { 2210 assert(NewLHS.getValueType() == N->getValueType(0) && 2211 "Unexpected setcc expansion!"); 2212 return NewLHS; 2213 } 2214 2215 // Otherwise, update N to have the operands specified. 2216 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 2217 DAG.getCondCode(CCCode)); 2218} 2219 2220SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) { 2221 // The value being shifted is legal, but the shift amount is too big. 2222 // It follows that either the result of the shift is undefined, or the 2223 // upper half of the shift amount is zero. Just use the lower half. 2224 SDValue Lo, Hi; 2225 GetExpandedInteger(N->getOperand(1), Lo, Hi); 2226 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Lo); 2227} 2228 2229SDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) { 2230 SDValue Op = N->getOperand(0); 2231 MVT DstVT = N->getValueType(0); 2232 RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT); 2233 assert(LC != RTLIB::UNKNOWN_LIBCALL && 2234 "Don't know how to expand this SINT_TO_FP!"); 2235 return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc()); 2236} 2237 2238SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { 2239 if (ISD::isNormalStore(N)) 2240 return ExpandOp_NormalStore(N, OpNo); 2241 2242 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 2243 assert(OpNo == 1 && "Can only expand the stored value so far"); 2244 2245 MVT VT = N->getOperand(1).getValueType(); 2246 MVT NVT = TLI.getTypeToTransformTo(VT); 2247 SDValue Ch = N->getChain(); 2248 SDValue Ptr = N->getBasePtr(); 2249 int SVOffset = N->getSrcValueOffset(); 2250 unsigned Alignment = N->getAlignment(); 2251 bool isVolatile = N->isVolatile(); 2252 DebugLoc dl = N->getDebugLoc(); 2253 SDValue Lo, Hi; 2254 2255 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 2256 2257 if (N->getMemoryVT().bitsLE(NVT)) { 2258 GetExpandedInteger(N->getValue(), Lo, Hi); 2259 return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, 2260 N->getMemoryVT(), isVolatile, Alignment); 2261 } else if (TLI.isLittleEndian()) { 2262 // Little-endian - low bits are at low addresses. 2263 GetExpandedInteger(N->getValue(), Lo, Hi); 2264 2265 Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, 2266 isVolatile, Alignment); 2267 2268 unsigned ExcessBits = 2269 N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); 2270 MVT NEVT = MVT::getIntegerVT(ExcessBits); 2271 2272 // Increment the pointer to the other half. 2273 unsigned IncrementSize = NVT.getSizeInBits()/8; 2274 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 2275 DAG.getIntPtrConstant(IncrementSize)); 2276 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), 2277 SVOffset+IncrementSize, NEVT, 2278 isVolatile, MinAlign(Alignment, IncrementSize)); 2279 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 2280 } else { 2281 // Big-endian - high bits are at low addresses. Favor aligned stores at 2282 // the cost of some bit-fiddling. 2283 GetExpandedInteger(N->getValue(), Lo, Hi); 2284 2285 MVT EVT = N->getMemoryVT(); 2286 unsigned EBytes = EVT.getStoreSizeInBits()/8; 2287 unsigned IncrementSize = NVT.getSizeInBits()/8; 2288 unsigned ExcessBits = (EBytes - IncrementSize)*8; 2289 MVT HiVT = MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits); 2290 2291 if (ExcessBits < NVT.getSizeInBits()) { 2292 // Transfer high bits from the top of Lo to the bottom of Hi. 2293 Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi, 2294 DAG.getConstant(NVT.getSizeInBits() - ExcessBits, 2295 TLI.getPointerTy())); 2296 Hi = DAG.getNode(ISD::OR, dl, NVT, Hi, 2297 DAG.getNode(ISD::SRL, dl, NVT, Lo, 2298 DAG.getConstant(ExcessBits, 2299 TLI.getPointerTy()))); 2300 } 2301 2302 // Store both the high bits and maybe some of the low bits. 2303 Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), 2304 SVOffset, HiVT, isVolatile, Alignment); 2305 2306 // Increment the pointer to the other half. 2307 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 2308 DAG.getIntPtrConstant(IncrementSize)); 2309 // Store the lowest ExcessBits bits in the second half. 2310 Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), 2311 SVOffset+IncrementSize, 2312 MVT::getIntegerVT(ExcessBits), 2313 isVolatile, MinAlign(Alignment, IncrementSize)); 2314 return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 2315 } 2316} 2317 2318SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) { 2319 SDValue InL, InH; 2320 GetExpandedInteger(N->getOperand(0), InL, InH); 2321 // Just truncate the low part of the source. 2322 return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL); 2323} 2324 2325SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { 2326 SDValue Op = N->getOperand(0); 2327 MVT SrcVT = Op.getValueType(); 2328 MVT DstVT = N->getValueType(0); 2329 DebugLoc dl = N->getDebugLoc(); 2330 2331 if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){ 2332 // Do a signed conversion then adjust the result. 2333 SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op); 2334 SignedConv = TLI.LowerOperation(SignedConv, DAG); 2335 2336 // The result of the signed conversion needs adjusting if the 'sign bit' of 2337 // the incoming integer was set. To handle this, we dynamically test to see 2338 // if it is set, and, if so, add a fudge factor. 2339 2340 const uint64_t F32TwoE32 = 0x4F800000ULL; 2341 const uint64_t F32TwoE64 = 0x5F800000ULL; 2342 const uint64_t F32TwoE128 = 0x7F800000ULL; 2343 2344 APInt FF(32, 0); 2345 if (SrcVT == MVT::i32) 2346 FF = APInt(32, F32TwoE32); 2347 else if (SrcVT == MVT::i64) 2348 FF = APInt(32, F32TwoE64); 2349 else if (SrcVT == MVT::i128) 2350 FF = APInt(32, F32TwoE128); 2351 else 2352 assert(false && "Unsupported UINT_TO_FP!"); 2353 2354 // Check whether the sign bit is set. 2355 SDValue Lo, Hi; 2356 GetExpandedInteger(Op, Lo, Hi); 2357 SDValue SignSet = DAG.getSetCC(dl, 2358 TLI.getSetCCResultType(Hi.getValueType()), 2359 Hi, DAG.getConstant(0, Hi.getValueType()), 2360 ISD::SETLT); 2361 2362 // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits. 2363 SDValue FudgePtr = DAG.getConstantPool(ConstantInt::get(FF.zext(64)), 2364 TLI.getPointerTy()); 2365 2366 // Get a pointer to FF if the sign bit was set, or to 0 otherwise. 2367 SDValue Zero = DAG.getIntPtrConstant(0); 2368 SDValue Four = DAG.getIntPtrConstant(4); 2369 if (TLI.isBigEndian()) std::swap(Zero, Four); 2370 SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, 2371 Zero, Four); 2372 unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment(); 2373 FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset); 2374 Alignment = std::min(Alignment, 4u); 2375 2376 // Load the value out, extending it from f32 to the destination float type. 2377 // FIXME: Avoid the extend by constructing the right constant pool? 2378 SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(), 2379 FudgePtr, NULL, 0, MVT::f32, 2380 false, Alignment); 2381 return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge); 2382 } 2383 2384 // Otherwise, use a libcall. 2385 RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT); 2386 assert(LC != RTLIB::UNKNOWN_LIBCALL && 2387 "Don't know how to expand this UINT_TO_FP!"); 2388 return MakeLibCall(LC, DstVT, &Op, 1, true, dl); 2389} 2390