本文整理汇总了C++中MipsFunctionInfo类的典型用法代码示例。如果您正苦于以下问题:C++ MipsFunctionInfo类的具体用法?C++ MipsFunctionInfo怎么用?C++ MipsFunctionInfo使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了MipsFunctionInfo类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: eliminateFI
void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
unsigned OpNo, int FrameIndex,
uint64_t StackSize,
int64_t SPOffset) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
int MinCSFI = 0;
int MaxCSFI = -1;
if (CSI.size()) {
MinCSFI = CSI[0].getFrameIdx();
MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
}
bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);
// The following stack frame objects are always referenced relative to $sp:
// 1. Outgoing arguments.
// 2. Pointer to dynamically allocated stack space.
// 3. Locations for callee-saved registers.
// 4. Locations for eh data registers.
// Everything else is referenced relative to whatever register
// getFrameRegister() returns.
unsigned FrameReg;
if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI)
FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
else
FrameReg = getFrameRegister(MF);
// Calculate final offset.
// - There is no need to change the offset if the frame object is one of the
// following: an outgoing argument, pointer to a dynamically allocated
// stack space or a $gp restore location,
// - If the frame object is any of the following, its offset must be adjusted
// by adding the size of the stack:
// incoming argument, callee-saved register location or local variable.
bool IsKill = false;
int64_t Offset;
Offset = SPOffset + (int64_t)StackSize;
Offset += MI.getOperand(OpNo + 1).getImm();
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
if (!MI.isDebugValue()) {
// Make sure Offset fits within the field available.
// For MSA instructions, this is a 10-bit signed immediate (scaled by
// element size), otherwise it is a 16-bit signed immediate.
unsigned OffsetBitSize = getLoadStoreOffsetSizeInBits(MI.getOpcode());
unsigned OffsetAlign = getLoadStoreOffsetAlign(MI.getOpcode());
if (OffsetBitSize < 16 && isInt<16>(Offset) &&
(!isIntN(OffsetBitSize, Offset) ||
OffsetToAlignment(Offset, OffsetAlign) != 0)) {
// If we have an offset that needs to fit into a signed n-bit immediate
// (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
unsigned ADDiu = Subtarget.isABI_N64() ? Mips::DADDiu : Mips::ADDiu;
const TargetRegisterClass *RC =
Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
unsigned Reg = RegInfo.createVirtualRegister(RC);
const MipsSEInstrInfo &TII =
*static_cast<const MipsSEInstrInfo *>(
MBB.getParent()->getTarget().getInstrInfo());
BuildMI(MBB, II, DL, TII.get(ADDiu), Reg).addReg(FrameReg).addImm(Offset);
FrameReg = Reg;
Offset = 0;
IsKill = true;
} else if (!isInt<16>(Offset)) {
// Otherwise split the offset into 16-bit pieces and add it in multiple
// instructions.
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
unsigned NewImm = 0;
const MipsSEInstrInfo &TII =
*static_cast<const MipsSEInstrInfo *>(
MBB.getParent()->getTarget().getInstrInfo());
unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL,
OffsetBitSize == 16 ? &NewImm : nullptr);
BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg)
.addReg(Reg, RegState::Kill);
FrameReg = Reg;
Offset = SignExtend64<16>(NewImm);
IsKill = true;
}
}
MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
}
示例2: eliminateFrameIndex
// FrameIndex represent objects inside a abstract stack.
// We must replace FrameIndex with an stack/frame pointer
// direct reference.
void MipsRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
RegScavenger *RS) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
unsigned i = 0;
while (!MI.getOperand(i).isFI()) {
++i;
assert(i < MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
}
DEBUG(errs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
errs() << "<--------->\n" << MI);
int FrameIndex = MI.getOperand(i).getIndex();
uint64_t stackSize = MF.getFrameInfo()->getStackSize();
int64_t spOffset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"
<< "spOffset : " << spOffset << "\n"
<< "stackSize : " << stackSize << "\n");
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
int MinCSFI = 0;
int MaxCSFI = -1;
if (CSI.size()) {
MinCSFI = CSI[0].getFrameIdx();
MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
}
// The following stack frame objects are always referenced relative to $sp:
// 1. Outgoing arguments.
// 2. Pointer to dynamically allocated stack space.
// 3. Locations for callee-saved registers.
// Everything else is referenced relative to whatever register
// getFrameRegister() returns.
unsigned FrameReg;
if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isDynAllocFI(FrameIndex) ||
(FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))
FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
else
FrameReg = getFrameRegister(MF);
// Calculate final offset.
// - There is no need to change the offset if the frame object is one of the
// following: an outgoing argument, pointer to a dynamically allocated
// stack space or a $gp restore location,
// - If the frame object is any of the following, its offset must be adjusted
// by adding the size of the stack:
// incoming argument, callee-saved register location or local variable.
int64_t Offset;
if (MipsFI->isOutArgFI(FrameIndex) || MipsFI->isGPFI(FrameIndex) ||
MipsFI->isDynAllocFI(FrameIndex))
Offset = spOffset;
else
Offset = spOffset + (int64_t)stackSize;
Offset += MI.getOperand(i+1).getImm();
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
// If MI is not a debug value, make sure Offset fits in the 16-bit immediate
// field.
if (!MI.isDebugValue() && !isInt<16>(Offset)) {
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
MipsAnalyzeImmediate AnalyzeImm;
unsigned Size = Subtarget.isABI_N64() ? 64 : 32;
unsigned LUi = Subtarget.isABI_N64() ? Mips::LUi64 : Mips::LUi;
unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
unsigned ZEROReg = Subtarget.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
unsigned ATReg = Subtarget.isABI_N64() ? Mips::AT_64 : Mips::AT;
const MipsAnalyzeImmediate::InstSeq &Seq =
AnalyzeImm.Analyze(Offset, Size, true /* LastInstrIsADDiu */);
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
// FIXME: change this when mips goes MC".
BuildMI(MBB, II, DL, TII.get(Mips::NOAT));
// The first instruction can be a LUi, which is different from other
// instructions (ADDiu, ORI and SLL) in that it does not have a register
// operand.
if (Inst->Opc == LUi)
BuildMI(MBB, II, DL, TII.get(LUi), ATReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
else
BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
// Build the remaining instructions in Seq except for the last one.
//.........这里部分代码省略.........
示例3: emitPrologue
void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const MipsRegisterInfo *RegInfo =
static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
const MipsInstrInfo &TII =
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
unsigned NewReg = 0;
int NewImm = 0;
bool ATUsed;
// First, compute final stack size.
unsigned RegSize = STI.isGP32bit() ? 4 : 8;
unsigned StackAlign = getStackAlignment();
unsigned LocalVarAreaOffset = MipsFI->needGPSaveRestore() ?
(MFI->getObjectOffset(MipsFI->getGPFI()) + RegSize) :
MipsFI->getMaxCallFrameSize();
unsigned StackSize = AlignOffset(LocalVarAreaOffset, StackAlign) +
AlignOffset(MFI->getStackSize(), StackAlign);
// Update stack size
MFI->setStackSize(StackSize);
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
// TODO: check need from GP here.
if (isPIC && STI.isABI_O32())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPLOAD))
.addReg(RegInfo->getPICCallReg());
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO));
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
// Adjust stack : addi sp, sp, (-imm)
ATUsed = expandRegLargeImmPair(Mips::SP, -StackSize, NewReg, NewImm, MBB,
MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP)
.addReg(NewReg).addImm(NewImm);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
// Find the instruction past the last instruction that saves a callee-saved
// register to the stack.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned i = 0; i < CSI.size(); ++i)
++MBBI;
// if framepointer enabled, set it to point to the stack pointer.
if (hasFP(MF))
// Insert instruction "move $fp, $sp" at this location.
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
.addReg(Mips::SP).addReg(Mips::ZERO);
// Restore GP from the saved stack location
if (MipsFI->needGPSaveRestore())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE))
.addImm(MFI->getObjectOffset(MipsFI->getGPFI()));
// EH Frame infomation.
MachineModuleInfo &MMI = MF.getMMI();
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(FrameLabel);
if (hasFP(MF)) {
MachineLocation SPDst(Mips::FP);
MachineLocation SPSrc(Mips::SP);
Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
}
if (StackSize) {
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, -StackSize);
Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
}
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
E = CSI.end(); I != E; ++I) {
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(I->getReg());
Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
}
}
示例4: emitPrologue
void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const MipsSEInstrInfo &TII =
*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
const MipsRegisterInfo &RegInfo =
*static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
// First, compute final stack size.
uint64_t StackSize = MFI->getStackSize();
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
MachineModuleInfo &MMI = MF.getMMI();
const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
MachineLocation DstML, SrcML;
// Adjust stack.
TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
// emit ".cfi_def_cfa_offset StackSize"
MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
MMI.addFrameInst(
MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize));
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
if (CSI.size()) {
// Find the instruction past the last instruction that saves a callee-saved
// register to the stack.
for (unsigned i = 0; i < CSI.size(); ++i)
++MBBI;
// Iterate over list of callee-saved registers and emit .cfi_offset
// directives.
MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
E = CSI.end(); I != E; ++I) {
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
unsigned Reg = I->getReg();
// If Reg is a double precision register, emit two cfa_offsets,
// one for each of the paired single precision registers.
if (Mips::AFGR64RegClass.contains(Reg)) {
unsigned Reg0 =
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true);
unsigned Reg1 =
MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true);
if (!STI.isLittle())
std::swap(Reg0, Reg1);
MMI.addFrameInst(
MCCFIInstruction::createOffset(CSLabel, Reg0, Offset));
MMI.addFrameInst(
MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4));
} else {
// Reg is either in GPR32 or FGR32.
MMI.addFrameInst(MCCFIInstruction::createOffset(
CSLabel, MRI->getDwarfRegNum(Reg, 1), Offset));
}
}
}
if (MipsFI->callsEhReturn()) {
const TargetRegisterClass *RC = STI.isABI_N64() ?
&Mips::GPR64RegClass : &Mips::GPR32RegClass;
// Insert instructions that spill eh data registers.
for (int I = 0; I < 4; ++I) {
if (!MBB.isLiveIn(ehDataReg(I)))
MBB.addLiveIn(ehDataReg(I));
TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
MipsFI->getEhDataRegFI(I), RC, &RegInfo);
}
// Emit .cfi_offset directives for eh data registers.
MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
for (int I = 0; I < 4; ++I) {
int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true);
MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset));
}
//.........这里部分代码省略.........
开发者ID:IllusionRom-deprecated,项目名称:android_platform_external_llvm,代码行数:101,代码来源:MipsSEFrameLowering.cpp
示例5: adjustMipsStackFrame
void MipsFrameInfo::adjustMipsStackFrame(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
unsigned RegSize = STI.isGP32bit() ? 4 : 8;
bool HasGP = MipsFI->needGPSaveRestore();
// Min and Max CSI FrameIndex.
int MinCSFI = -1, MaxCSFI = -1;
// See the description at MipsMachineFunction.h
int TopCPUSavedRegOff = -1, TopFPUSavedRegOff = -1;
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
// LowerFormalArguments. Leaving '0' for while is necessary to avoid the
// approach done by calculateFrameObjectOffsets to the stack frame.
MipsFI->adjustLoadArgsFI(MFI);
MipsFI->adjustStoreVarArgsFI(MFI);
// It happens that the default stack frame allocation order does not directly
// map to the convention used for mips. So we must fix it. We move the callee
// save register slots after the local variables area, as described in the
// stack frame above.
unsigned CalleeSavedAreaSize = 0;
if (!CSI.empty()) {
MinCSFI = CSI[0].getFrameIdx();
MaxCSFI = CSI[CSI.size()-1].getFrameIdx();
}
for (unsigned i = 0, e = CSI.size(); i != e; ++i)
CalleeSavedAreaSize += MFI->getObjectAlignment(CSI[i].getFrameIdx());
unsigned StackOffset = HasGP ? (MipsFI->getGPStackOffset()+RegSize)
: (STI.isABI_O32() ? 16 : 0);
// Adjust local variables. They should come on the stack right
// after the arguments.
int LastOffsetFI = -1;
for (int i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
if (i >= MinCSFI && i <= MaxCSFI)
continue;
if (MFI->isDeadObjectIndex(i))
continue;
unsigned Offset =
StackOffset + MFI->getObjectOffset(i) - CalleeSavedAreaSize;
if (LastOffsetFI == -1)
LastOffsetFI = i;
if (Offset > MFI->getObjectOffset(LastOffsetFI))
LastOffsetFI = i;
MFI->setObjectOffset(i, Offset);
}
// Adjust CPU Callee Saved Registers Area. Registers RA and FP must
// be saved in this CPU Area. This whole area must be aligned to the
// default Stack Alignment requirements.
if (LastOffsetFI >= 0)
StackOffset = MFI->getObjectOffset(LastOffsetFI)+
MFI->getObjectSize(LastOffsetFI);
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
for (unsigned i = 0, e = CSI.size(); i != e ; ++i) {
unsigned Reg = CSI[i].getReg();
if (!Mips::CPURegsRegisterClass->contains(Reg))
break;
MFI->setObjectOffset(CSI[i].getFrameIdx(), StackOffset);
TopCPUSavedRegOff = StackOffset;
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
}
// Stack locations for FP and RA. If only one of them is used,
// the space must be allocated for both, otherwise no space at all.
if (hasFP(MF) || MFI->adjustsStack()) {
// FP stack location
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setFPStackOffset(StackOffset);
TopCPUSavedRegOff = StackOffset;
StackOffset += RegSize;
// SP stack location
MFI->setObjectOffset(MFI->CreateStackObject(RegSize, RegSize, true),
StackOffset);
MipsFI->setRAStackOffset(StackOffset);
StackOffset += RegSize;
if (MFI->adjustsStack())
TopCPUSavedRegOff += RegSize;
}
StackOffset = ((StackOffset+StackAlign-1)/StackAlign*StackAlign);
// Adjust FPU Callee Saved Registers Area. This Area must be
// aligned to the default Stack Alignment requirements.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (Mips::CPURegsRegisterClass->contains(Reg))
continue;
MFI->setObjectOffset(CSI[i].getFrameIdx(), StackOffset);
TopFPUSavedRegOff = StackOffset;
StackOffset += MFI->getObjectAlignment(CSI[i].getFrameIdx());
//.........这里部分代码省略.........
示例6: emitPrologue
void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const MipsRegisterInfo *RegInfo =
static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
const MipsInstrInfo &TII =
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
unsigned NewReg = 0;
int NewImm = 0;
bool ATUsed;
// Get the right frame order for Mips.
adjustMipsStackFrame(MF);
// Get the number of bytes to allocate from the FrameInfo.
unsigned StackSize = MFI->getStackSize();
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
int FPOffset = MipsFI->getFPStackOffset();
int RAOffset = MipsFI->getRAStackOffset();
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
// TODO: check need from GP here.
if (isPIC && STI.isABI_O32())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPLOAD))
.addReg(RegInfo->getPICCallReg());
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO));
// Adjust stack : addi sp, sp, (-imm)
ATUsed = expandRegLargeImmPair(Mips::SP, -StackSize, NewReg, NewImm, MBB,
MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP)
.addReg(NewReg).addImm(NewImm);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
// Save the return address only if the function isnt a leaf one.
// sw $ra, stack_loc($sp)
if (MFI->adjustsStack()) {
expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB, MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
.addReg(Mips::RA).addImm(NewImm).addReg(NewReg);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
}
// if framepointer enabled, save it and set it
// to point to the stack pointer
if (hasFP(MF)) {
// sw $fp,stack_loc($sp)
expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB, MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::SW))
.addReg(Mips::FP).addImm(NewImm).addReg(NewReg);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
// move $fp, $sp
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::FP)
.addReg(Mips::SP).addReg(Mips::ZERO);
}
// Restore GP from the saved stack location
if (MipsFI->needGPSaveRestore())
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE))
.addImm(MipsFI->getGPStackOffset());
}
示例7: emitInterruptPrologueStub
void MipsSEFrameLowering::emitInterruptPrologueStub(
MachineFunction &MF, MachineBasicBlock &MBB) const {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Report an error the target doesn't support Mips32r2 or later.
// The epilogue relies on the use of the "ehb" to clear execution
// hazards. Pre R2 Mips relies on an implementation defined number
// of "ssnop"s to clear the execution hazard. Support for ssnop hazard
// clearing is not provided so reject that configuration.
if (!STI.hasMips32r2())
report_fatal_error(
"\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
"MIPS16 targets.");
// The GP register contains the "user" value, so we cannot perform
// any gp relative loads until we restore the "kernel" or "system" gp
// value. Until support is written we shall only accept the static
// relocation model.
if ((STI.getRelocationModel() != Reloc::Static))
report_fatal_error("\"interrupt\" attribute is only supported for the "
"static relocation model on MIPS at the present time.");
if (!STI.isABI_O32() || STI.hasMips64())
report_fatal_error("\"interrupt\" attribute is only supported for the "
"O32 ABI on MIPS32R2+ at the present time.");
// Perform ISR handling like GCC
StringRef IntKind =
MF.getFunction()->getFnAttribute("interrupt").getValueAsString();
const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
// EIC interrupt handling needs to read the Cause register to disable
// interrupts.
if (IntKind == "eic") {
// Coprocessor registers are always live per se.
MBB.addLiveIn(Mips::COP013);
BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K0)
.addReg(Mips::COP013)
.addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)
.addReg(Mips::K0)
.addImm(10)
.addImm(6)
.setMIFlag(MachineInstr::FrameSetup);
}
// Fetch and spill EPC
MBB.addLiveIn(Mips::COP014);
BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
.addReg(Mips::COP014)
.addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
MipsFI->getISRRegFI(0), PtrRC,
STI.getRegisterInfo(), 0);
// Fetch and Spill Status
MBB.addLiveIn(Mips::COP012);
BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
.addReg(Mips::COP012)
.addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
MipsFI->getISRRegFI(1), PtrRC,
STI.getRegisterInfo(), 0);
// Build the configuration for disabling lower priority interrupts. Non EIC
// interrupts need to be masked off with zero, EIC from the Cause register.
unsigned InsPosition = 8;
unsigned InsSize = 0;
unsigned SrcReg = Mips::ZERO;
// If the interrupt we're tied to is the EIC, switch the source for the
// masking off interrupts to the cause register.
if (IntKind == "eic") {
SrcReg = Mips::K0;
InsPosition = 10;
InsSize = 6;
} else
InsSize = StringSwitch<unsigned>(IntKind)
.Case("sw0", 1)
.Case("sw1", 2)
.Case("hw0", 3)
.Case("hw1", 4)
.Case("hw2", 5)
.Case("hw3", 6)
.Case("hw4", 7)
.Case("hw5", 8)
.Default(0);
assert(InsSize != 0 && "Unknown interrupt type!");
BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
.addReg(SrcReg)
//.........这里部分代码省略.........
示例8: InitGlobalBaseReg
// Insert instructions to initialize the global base register in the
// first MBB of the function. When the ABI is O32 and the relocation model is
// PIC, the necessary instructions are emitted later to prevent optimization
// passes from moving them.
void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
if (!MipsFI->globalBaseRegSet())
return;
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator I = MBB.begin();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();
const TargetRegisterClass *RC;
if (Subtarget.isABI_N64())
RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass;
else if (Subtarget.inMips16Mode())
RC = (const TargetRegisterClass*)&Mips::CPU16RegsRegClass;
else
RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass;
V0 = RegInfo.createVirtualRegister(RC);
V1 = RegInfo.createVirtualRegister(RC);
V2 = RegInfo.createVirtualRegister(RC);
if (Subtarget.isABI_N64()) {
MF.getRegInfo().addLiveIn(Mips::T9_64);
MBB.addLiveIn(Mips::T9_64);
// lui $v0, %hi(%neg(%gp_rel(fname)))
// daddu $v1, $v0, $t9
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
.addReg(Mips::T9_64);
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
return;
}
if (Subtarget.inMips16Mode()) {
BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0)
.addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1)
.addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
.addReg(V1).addReg(V2);
return;
}
if (MF.getTarget().getRelocationModel() == Reloc::Static) {
// Set global register to __gnu_local_gp.
//
// lui $v0, %hi(__gnu_local_gp)
// addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
return;
}
MF.getRegInfo().addLiveIn(Mips::T9);
MBB.addLiveIn(Mips::T9);
if (Subtarget.isABI_N32()) {
// lui $v0, %hi(%neg(%gp_rel(fname)))
// addu $v1, $v0, $t9
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
return;
}
assert(Subtarget.isABI_O32());
// For O32 ABI, the following instruction sequence is emitted to initialize
// the global base register:
//
// 0. lui $2, %hi(_gp_disp)
// 1. addiu $2, $2, %lo(_gp_disp)
// 2. addu $globalbasereg, $2, $t9
//
// We emit only the last instruction here.
//
// GNU linker requires that the first two instructions appear at the beginning
// of a function and no instructions be inserted before or between them.
// The two instructions are emitted during lowering to MC layer in order to
// avoid any reordering.
//.........这里部分代码省略.........
示例9: getOpndList
void Mips16TargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
SDValue Chain) const {
SelectionDAG &DAG = CLI.DAG;
MachineFunction &MF = DAG.getMachineFunction();
MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
const char* Mips16HelperFunction = nullptr;
bool NeedMips16Helper = false;
if (Subtarget.inMips16HardFloat()) {
//
// currently we don't have symbols tagged with the mips16 or mips32
// qualifier so we will assume that we don't know what kind it is.
// and generate the helper
//
bool LookupHelper = true;
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
if (std::binary_search(std::begin(HardFloatLibCalls),
std::end(HardFloatLibCalls), Find))
LookupHelper = false;
else {
const char *Symbol = S->getSymbol();
Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
const Mips16HardFloatInfo::FuncSignature *Signature =
Mips16HardFloatInfo::findFuncSignature(Symbol);
if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
FuncInfo->StubsNeeded.end()))) {
FuncInfo->StubsNeeded[Symbol] = Signature;
//
// S2 is normally saved if the stub is for a function which
// returns a float or double value and is not otherwise. This is
// because more work is required after the function the stub
// is calling completes, and so the stub cannot directly return
// and the stub has no stack space to store the return address so
// S2 is used for that purpose.
// In order to take advantage of not saving S2, we need to also
// optimize the call in the stub and this requires some further
// functionality in MipsAsmPrinter which we don't have yet.
// So for now we always save S2. The optimization will be done
// in a follow-on patch.
//
if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
FuncInfo->setSaveS2();
}
// one more look at list of intrinsics
const Mips16IntrinsicHelperType *Helper =
std::lower_bound(std::begin(Mips16IntrinsicHelper),
std::end(Mips16IntrinsicHelper), IntrinsicFind);
if (Helper != std::end(Mips16IntrinsicHelper) &&
*Helper == IntrinsicFind) {
Mips16HelperFunction = Helper->Helper;
NeedMips16Helper = true;
LookupHelper = false;
}
}
} else if (GlobalAddressSDNode *G =
dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
G->getGlobal()->getName().data() };
if (std::binary_search(std::begin(HardFloatLibCalls),
std::end(HardFloatLibCalls), Find))
LookupHelper = false;
}
if (LookupHelper)
Mips16HelperFunction =
getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
}
SDValue JumpTarget = Callee;
// T9 should contain the address of the callee function if
// -relocation-model=pic or it is an indirect call.
if (IsPICCall || !GlobalOrExternal) {
unsigned V0Reg = Mips::V0;
if (NeedMips16Helper) {
RegsToPass.push_front(std::make_pair(V0Reg, Callee));
JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy());
ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
MipsII::MO_GOT, Chain,
FuncInfo->callPtrInfo(S->getSymbol()));
} else
RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
}
Ops.push_back(JumpTarget);
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
InternalLinkage, IsCallReloc, CLI, Callee,
Chain);
}
示例10: DebugLoc
void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const MipsRegisterInfo *RegInfo =
static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
const MipsInstrInfo &TII =
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu;
// First, compute final stack size.
unsigned StackAlign = getStackAlignment();
uint64_t StackSize = RoundUpToAlignment(MFI->getStackSize(), StackAlign);
if (MipsFI->globalBaseRegSet())
StackSize += MFI->getObjectOffset(MipsFI->getGlobalRegFI()) + StackAlign;
else
StackSize += RoundUpToAlignment(MipsFI->getMaxCallFrameSize(), StackAlign);
// Update stack size
MFI->setStackSize(StackSize);
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
MachineModuleInfo &MMI = MF.getMMI();
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
MachineLocation DstML, SrcML;
// Adjust stack.
if (isInt<16>(-StackSize)) // addi sp, sp, (-stacksize)
BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize);
else { // Expand immediate that doesn't fit in 16-bit.
unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT;
MF.getInfo<MipsFunctionInfo>()->setEmitNOAT();
Mips::loadImmediate(-StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl, false,
0);
BuildMI(MBB, MBBI, dl, TII.get(ADDu), SP).addReg(SP).addReg(ATReg);
}
// emit ".cfi_def_cfa_offset StackSize"
MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
DstML = MachineLocation(MachineLocation::VirtualFP);
SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
if (CSI.size()) {
// Find the instruction past the last instruction that saves a callee-saved
// register to the stack.
for (unsigned i = 0; i < CSI.size(); ++i)
++MBBI;
// Iterate over list of callee-saved registers and emit .cfi_offset
// directives.
MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
E = CSI.end(); I != E; ++I) {
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
unsigned Reg = I->getReg();
// If Reg is a double precision register, emit two cfa_offsets,
// one for each of the paired single precision registers.
if (Mips::AFGR64RegClass.contains(Reg)) {
MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
if (!STI.isLittle())
std::swap(SrcML0, SrcML1);
Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
} else {
// Reg is either in CPURegs or FGR32.
DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
SrcML = MachineLocation(Reg);
Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
}
}
}
// if framepointer enabled, set it to point to the stack pointer.
if (hasFP(MF)) {
// Insert instruction "move $fp, $sp" at this location.
BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
//.........这里部分代码省略.........
示例11: InitGlobalBaseReg
// Insert instructions to initialize the global base register in the
// first MBB of the function. When the ABI is O32 and the relocation model is
// PIC, the necessary instructions are emitted later to prevent optimization
// passes from moving them.
void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
if (!MipsFI->globalBaseRegSet())
return;
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator I = MBB.begin();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
bool FixGlobalBaseReg = MipsFI->globalBaseRegFixed();
if (Subtarget.isABI_O32() && FixGlobalBaseReg)
// $gp is the global base register.
V0 = V1 = GlobalBaseReg;
else {
const TargetRegisterClass *RC;
RC = Subtarget.isABI_N64() ?
Mips::CPU64RegsRegisterClass : Mips::CPURegsRegisterClass;
V0 = RegInfo.createVirtualRegister(RC);
V1 = RegInfo.createVirtualRegister(RC);
}
if (Subtarget.isABI_N64()) {
MF.getRegInfo().addLiveIn(Mips::T9_64);
MBB.addLiveIn(Mips::T9_64);
// lui $v0, %hi(%neg(%gp_rel(fname)))
// daddu $v1, $v0, $t9
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0).addReg(Mips::T9_64);
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
} else if (MF.getTarget().getRelocationModel() == Reloc::Static) {
// Set global register to __gnu_local_gp.
//
// lui $v0, %hi(__gnu_local_gp)
// addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
} else {
MF.getRegInfo().addLiveIn(Mips::T9);
MBB.addLiveIn(Mips::T9);
if (Subtarget.isABI_N32()) {
// lui $v0, %hi(%neg(%gp_rel(fname)))
// addu $v1, $v0, $t9
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
} else if (!MipsFI->globalBaseRegFixed()) {
assert(Subtarget.isABI_O32());
BuildMI(MBB, I, DL, TII.get(Mips::SETGP2), GlobalBaseReg)
.addReg(Mips::T9);
}
}
}
示例12: eliminateFI
void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
unsigned OpNo, int FrameIndex,
uint64_t StackSize,
int64_t SPOffset) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
int MinCSFI = 0;
int MaxCSFI = -1;
if (CSI.size()) {
MinCSFI = CSI[0].getFrameIdx();
MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
}
bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex);
// The following stack frame objects are always referenced relative to $sp:
// 1. Outgoing arguments.
// 2. Pointer to dynamically allocated stack space.
// 3. Locations for callee-saved registers.
// 4. Locations for eh data registers.
// Everything else is referenced relative to whatever register
// getFrameRegister() returns.
unsigned FrameReg;
if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI)
FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
else
FrameReg = getFrameRegister(MF);
// Calculate final offset.
// - There is no need to change the offset if the frame object is one of the
// following: an outgoing argument, pointer to a dynamically allocated
// stack space or a $gp restore location,
// - If the frame object is any of the following, its offset must be adjusted
// by adding the size of the stack:
// incoming argument, callee-saved register location or local variable.
bool IsKill = false;
int64_t Offset;
Offset = SPOffset + (int64_t)StackSize;
Offset += MI.getOperand(OpNo + 1).getImm();
DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n");
// If MI is not a debug value, make sure Offset fits in the 16-bit immediate
// field.
if (!MI.isDebugValue() && !isInt<16>(Offset)) {
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
unsigned NewImm;
unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL, &NewImm);
BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg)
.addReg(Reg, RegState::Kill);
FrameReg = Reg;
Offset = SignExtend64<16>(NewImm);
IsKill = true;
}
MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
}
示例13: getOpndList
void Mips16TargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
SelectionDAG &DAG = CLI.DAG;
MachineFunction &MF = DAG.getMachineFunction();
MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
const char* Mips16HelperFunction = 0;
bool NeedMips16Helper = false;
if (Subtarget->inMips16HardFloat()) {
//
// currently we don't have symbols tagged with the mips16 or mips32
// qualifier so we will assume that we don't know what kind it is.
// and generate the helper
//
bool LookupHelper = true;
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
Find))
LookupHelper = false;
else {
Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
// one more look at list of intrinsics
if (std::binary_search(Mips16IntrinsicHelper,
array_endof(Mips16IntrinsicHelper),
IntrinsicFind)) {
const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper,
array_endof(Mips16IntrinsicHelper),
IntrinsicFind));
Mips16HelperFunction = h->Helper;
NeedMips16Helper = true;
LookupHelper = false;
}
}
} else if (GlobalAddressSDNode *G =
dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
G->getGlobal()->getName().data() };
if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
Find))
LookupHelper = false;
}
if (LookupHelper) Mips16HelperFunction =
getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper);
}
SDValue JumpTarget = Callee;
// T9 should contain the address of the callee function if
// -reloction-model=pic or it is an indirect call.
if (IsPICCall || !GlobalOrExternal) {
unsigned V0Reg = Mips::V0;
if (NeedMips16Helper) {
RegsToPass.push_front(std::make_pair(V0Reg, Callee));
JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy());
ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG,
MipsII::MO_GOT, Chain,
FuncInfo->callPtrInfo(S->getSymbol()));
} else
RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
}
Ops.push_back(JumpTarget);
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
InternalLinkage, CLI, Callee, Chain);
}
示例14: emitEpilogue
void MipsFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
const MipsInstrInfo &TII =
*static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo());
DebugLoc dl = MBBI->getDebugLoc();
// Get the number of bytes from FrameInfo
int NumBytes = (int) MFI->getStackSize();
// Get the FI's where RA and FP are saved.
int FPOffset = MipsFI->getFPStackOffset();
int RAOffset = MipsFI->getRAStackOffset();
unsigned NewReg = 0;
int NewImm = 0;
bool ATUsed = false;
// if framepointer enabled, restore it and restore the
// stack pointer
if (hasFP(MF)) {
// move $sp, $fp
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDu), Mips::SP)
.addReg(Mips::FP).addReg(Mips::ZERO);
// lw $fp,stack_loc($sp)
ATUsed = expandRegLargeImmPair(Mips::SP, FPOffset, NewReg, NewImm, MBB,
MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::FP)
.addImm(NewImm).addReg(NewReg);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
}
// Restore the return address only if the function isnt a leaf one.
// lw $ra, stack_loc($sp)
if (MFI->adjustsStack()) {
expandRegLargeImmPair(Mips::SP, RAOffset, NewReg, NewImm, MBB, MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::LW), Mips::RA)
.addImm(NewImm).addReg(NewReg);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
}
// adjust stack : insert addi sp, sp, (imm)
if (NumBytes) {
expandRegLargeImmPair(Mips::SP, NumBytes, NewReg, NewImm, MBB, MBBI);
BuildMI(MBB, MBBI, dl, TII.get(Mips::ADDiu), Mips::SP)
.addReg(NewReg).addImm(NewImm);
// FIXME: change this when mips goes MC".
if (ATUsed)
BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO));
}
}
示例15: initGlobalBaseReg
void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
if (!MipsFI->globalBaseRegSet())
return;
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator I = MBB.begin();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
DebugLoc DL;
unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
const TargetRegisterClass *RC;
const MipsABIInfo &ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
V0 = RegInfo.createVirtualRegister(RC);
V1 = RegInfo.createVirtualRegister(RC);
if (ABI.IsN64()) {
MF.getRegInfo().addLiveIn(Mips::T9_64);
MBB.addLiveIn(Mips::T9_64);
// lui $v0, %hi(%neg(%gp_rel(fname)))
// daddu $v1, $v0, $t9
// daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
.addReg(Mips::T9_64);
BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
return;
}
if (!MF.getTarget().isPositionIndependent()) {
// Set global register to __gnu_local_gp.
//
// lui $v0, %hi(__gnu_local_gp)
// addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
.addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
return;
}
MF.getRegInfo().addLiveIn(Mips::T9);
MBB.addLiveIn(Mips::T9);
if (ABI.IsN32()) {
// lui $v0, %hi(%neg(%gp_rel(fname)))
// addu $v1, $v0, $t9
// addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
const GlobalValue *FName = MF.getFunction();
BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
.addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
return;
}
assert(ABI.IsO32());
// For O32 ABI, the following instruction sequence is emitted to initialize
// the global base register:
//
// 0. lui $2, %hi(_gp_disp)
// 1. addiu $2, $2, %lo(_gp_disp)
// 2. addu $globalbasereg, $2, $t9
//
// We emit only the last instruction here.
//
// GNU linker requires that the first two instructions appear at the beginning
// of a function and no instructions be inserted before or between them.
// The two instructions are emitted during lowering to MC layer in order to
// avoid any reordering.
//
// Register $2 (Mips::V0) is added to the list of live-in registers to ensure
// the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
// reads it.
MF.getRegInfo().addLiveIn(Mips::V0);
MBB.addLiveIn(Mips::V0);
BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
.addReg(Mips::V0).addReg(Mips::T9);
}