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;
}
Пример #2
0
static bool inClass(const TargetRegisterClass &Test,
                    unsigned Reg,
                    const TargetRegisterClass *RC) {
  if (TargetRegisterInfo::isPhysicalRegister(Reg))
    return Test.contains(Reg);
  else
    return Test.hasSubClassEq(RC);
}
Пример #3
0
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);
}
Пример #4
0
/// 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;
}
Пример #5
0
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;
}
Пример #6
0
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");
}
Пример #7
0
/// 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;
}
Пример #8
0
bool RegisterBank::covers(const TargetRegisterClass &RC) const {
  assert(isValid() && "RB hasn't been initialized yet");
  return ContainedRegClasses.test(RC.getID());
}