diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp | 151 |
1 files changed, 99 insertions, 52 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 8738bc8..2ac9aae 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -32,6 +32,7 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -403,7 +404,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( if (InIdx != 0) report_fatal_error("sparc only supports sret on the first parameter"); // Get SRet from [%fp+64]. - int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, 64, true); + int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, 64, true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); SDValue Arg = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); @@ -424,7 +425,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( SDValue LoVal; if (NextVA.isMemLoc()) { - int FrameIdx = MF.getFrameInfo()-> + int FrameIdx = MF.getFrameInfo(). CreateFixedObject(4, StackOffset+NextVA.getLocMemOffset(),true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); @@ -466,9 +467,9 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( assert(VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::v2i32); // If it is double-word aligned, just load. if (Offset % 8 == 0) { - int FI = MF.getFrameInfo()->CreateFixedObject(8, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(8, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo()); @@ -476,15 +477,15 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( continue; } - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(4, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, MachinePointerInfo()); - int FI2 = MF.getFrameInfo()->CreateFixedObject(4, - Offset+4, - true); + int FI2 = MF.getFrameInfo().CreateFixedObject(4, + Offset+4, + true); SDValue FIPtr2 = DAG.getFrameIndex(FI2, PtrVT); SDValue LoVal = @@ -500,9 +501,9 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( continue; } - int FI = MF.getFrameInfo()->CreateFixedObject(4, - Offset, - true); + int FI = MF.getFrameInfo().CreateFixedObject(4, + Offset, + true); SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT); SDValue Load ; if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) { @@ -554,8 +555,8 @@ SDValue SparcTargetLowering::LowerFormalArguments_32( MF.getRegInfo().addLiveIn(*CurArgReg, VReg); SDValue Arg = DAG.getCopyFromReg(DAG.getRoot(), dl, VReg, MVT::i32); - int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset, - true); + int FrameIdx = MF.getFrameInfo().CreateFixedObject(4, ArgOffset, + true); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); OutChains.push_back( @@ -638,7 +639,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_64( // prefer our own extending loads. if (VA.isExtInLoc()) Offset += 8 - ValSize; - int FI = MF.getFrameInfo()->CreateFixedObject(ValSize, Offset, true); + int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true); InVals.push_back( DAG.getLoad(VA.getValVT(), DL, Chain, DAG.getFrameIndex(FI, getPointerTy(MF.getDataLayout())), @@ -668,7 +669,7 @@ SDValue SparcTargetLowering::LowerFormalArguments_64( for (; ArgOffset < 6*8; ArgOffset += 8) { unsigned VReg = MF.addLiveIn(SP::I0 + ArgOffset/8, &SP::I64RegsRegClass); SDValue VArg = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i64); - int FI = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset + ArgArea, true); + int FI = MF.getFrameInfo().CreateFixedObject(8, ArgOffset + ArgArea, true); auto PtrVT = getPointerTy(MF.getDataLayout()); OutChains.push_back( DAG.getStore(Chain, DL, VArg, DAG.getFrameIndex(FI, PtrVT), @@ -740,7 +741,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, // Keep stack frames 8-byte aligned. ArgsSize = (ArgsSize+7) & ~7; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); // Create local copies for byval args. SmallVector<SDValue, 8> ByValArgs; @@ -754,7 +755,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI, unsigned Align = Flags.getByValAlign(); if (Size > 0U) { - int FI = MFI->CreateStackObject(Size, Align, false); + int FI = MFI.CreateStackObject(Size, Align, false); SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); SDValue SizeNode = DAG.getConstant(Size, dl, MVT::i32); @@ -1207,7 +1208,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI, if (VA.isRegLoc()) { if (VA.needsCustom() && VA.getValVT() == MVT::f128 && VA.getLocVT() == MVT::i128) { - // Store and reload into the interger register reg and reg+1. + // Store and reload into the integer register reg and reg+1. unsigned Offset = 8 * (VA.getLocReg() - SP::I0); unsigned StackOffset = Offset + Subtarget->getStackPointerBias() + 128; SDValue StackPtr = DAG.getRegister(SP::O6, PtrVT); @@ -1507,7 +1508,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // AddPromotedToType(ISD::STORE, MVT::i64, MVT::v2i32); } - // Turn FP extload into load/fextend + // Turn FP extload into load/fpextend for (MVT VT : MVT::fp_valuetypes()) { setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand); setLoadExtAction(ISD::EXTLOAD, VT, MVT::f64, Expand); @@ -1616,8 +1617,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // Atomics are supported on SparcV9. 32-bit atomics are also // supported by some Leon SparcV8 variants. Otherwise, atomics // are unsupported. - if (Subtarget->isV9() || Subtarget->hasLeonCasa()) + if (Subtarget->isV9()) setMaxAtomicSizeInBitsSupported(64); + else if (Subtarget->hasLeonCasa()) + setMaxAtomicSizeInBitsSupported(32); else setMaxAtomicSizeInBitsSupported(0); @@ -1638,6 +1641,13 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom); } + if (!Subtarget->is64Bit()) { + // These libcalls are not available in 32-bit. + setLibcallName(RTLIB::SHL_I128, nullptr); + setLibcallName(RTLIB::SRL_I128, nullptr); + setLibcallName(RTLIB::SRA_I128, nullptr); + } + if (!Subtarget->isV9()) { // SparcV8 does not have FNEGD and FABSD. setOperationAction(ISD::FNEG, MVT::f64, Custom); @@ -1675,9 +1685,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - // FIXME: Sparc provides these multiplies, but we don't have them yet. - setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); - setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); + // Expands to [SU]MUL_LOHI. + setOperationAction(ISD::MULHU, MVT::i32, Expand); + setOperationAction(ISD::MULHS, MVT::i32, Expand); + setOperationAction(ISD::MUL, MVT::i32, Expand); if (Subtarget->is64Bit()) { setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); @@ -1961,8 +1972,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue Op, SelectionDAG &DAG) const { SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this // function has calls. - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setHasCalls(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setHasCalls(true); return DAG.getLoad(VT, DL, DAG.getEntryNode(), AbsAddr, MachinePointerInfo::getGOT(DAG.getMachineFunction())); } @@ -2089,8 +2100,8 @@ SDValue SparcTargetLowering::LowerGlobalTLSAddress(SDValue Op, // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this // function has calls. - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setHasCalls(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setHasCalls(true); SDValue TGA = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_TLS_IE_HI22, @@ -2120,7 +2131,7 @@ SDValue SparcTargetLowering::LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, const SDLoc &DL, SelectionDAG &DAG) const { - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); EVT ArgVT = Arg.getValueType(); Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); @@ -2130,7 +2141,7 @@ SDValue SparcTargetLowering::LowerF128_LibCallArg(SDValue Chain, if (ArgTy->isFP128Ty()) { // Create a stack object and pass the pointer to the library function. - int FI = MFI->CreateStackObject(16, 8, false); + int FI = MFI.CreateStackObject(16, 8, false); SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); Chain = DAG.getStore(Chain, DL, Entry.Node, FIPtr, MachinePointerInfo(), /* Alignment = */ 8); @@ -2149,7 +2160,7 @@ SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, ArgListTy Args; - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); auto PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Callee = DAG.getExternalSymbol(LibFuncName, PtrVT); @@ -2161,7 +2172,7 @@ SparcTargetLowering::LowerF128Op(SDValue Op, SelectionDAG &DAG, if (RetTy->isFP128Ty()) { // Create a Stack Object to receive the return value of type f128. ArgListEntry Entry; - int RetFI = MFI->CreateStackObject(16, 8, false); + int RetFI = MFI.CreateStackObject(16, 8, false); RetPtr = DAG.getFrameIndex(RetFI, PtrVT); Entry.Node = RetPtr; Entry.Ty = PointerType::getUnqual(RetTy); @@ -2517,7 +2528,7 @@ static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, auto PtrVT = TLI.getPointerTy(DAG.getDataLayout()); // Need frame address to find the address of VarArgsFrameIndex. - MF.getFrameInfo()->setFrameAddressIsTaken(true); + MF.getFrameInfo().setFrameAddressIsTaken(true); // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. @@ -2557,17 +2568,57 @@ static SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget) { SDValue Chain = Op.getOperand(0); // Legalize the chain. SDValue Size = Op.getOperand(1); // Legalize the size. + unsigned Align = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue(); + unsigned StackAlign = Subtarget->getFrameLowering()->getStackAlignment(); EVT VT = Size->getValueType(0); SDLoc dl(Op); + // TODO: implement over-aligned alloca. (Note: also implies + // supporting support for overaligned function frames + dynamic + // allocations, at all, which currently isn't supported) + if (Align > StackAlign) { + const MachineFunction &MF = DAG.getMachineFunction(); + report_fatal_error("Function \"" + Twine(MF.getName()) + "\": " + "over-aligned dynamic alloca not supported."); + } + + // The resultant pointer needs to be above the register spill area + // at the bottom of the stack. + unsigned regSpillArea; + if (Subtarget->is64Bit()) { + regSpillArea = 128; + } else { + // On Sparc32, the size of the spill area is 92. Unfortunately, + // that's only 4-byte aligned, not 8-byte aligned (the stack + // pointer is 8-byte aligned). So, if the user asked for an 8-byte + // aligned dynamic allocation, we actually need to add 96 to the + // bottom of the stack, instead of 92, to ensure 8-byte alignment. + + // That also means adding 4 to the size of the allocation -- + // before applying the 8-byte rounding. Unfortunately, we the + // value we get here has already had rounding applied. So, we need + // to add 8, instead, wasting a bit more memory. + + // Further, this only actually needs to be done if the required + // alignment is > 4, but, we've lost that info by this point, too, + // so we always apply it. + + // (An alternative approach would be to always reserve 96 bytes + // instead of the required 92, but then we'd waste 4 extra bytes + // in every frame, not just those with dynamic stack allocations) + + // TODO: modify code in SelectionDAGBuilder to make this less sad. + + Size = DAG.getNode(ISD::ADD, dl, VT, Size, + DAG.getConstant(8, dl, VT)); + regSpillArea = 96; + } + unsigned SPReg = SP::O6; SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); SDValue NewSP = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value Chain = DAG.getCopyToReg(SP.getValue(1), dl, SPReg, NewSP); // Output chain - // The resultant pointer is actually 16 words from the bottom of the stack, - // to provide a register spill area. - unsigned regSpillArea = Subtarget->is64Bit() ? 128 : 96; regSpillArea += Subtarget->getStackPointerBias(); SDValue NewVal = DAG.getNode(ISD::ADD, dl, VT, NewSP, @@ -2586,8 +2637,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG &DAG) { static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget) { - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); - MFI->setFrameAddressIsTaken(true); + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MFI.setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); SDLoc dl(Op); @@ -2628,14 +2679,15 @@ static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, uint64_t depth = Op.getConstantOperandVal(0); return getFRAMEADDR(depth, Op, DAG, Subtarget); + } static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, const SparcTargetLowering &TLI, const SparcSubtarget *Subtarget) { MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MFI->setReturnAddressIsTaken(true); + MachineFrameInfo &MFI = MF.getFrameInfo(); + MFI.setReturnAddressIsTaken(true); if (TLI.verifyReturnAddressArgumentIsConstant(Op, DAG)) return SDValue(); @@ -2805,7 +2857,7 @@ static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) SDValue Val = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, St->getValue()); SDValue Chain = DAG.getStore( St->getChain(), dl, Val, St->getBasePtr(), St->getPointerInfo(), - St->isVolatile(), St->getMemOperand()->getFlags(), St->getAAInfo()); + St->getAlignment(), St->getMemOperand()->getFlags(), St->getAAInfo()); return Chain; } @@ -3042,7 +3094,7 @@ MachineBasicBlock * SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const { switch (MI.getOpcode()) { - default: llvm_unreachable("Unknown Custom Instruction!"); + default: llvm_unreachable("Unknown SELECT_CC!"); case SP::SELECT_CC_Int_ICC: case SP::SELECT_CC_FP_ICC: case SP::SELECT_CC_DFP_ICC: @@ -3059,6 +3111,7 @@ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, case SP::EH_SJLJ_LONGJMP32rr: case SP::EH_SJLJ_LONGJMP32ri: return emitEHSjLjLongJmp(MI, BB); + } } @@ -3329,11 +3382,8 @@ SparcTargetLowering::ConstraintType SparcTargetLowering::getConstraintType(StringRef Constraint) const { if (Constraint.size() == 1) { switch (Constraint[0]) { - default: - break; - case 'f': - case 'r': - return C_RegisterClass; + default: break; + case 'r': return C_RegisterClass; case 'I': // SIMM13 return C_Other; } @@ -3407,9 +3457,6 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { - case 'f': - return std::make_pair(0U, &SP::FPRegsRegClass); - case 'r': if (VT == MVT::v2i32) return std::make_pair(0U, &SP::IntPairRegClass); |