X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsISelLowering.cpp;h=8bf4249af1e5d37343bae9d14f44bd3d373aab05;hb=407883b69b3bc10ebf053f5922d877b2e786d124;hp=ab105b365540963eefab0b881f2423a2b7bcdd5e;hpb=46090914b783b632618268f2a5c99aab83732688;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ab105b36554..8bf4249af1e 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -43,6 +43,11 @@ static cl::opt LargeGOT("mxgot", cl::Hidden, cl::desc("MIPS: Enable GOT larger than 64k."), cl::init(false)); +static cl::opt +NoZeroDivCheck("mno-check-zero-division", cl::Hidden, + cl::desc("MIPS: Don't trap on integer division by zero."), + cl::init(false)); + static const uint16_t O32IntRegs[4] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 }; @@ -65,7 +70,7 @@ static bool isShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size) { return false; Size = CountPopulation_64(I); - Pos = CountTrailingZeros_64(I); + Pos = countTrailingZeros(I); return true; } @@ -78,7 +83,7 @@ static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) { EVT Ty = Op.getValueType(); if (GlobalAddressSDNode *N = dyn_cast(Op)) - return DAG.getTargetGlobalAddress(N->getGlobal(), Op.getDebugLoc(), Ty, 0, + return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(Op), Ty, 0, Flag); if (ExternalSymbolSDNode *N = dyn_cast(Op)) return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag); @@ -95,7 +100,7 @@ static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) { } static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Hi = getTargetNode(Op, DAG, MipsII::MO_ABS_HI); SDValue Lo = getTargetNode(Op, DAG, MipsII::MO_ABS_LO); @@ -106,7 +111,7 @@ static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) { SDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG, bool HasMips64) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT; SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), @@ -121,7 +126,7 @@ SDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG, SDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG, unsigned Flag) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), getTargetNode(Op, DAG, Flag)); @@ -132,7 +137,7 @@ SDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG, SDValue MipsTargetLowering::getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(Op, DAG, HiFlag)); Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty)); @@ -156,7 +161,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::FPCmp: return "MipsISD::FPCmp"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; - case MipsISD::FPRound: return "MipsISD::FPRound"; + case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI"; case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI"; case MipsISD::Mult: return "MipsISD::Mult"; @@ -250,6 +255,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); if (!TM.Options.NoNaNsFPMath) { setOperationAction(ISD::FABS, MVT::f32, Custom); @@ -265,6 +271,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SELECT, MVT::i64, Custom); setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); } if (!HasMips64) { @@ -339,11 +346,6 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::FNEG, MVT::f64, Expand); } - setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); - setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); - setOperationAction(ISD::EHSELECTION, MVT::i64, Expand); - setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::Other, Expand); @@ -407,7 +409,7 @@ const MipsTargetLowering *MipsTargetLowering::create(MipsTargetMachine &TM) { return llvm::createMipsSETargetLowering(TM); } -EVT MipsTargetLowering::getSetCCResultType(EVT VT) const { +EVT MipsTargetLowering::getSetCCResultType(LLVMContext &, EVT VT) const { if (!VT.isVector()) return MVT::i32; return VT.changeVectorElementTypeToInteger(); @@ -424,7 +426,7 @@ static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, unsigned HI = (Ty == MVT::i32) ? Mips::HI : Mips::HI64; unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem16 : MipsISD::DivRemU16; - DebugLoc DL = N->getDebugLoc(); + SDLoc DL(N); SDValue DivRem = DAG.getNode(Opc, DL, MVT::Glue, N->getOperand(0), N->getOperand(1)); @@ -502,7 +504,7 @@ static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { return Op; SDValue RHS = Op.getOperand(1); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of // node if necessary. @@ -514,12 +516,13 @@ static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { // Creates and returns a CMovFPT/F node. static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, - SDValue False, DebugLoc DL) { + SDValue False, SDLoc DL) { ConstantSDNode *CC = cast(Cond.getOperand(2)); bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue()); + SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32); return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL, - True.getValueType(), True, False, Cond); + True.getValueType(), True, FCC0, False, Cond); } static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, @@ -545,7 +548,7 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, if (!CN || CN->getZExtValue()) return SDValue(); - const DebugLoc DL = N->getDebugLoc(); + const SDLoc DL(N); ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); SDValue True = N->getOperand(1); @@ -590,7 +593,7 @@ static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits()) return SDValue(); - return DAG.getNode(MipsISD::Ext, N->getDebugLoc(), ValTy, + return DAG.getNode(MipsISD::Ext, SDLoc(N), ValTy, ShiftRight.getOperand(0), DAG.getConstant(Pos, MVT::i32), DAG.getConstant(SMSize, MVT::i32)); } @@ -644,7 +647,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits())) return SDValue(); - return DAG.getNode(MipsISD::Ins, N->getDebugLoc(), ValTy, Shl.getOperand(0), + return DAG.getNode(MipsISD::Ins, SDLoc(N), ValTy, Shl.getOperand(0), DAG.getConstant(SMPos0, MVT::i32), DAG.getConstant(SMSize0, MVT::i32), And0.getOperand(0)); } @@ -669,7 +672,7 @@ static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); EVT ValTy = N->getValueType(0); - DebugLoc DL = N->getDebugLoc(); + SDLoc DL(N); SDValue Add1 = DAG.getNode(ISD::ADD, DL, ValTy, N->getOperand(0), Add.getOperand(0)); @@ -744,6 +747,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::ADD: return lowerADD(Op, DAG); + case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); } return SDValue(); } @@ -763,6 +767,26 @@ addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC) return VReg; } +static MachineBasicBlock *expandPseudoDIV(MachineInstr *MI, + MachineBasicBlock &MBB, + const TargetInstrInfo &TII, + bool Is64Bit) { + if (NoZeroDivCheck) + return &MBB; + + // Insert instruction "teq $divisor_reg, $zero, 7". + MachineBasicBlock::iterator I(MI); + MachineInstrBuilder MIB; + MIB = BuildMI(MBB, llvm::next(I), MI->getDebugLoc(), TII.get(Mips::TEQ)) + .addOperand(MI->getOperand(2)).addReg(Mips::ZERO).addImm(7); + + // Use the 32-bit sub-register if this is a 64-bit division. + if (Is64Bit) + MIB->getOperand(0).setSubReg(Mips::sub_32); + + return &MBB; +} + MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { @@ -872,6 +896,12 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case Mips::ATOMIC_CMP_SWAP_I64: case Mips::ATOMIC_CMP_SWAP_I64_P8: return emitAtomicCmpSwap(MI, BB, 8); + case Mips::PseudoSDIV: + case Mips::PseudoUDIV: + return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), false); + case Mips::PseudoDSDIV: + case Mips::PseudoDUDIV: + return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), true); } } @@ -1039,13 +1069,20 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr) .addReg(Ptr).addReg(MaskLSB2); BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3); - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + if (Subtarget->isLittle()) { + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + } else { + unsigned Off = RegInfo.createVirtualRegister(RC); + BuildMI(BB, DL, TII->get(Mips::XORi), Off) + .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3); + } BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) - .addReg(ShiftAmt).addReg(MaskUpper); + .addReg(MaskUpper).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); - BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(ShiftAmt).addReg(Incr); + BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt); // atomic.load.binop // loopMBB: @@ -1106,7 +1143,7 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), MaskedOldVal1) .addReg(OldVal).addReg(Mask); BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) - .addReg(ShiftAmt).addReg(MaskedOldVal1); + .addReg(MaskedOldVal1).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::SLL), SllRes) .addReg(SrlRes).addImm(ShiftImm); BuildMI(BB, DL, TII->get(Mips::SRA), Dest) @@ -1282,20 +1319,27 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr) .addReg(Ptr).addReg(MaskLSB2); BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3); - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + if (Subtarget->isLittle()) { + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + } else { + unsigned Off = RegInfo.createVirtualRegister(RC); + BuildMI(BB, DL, TII->get(Mips::XORi), Off) + .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3); + } BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) - .addReg(ShiftAmt).addReg(MaskUpper); + .addReg(MaskUpper).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal) .addReg(CmpVal).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal) - .addReg(ShiftAmt).addReg(MaskedCmpVal); + .addReg(MaskedCmpVal).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal) .addReg(NewVal).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal) - .addReg(ShiftAmt).addReg(MaskedNewVal); + .addReg(MaskedNewVal).addReg(ShiftAmt); // loop1MBB: // ll oldval,0(alginedaddr) @@ -1331,7 +1375,7 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI, int64_t ShiftImm = (Size == 1) ? 24 : 16; BuildMI(BB, DL, TII->get(Mips::SRLV), SrlRes) - .addReg(ShiftAmt).addReg(MaskedOldVal0); + .addReg(MaskedOldVal0).addReg(ShiftAmt); BuildMI(BB, DL, TII->get(Mips::SLL), SllRes) .addReg(SrlRes).addImm(ShiftImm); BuildMI(BB, DL, TII->get(Mips::SRA), Dest) @@ -1349,7 +1393,7 @@ SDValue MipsTargetLowering::lowerBR_JT(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Table = Op.getOperand(1); SDValue Index = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT PTy = getPointerTy(); unsigned EntrySize = DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(*getDataLayout()); @@ -1382,7 +1426,7 @@ lowerBRCOND(SDValue Op, SelectionDAG &DAG) const // the block to branch to if the condition is true. SDValue Chain = Op.getOperand(0); SDValue Dest = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue CondRes = createFPCmp(DAG, Op.getOperand(1)); @@ -1395,8 +1439,9 @@ lowerBRCOND(SDValue Op, SelectionDAG &DAG) const (Mips::CondCode)cast(CCNode)->getZExtValue(); unsigned Opc = invertFPCondCodeUser(CC) ? Mips::BRANCH_F : Mips::BRANCH_T; SDValue BrCode = DAG.getConstant(Opc, MVT::i32); + SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32); return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode, - Dest, CondRes); + FCC0, Dest, CondRes); } SDValue MipsTargetLowering:: @@ -1409,15 +1454,16 @@ lowerSELECT(SDValue Op, SelectionDAG &DAG) const return Op; return createCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2), - Op.getDebugLoc()); + SDLoc(Op)); } SDValue MipsTargetLowering:: lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getOperand(0).getValueType(); - SDValue Cond = DAG.getNode(ISD::SETCC, DL, getSetCCResultType(Ty), + SDValue Cond = DAG.getNode(ISD::SETCC, DL, + getSetCCResultType(*DAG.getContext(), Ty), Op.getOperand(0), Op.getOperand(1), Op.getOperand(4)); @@ -1434,13 +1480,13 @@ SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const { SDValue True = DAG.getConstant(1, MVT::i32); SDValue False = DAG.getConstant(0, MVT::i32); - return createCMovFP(DAG, Cond, True, False, Op.getDebugLoc()); + return createCMovFP(DAG, Cond, True, False, SDLoc(Op)); } SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { // FIXME there isn't actually debug info here - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); const GlobalValue *GV = cast(Op)->getGlobal(); if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) { @@ -1488,7 +1534,7 @@ lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const // Local Exec TLS Model. GlobalAddressSDNode *GA = cast(Op); - DebugLoc DL = GA->getDebugLoc(); + SDLoc DL(GA); const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(); @@ -1593,7 +1639,7 @@ SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *FuncInfo = MF.getInfo(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), getPointerTy()); @@ -1609,7 +1655,7 @@ static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasR2) { EVT TyY = Op.getOperand(1).getValueType(); SDValue Const1 = DAG.getConstant(1, MVT::i32); SDValue Const31 = DAG.getConstant(31, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Res; // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it @@ -1654,7 +1700,7 @@ static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasR2) { unsigned WidthY = Op.getOperand(1).getValueSizeInBits(); EVT TyX = MVT::getIntegerVT(WidthX), TyY = MVT::getIntegerVT(WidthY); SDValue Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Bitcast to integer nodes. SDValue X = DAG.getNode(ISD::BITCAST, DL, TyX, Op.getOperand(0)); @@ -1707,7 +1753,7 @@ MipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const { static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasR2) { SDValue Res, Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it // to i32. @@ -1736,7 +1782,7 @@ static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasR2) { static SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG, bool HasR2) { SDValue Res, Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Bitcast to integer node. SDValue X = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Op.getOperand(0)); @@ -1771,7 +1817,7 @@ lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, IsN64 ? Mips::FP_64 : Mips::FP, VT); return FrameAddr; @@ -1791,7 +1837,7 @@ SDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op, // Return RA, which contains the return address. Mark it an implicit live-in. unsigned Reg = MF.addLiveIn(RA, getRegClassFor(VT)); - return DAG.getCopyFromReg(DAG.getEntryNode(), Op.getDebugLoc(), Reg, VT); + return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, VT); } // An EH_RETURN is the result of lowering llvm.eh.return which in turn is @@ -1807,7 +1853,7 @@ SDValue MipsTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) SDValue Chain = Op.getOperand(0); SDValue Offset = Op.getOperand(1); SDValue Handler = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = IsN64 ? MVT::i64 : MVT::i32; // Store stack offset in V1, store jump target in V0. Glue CopyToReg and @@ -1827,14 +1873,14 @@ SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op, // FIXME: Need pseudo-fence for 'singlethread' fences // FIXME: Set SType for weaker fences where supported/appropriate. unsigned SType = 0; - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0), DAG.getConstant(SType, MVT::i32)); } SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); SDValue Shamt = Op.getOperand(2); @@ -1865,7 +1911,7 @@ SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op, SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); SDValue Shamt = Op.getOperand(2); @@ -1909,7 +1955,7 @@ static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Ptr = LD->getBasePtr(); EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT(); EVT BasePtrVT = Ptr.getValueType(); - DebugLoc DL = LD->getDebugLoc(); + SDLoc DL(LD); SDVTList VTList = DAG.getVTList(VT, MVT::Other); if (Offset) @@ -1975,7 +2021,7 @@ SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { // (set tmp1, (lwr baseptr, tmp0)) // (set tmp2, (shl tmp1, 32)) // (set dst, (srl tmp2, 32)) - DebugLoc DL = LD->getDebugLoc(); + SDLoc DL(LD); SDValue Const32 = DAG.getConstant(32, MVT::i32); SDValue SLL = DAG.getNode(ISD::SHL, DL, MVT::i64, LWR, Const32); SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i64, SLL, Const32); @@ -1987,7 +2033,7 @@ static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset) { SDValue Ptr = SD->getBasePtr(), Value = SD->getValue(); EVT MemVT = SD->getMemoryVT(), BasePtrVT = Ptr.getValueType(); - DebugLoc DL = SD->getDebugLoc(); + SDLoc DL(SD); SDVTList VTList = DAG.getVTList(MVT::Other); if (Offset) @@ -2000,16 +2046,8 @@ static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, } // Expand an unaligned 32 or 64-bit integer store node. -SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { - StoreSDNode *SD = cast(Op); - EVT MemVT = SD->getMemoryVT(); - - // Return if store is aligned or if MemVT is neither i32 nor i64. - if ((SD->getAlignment() >= MemVT.getSizeInBits() / 8) || - ((MemVT != MVT::i32) && (MemVT != MVT::i64))) - return SDValue(); - - bool IsLittle = Subtarget->isLittle(); +static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, + bool IsLittle) { SDValue Value = SD->getValue(), Chain = SD->getChain(); EVT VT = Value.getValueType(); @@ -2036,6 +2074,34 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7); } +// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). +static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG) { + SDValue Val = SD->getValue(); + + if (Val.getOpcode() != ISD::FP_TO_SINT) + return SDValue(); + + EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); + SDValue Tr = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Val), FPTy, + Val.getOperand(0)); + + return DAG.getStore(SD->getChain(), SDLoc(SD), Tr, SD->getBasePtr(), + SD->getPointerInfo(), SD->isVolatile(), + SD->isNonTemporal(), SD->getAlignment()); +} + +SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { + StoreSDNode *SD = cast(Op); + EVT MemVT = SD->getMemoryVT(); + + // Lower unaligned integer stores. + if ((SD->getAlignment() < MemVT.getSizeInBits() / 8) && + ((MemVT == MVT::i32) || (MemVT == MVT::i64))) + return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle()); + + return lowerFP_TO_SINT_STORE(SD, DAG); +} + SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { if (Op->getOperand(0).getOpcode() != ISD::FRAMEADDR || cast @@ -2053,10 +2119,18 @@ SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { EVT ValTy = Op->getValueType(0); int FI = MFI->CreateFixedObject(Op.getValueSizeInBits() / 8, 0, false); SDValue InArgsAddr = DAG.getFrameIndex(FI, ValTy); - return DAG.getNode(ISD::ADD, Op->getDebugLoc(), ValTy, InArgsAddr, + return DAG.getNode(ISD::ADD, SDLoc(Op), ValTy, InArgsAddr, DAG.getConstant(0, ValTy)); } +SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, + SelectionDAG &DAG) const { + EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); + SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy, + Op.getOperand(0)); + return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -2175,7 +2249,7 @@ static unsigned getNextIntArgReg(unsigned Reg) { SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset, - SDValue Chain, SDValue Arg, DebugLoc DL, + SDValue Chain, SDValue Arg, SDLoc DL, bool IsTailCall, SelectionDAG &DAG) const { if (!IsTailCall) { SDValue PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, @@ -2250,10 +2324,10 @@ SDValue MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl &InVals) const { SelectionDAG &DAG = CLI.DAG; - DebugLoc &DL = CLI.DL; - SmallVector &Outs = CLI.Outs; - SmallVector &OutVals = CLI.OutVals; - SmallVector &Ins = CLI.Ins; + SDLoc DL = CLI.DL; + SmallVectorImpl &Outs = CLI.Outs; + SmallVectorImpl &OutVals = CLI.OutVals; + SmallVectorImpl &Ins = CLI.Ins; SDValue Chain = CLI.Chain; SDValue Callee = CLI.Callee; bool &IsTailCall = CLI.IsTailCall; @@ -2297,7 +2371,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SDValue NextStackOffsetVal = DAG.getIntPtrConstant(NextStackOffset, true); if (!IsTailCall) - Chain = DAG.getCALLSEQ_START(Chain, NextStackOffsetVal); + Chain = DAG.getCALLSEQ_START(Chain, NextStackOffsetVal, DL); SDValue StackPtr = DAG.getCopyFromReg(Chain, DL, IsN64 ? Mips::SP_64 : Mips::SP, @@ -2435,7 +2509,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Create the CALLSEQ_END node. Chain = DAG.getCALLSEQ_END(Chain, NextStackOffsetVal, - DAG.getIntPtrConstant(0, true), InFlag); + DAG.getIntPtrConstant(0, true), InFlag, DL); InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we @@ -2450,7 +2524,7 @@ SDValue MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Ins, - DebugLoc DL, SelectionDAG &DAG, + SDLoc DL, SelectionDAG &DAG, SmallVectorImpl &InVals, const SDNode *CallNode, const Type *RetTy) const { @@ -2489,7 +2563,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Ins, - DebugLoc DL, SelectionDAG &DAG, + SDLoc DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); @@ -2655,7 +2729,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, - DebugLoc DL, SelectionDAG &DAG) const { + SDLoc DL, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of // the return value to a location SmallVector RVLocs; @@ -2808,7 +2882,7 @@ MipsTargetLowering::getSingleConstraintMatchWeight( /// to an LLVM register class, return a register of 0 and the register class /// pointer. std::pair MipsTargetLowering:: -getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const +getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { @@ -3265,7 +3339,7 @@ MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy, } void MipsTargetLowering:: -copyByValRegs(SDValue Chain, DebugLoc DL, std::vector &OutChains, +copyByValRegs(SDValue Chain, SDLoc DL, std::vector &OutChains, SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl &InVals, const Argument *FuncArg, const MipsCC &CC, const ByValArgInfo &ByVal) const { @@ -3309,9 +3383,9 @@ copyByValRegs(SDValue Chain, DebugLoc DL, std::vector &OutChains, // Copy byVal arg to registers and stack. void MipsTargetLowering:: -passByValArg(SDValue Chain, DebugLoc DL, +passByValArg(SDValue Chain, SDLoc DL, std::deque< std::pair > &RegsToPass, - SmallVector &MemOpChains, SDValue StackPtr, + SmallVectorImpl &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, const MipsCC &CC, const ByValArgInfo &ByVal, const ISD::ArgFlagsTy &Flags, bool isLittle) const { @@ -3407,7 +3481,7 @@ passByValArg(SDValue Chain, DebugLoc DL, void MipsTargetLowering::writeVarArgRegs(std::vector &OutChains, const MipsCC &CC, SDValue Chain, - DebugLoc DL, SelectionDAG &DAG) const { + SDLoc DL, SelectionDAG &DAG) const { unsigned NumRegs = CC.numIntArgRegs(); const uint16_t *ArgRegs = CC.intArgRegs(); const CCState &CCInfo = CC.getCCInfo();