SDValue BlackfinTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); SmallVector<CCValAssign, 16> ArgLocs; CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), getTargetMachine(), ArgLocs, *DAG.getContext()); CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space CCInfo.AnalyzeFormalArguments(Ins, CC_Blackfin); for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; if (VA.isRegLoc()) { EVT RegVT = VA.getLocVT(); TargetRegisterClass *RC = VA.getLocReg() == BF::P0 ? BF::PRegisterClass : BF::DRegisterClass; assert(RC->contains(VA.getLocReg()) && "Unexpected regclass in CCState"); assert(RC->hasType(RegVT) && "Unexpected regclass in CCState"); unsigned Reg = MF.getRegInfo().createVirtualRegister(RC); MF.getRegInfo().addLiveIn(VA.getLocReg(), Reg); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it is really passed promoted to 32 // bits. Insert an assert[sz]ext to capture this, then truncate to the // right size. if (VA.getLocInfo() == CCValAssign::SExt) ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, DAG.getValueType(VA.getValVT())); else if (VA.getLocInfo() == CCValAssign::ZExt) ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, DAG.getValueType(VA.getValVT())); if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); InVals.push_back(ArgValue); } else { assert(VA.isMemLoc() && "CCValAssign must be RegLoc or MemLoc"); unsigned ObjSize = VA.getLocVT().getStoreSize(); int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, MachinePointerInfo(), false, false, 0)); } } return Chain; }
static bool inClass(const TargetRegisterClass &Test, unsigned Reg, const TargetRegisterClass *RC) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) return Test.contains(Reg); else return Test.hasSubClassEq(RC); }
static bool inClass(const TargetRegisterClass &Test, unsigned Reg, const TargetRegisterClass *RC, const llvm::TargetRegisterInfo *RI) { if (RI->isPhysicalRegister(Reg)) return Test.contains(Reg); else return &Test==RC || Test.hasSubClass(RC); }
/// Implements the 'w' and 'x' inline asm operand modifiers, which print a GPR /// with the obvious type and an immediate 0 as either wzr or xzr. static bool printModifiedGPRAsmOperand(const MachineOperand &MO, const TargetRegisterInfo *TRI, const TargetRegisterClass &RegClass, raw_ostream &O) { char Prefix = &RegClass == &AArch64::GPR32RegClass ? 'w' : 'x'; if (MO.isImm() && MO.getImm() == 0) { O << Prefix << "zr"; return false; } else if (MO.isReg()) { if (MO.getReg() == AArch64::XSP || MO.getReg() == AArch64::WSP) { O << (Prefix == 'x' ? "sp" : "wsp"); return false; } for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) { if (RegClass.contains(*AR)) { O << AArch64InstPrinter::getRegisterName(*AR); return false; } } } return true; }
unsigned RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj) { const MachineBasicBlock &MBB = *To->getParent(); const MachineFunction &MF = *MBB.getParent(); // Find the register whose use is furthest away. MachineBasicBlock::iterator UseMI; ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF); std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(*MRI, MBBI, To, LiveUnits, AllocationOrder); MCPhysReg Reg = P.first; MachineBasicBlock::iterator SpillBefore = P.second; assert(Reg != 0 && "No register left to scavenge!"); // Found an available register? if (SpillBefore != MBB.end()) { MachineBasicBlock::iterator ReloadAfter = RestoreAfter ? std::next(MBBI) : MBBI; MachineBasicBlock::iterator ReloadBefore = std::next(ReloadAfter); DEBUG(dbgs() << "Reload before: " << *ReloadBefore << '\n'); ScavengedInfo &Scavenged = spill(Reg, RC, SPAdj, SpillBefore, ReloadBefore); Scavenged.Restore = &*std::prev(SpillBefore); LiveUnits.removeReg(Reg); DEBUG(dbgs() << "Scavenged register with spill: " << PrintReg(Reg, TRI) << " until " << *SpillBefore); } else { DEBUG(dbgs() << "Scavenged free register: " << PrintReg(Reg, TRI) << '\n'); } return Reg; }
unsigned HexagonRegisterInfo::getHexagonSubRegIndex( const TargetRegisterClass &RC, unsigned GenIdx) const { assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi); static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi }; static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi }; switch (RC.getID()) { case Hexagon::CtrRegs64RegClassID: case Hexagon::DoubleRegsRegClassID: return ISub[GenIdx]; case Hexagon::HvxWRRegClassID: return VSub[GenIdx]; } if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses()) return getHexagonSubRegIndex(*SuperRC, GenIdx); llvm_unreachable("Invalid register class"); }
/// Try to print a floating-point register as if it belonged to a specified /// register-class. For example the inline asm operand modifier "b" requires its /// argument to be printed as "bN". static bool printModifiedFPRAsmOperand(const MachineOperand &MO, const TargetRegisterInfo *TRI, const TargetRegisterClass &RegClass, raw_ostream &O) { if (!MO.isReg()) return true; for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) { if (RegClass.contains(*AR)) { O << AArch64InstPrinter::getRegisterName(*AR); return false; } } return true; }
bool RegisterBank::covers(const TargetRegisterClass &RC) const { assert(isValid() && "RB hasn't been initialized yet"); return ContainedRegClasses.test(RC.getID()); }