本文整理汇总了C++中machinebasicblock::iterator::setDesc方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::setDesc方法的具体用法?C++ iterator::setDesc怎么用?C++ iterator::setDesc使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类machinebasicblock::iterator
的用法示例。
在下文中一共展示了iterator::setDesc方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: combineRestoreADD
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI,
MachineBasicBlock::iterator AddMI,
const TargetInstrInfo *TII)
{
// Before: add <op0>, <op1>, %i[0-7]
// restore %g0, %g0, %i[0-7]
//
// After : restore <op0>, <op1>, %o[0-7]
unsigned reg = AddMI->getOperand(0).getReg();
if (reg < SP::I0 || reg > SP::I7)
return false;
// Erase RESTORE.
RestoreMI->eraseFromParent();
// Change ADD to RESTORE.
AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr)
? SP::RESTORErr
: SP::RESTOREri));
// Map the destination register.
AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
return true;
}
示例2: splitMove
// MI is a 128-bit load or store. Split it into two 64-bit loads or stores,
// each having the opcode given by NewOpcode.
void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI,
unsigned NewOpcode) const {
MachineBasicBlock *MBB = MI->getParent();
MachineFunction &MF = *MBB->getParent();
// Get two load or store instructions. Use the original instruction for one
// of them (arbitarily the second here) and create a clone for the other.
MachineInstr *EarlierMI = MF.CloneMachineInstr(MI);
MBB->insert(MI, EarlierMI);
// Set up the two 64-bit registers.
MachineOperand &HighRegOp = EarlierMI->getOperand(0);
MachineOperand &LowRegOp = MI->getOperand(0);
HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high));
LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low));
// The address in the first (high) instruction is already correct.
// Adjust the offset in the second (low) instruction.
MachineOperand &HighOffsetOp = EarlierMI->getOperand(2);
MachineOperand &LowOffsetOp = MI->getOperand(2);
LowOffsetOp.setImm(LowOffsetOp.getImm() + 8);
// Set the opcodes.
unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm());
unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm());
assert(HighOpcode && LowOpcode && "Both offsets should be in range");
EarlierMI->setDesc(get(HighOpcode));
MI->setDesc(get(LowOpcode));
}
示例3: insertCallDefsUses
MachineBasicBlock::iterator
Filler::findDelayInstr(MachineBasicBlock &MBB,
MachineBasicBlock::iterator slot)
{
SmallSet<unsigned, 32> RegDefs;
SmallSet<unsigned, 32> RegUses;
bool sawLoad = false;
bool sawStore = false;
if (slot == MBB.begin())
return MBB.end();
if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL)
return MBB.end();
if (slot->getOpcode() == SP::RETL) {
MachineBasicBlock::iterator J = slot;
--J;
if (J->getOpcode() == SP::RESTORErr
|| J->getOpcode() == SP::RESTOREri) {
// change retl to ret.
slot->setDesc(TM.getInstrInfo()->get(SP::RET));
return J;
}
}
// Call's delay filler can def some of call's uses.
if (slot->isCall())
insertCallDefsUses(slot, RegDefs, RegUses);
else
insertDefsUses(slot, RegDefs, RegUses);
bool done = false;
MachineBasicBlock::iterator I = slot;
while (!done) {
done = (I == MBB.begin());
if (!done)
--I;
// skip debug value
if (I->isDebugValue())
continue;
if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() ||
I->hasDelaySlot() || I->isBundledWithSucc())
break;
if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
insertDefsUses(I, RegDefs, RegUses);
continue;
}
return I;
}
return MBB.end();
}
示例4: insertCallUses
MachineBasicBlock::iterator
Filler::findDelayInstr(MachineBasicBlock &MBB,
MachineBasicBlock::iterator slot)
{
SmallSet<unsigned, 32> RegDefs;
SmallSet<unsigned, 32> RegUses;
bool sawLoad = false;
bool sawStore = false;
MachineBasicBlock::iterator I = slot;
if (slot->getOpcode() == SP::RET)
return MBB.end();
if (slot->getOpcode() == SP::RETL) {
--I;
if (I->getOpcode() != SP::RESTORErr)
return MBB.end();
//change retl to ret
slot->setDesc(TII->get(SP::RET));
return I;
}
//Call's delay filler can def some of call's uses.
if (slot->isCall())
insertCallUses(slot, RegUses);
else
insertDefsUses(slot, RegDefs, RegUses);
bool done = false;
while (!done) {
done = (I == MBB.begin());
if (!done)
--I;
// skip debug value
if (I->isDebugValue())
continue;
if (I->hasUnmodeledSideEffects()
|| I->isInlineAsm()
|| I->isLabel()
|| I->hasDelaySlot()
|| isDelayFiller(MBB, I))
break;
if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
insertDefsUses(I, RegDefs, RegUses);
continue;
}
return I;
}
return MBB.end();
}
示例5: fixStackStores
/// Replace pseudo store instructions that pass arguments through the stack with
/// real instructions. If insertPushes is true then all instructions are
/// replaced with push instructions, otherwise regular std instructions are
/// inserted.
static void fixStackStores(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const TargetInstrInfo &TII, bool insertPushes) {
const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
// Iterate through the BB until we hit a call instruction or we reach the end.
for (auto I = MI, E = MBB.end(); I != E && !I->isCall();) {
MachineBasicBlock::iterator NextMI = std::next(I);
MachineInstr &MI = *I;
unsigned Opcode = I->getOpcode();
// Only care of pseudo store instructions where SP is the base pointer.
if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr) {
I = NextMI;
continue;
}
assert(MI.getOperand(0).getReg() == AVR::SP &&
"Invalid register, should be SP!");
if (insertPushes) {
// Replace this instruction with a push.
unsigned SrcReg = MI.getOperand(2).getReg();
bool SrcIsKill = MI.getOperand(2).isKill();
// We can't use PUSHWRr here because when expanded the order of the new
// instructions are reversed from what we need. Perform the expansion now.
if (Opcode == AVR::STDWSPQRr) {
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
.addReg(TRI.getSubReg(SrcReg, AVR::sub_hi),
getKillRegState(SrcIsKill));
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
.addReg(TRI.getSubReg(SrcReg, AVR::sub_lo),
getKillRegState(SrcIsKill));
} else {
BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
.addReg(SrcReg, getKillRegState(SrcIsKill));
}
MI.eraseFromParent();
I = NextMI;
continue;
}
// Replace this instruction with a regular store. Use Y as the base
// pointer since it is guaranteed to contain a copy of SP.
unsigned STOpc =
(Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
MI.setDesc(TII.get(STOpc));
MI.getOperand(0).setReg(AVR::R29R28);
I = NextMI;
}
}
示例6: splitAdjDynAlloc
// Split ADJDYNALLOC instruction MI.
void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const {
MachineBasicBlock *MBB = MI->getParent();
MachineFunction &MF = *MBB->getParent();
MachineFrameInfo *MFFrame = MF.getFrameInfo();
MachineOperand &OffsetMO = MI->getOperand(2);
uint64_t Offset = (MFFrame->getMaxCallFrameSize() +
SystemZMC::CallFrameSize +
OffsetMO.getImm());
unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset);
assert(NewOpcode && "No support for huge argument lists yet");
MI->setDesc(get(NewOpcode));
OffsetMO.setImm(Offset);
}
示例7: emitEpilogue
void SystemZFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const SystemZInstrInfo *ZII =
static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
// Skip the return instruction.
assert(MBBI->getOpcode() == SystemZ::RET &&
"Can only insert epilogue into returning blocks");
uint64_t StackSize = getAllocatedStackSize(MF);
if (ZFI->getLowSavedGPR()) {
--MBBI;
unsigned Opcode = MBBI->getOpcode();
if (Opcode != SystemZ::LMG)
llvm_unreachable("Expected to see callee-save register restore code");
unsigned AddrOpNo = 2;
DebugLoc DL = MBBI->getDebugLoc();
uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
// If the offset is too large, use the largest stack-aligned offset
// and add the rest to the base register (the stack or frame pointer).
if (!NewOpcode) {
uint64_t NumBytes = Offset - 0x7fff8;
emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
NumBytes, ZII);
Offset -= NumBytes;
NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
assert(NewOpcode && "No restore instruction available");
}
MBBI->setDesc(ZII->get(NewOpcode));
MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
} else if (StackSize) {
DebugLoc DL = MBBI->getDebugLoc();
emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII);
}
}
示例8: combineRestoreSETHIi
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI,
MachineBasicBlock::iterator SetHiMI,
const TargetInstrInfo *TII)
{
// Before: sethi imm3, %i[0-7]
// restore %g0, %g0, %g0
//
// After : restore %g0, (imm3<<10), %o[0-7]
unsigned reg = SetHiMI->getOperand(0).getReg();
if (reg < SP::I0 || reg > SP::I7)
return false;
if (!SetHiMI->getOperand(1).isImm())
return false;
int64_t imm = SetHiMI->getOperand(1).getImm();
// Is it a 3 bit immediate?
if (!isInt<3>(imm))
return false;
// Make it a 13 bit immediate.
imm = (imm << 10) & 0x1FFF;
assert(RestoreMI->getOpcode() == SP::RESTORErr);
RestoreMI->setDesc(TII->get(SP::RESTOREri));
RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
RestoreMI->getOperand(1).setReg(SP::G0);
RestoreMI->getOperand(2).ChangeToImmediate(imm);
// Erase the original SETHI.
SetHiMI->eraseFromParent();
return true;
}
示例9: combineRestoreOR
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI,
MachineBasicBlock::iterator OrMI,
const TargetInstrInfo *TII)
{
// Before: or <op0>, <op1>, %i[0-7]
// restore %g0, %g0, %i[0-7]
// and <op0> or <op1> is zero,
//
// After : restore <op0>, <op1>, %o[0-7]
unsigned reg = OrMI->getOperand(0).getReg();
if (reg < SP::I0 || reg > SP::I7)
return false;
// check whether it is a copy.
if (OrMI->getOpcode() == SP::ORrr
&& OrMI->getOperand(1).getReg() != SP::G0
&& OrMI->getOperand(2).getReg() != SP::G0)
return false;
if (OrMI->getOpcode() == SP::ORri
&& OrMI->getOperand(1).getReg() != SP::G0
&& (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
return false;
// Erase RESTORE.
RestoreMI->eraseFromParent();
// Change OR to RESTORE.
OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr)
? SP::RESTORErr
: SP::RESTOREri));
// Map the destination register.
OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
return true;
}
示例10: runOnMachineFunction
bool AlphaBSel::runOnMachineFunction(MachineFunction &Fn) {
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
++MFI) {
MachineBasicBlock *MBB = MFI;
for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
MBBI != EE; ++MBBI) {
if (MBBI->getOpcode() == Alpha::COND_BRANCH_I ||
MBBI->getOpcode() == Alpha::COND_BRANCH_F) {
// condbranch operands:
// 0. bc opcode
// 1. reg
// 2. target MBB
const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
MBBI->setDesc(TII->get(MBBI->getOperand(0).getImm()));
}
}
}
return true;
}
示例11: runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override {
ST = &MF.getSubtarget<R600Subtarget>();
MaxFetchInst = ST->getTexVTXClauseSize();
TII = ST->getInstrInfo();
TRI = ST->getRegisterInfo();
R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
CFStack CFStack(ST, MF.getFunction().getCallingConv());
for (MachineFunction::iterator MB = MF.begin(), ME = MF.end(); MB != ME;
++MB) {
MachineBasicBlock &MBB = *MB;
unsigned CfCount = 0;
std::vector<std::pair<unsigned, std::set<MachineInstr *>>> LoopStack;
std::vector<MachineInstr * > IfThenElseStack;
if (MF.getFunction().getCallingConv() == CallingConv::AMDGPU_VS) {
BuildMI(MBB, MBB.begin(), MBB.findDebugLoc(MBB.begin()),
getHWInstrDesc(CF_CALL_FS));
CfCount++;
}
std::vector<ClauseFile> FetchClauses, AluClauses;
std::vector<MachineInstr *> LastAlu(1);
std::vector<MachineInstr *> ToPopAfter;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E;) {
if (TII->usesTextureCache(*I) || TII->usesVertexCache(*I)) {
LLVM_DEBUG(dbgs() << CfCount << ":"; I->dump(););
FetchClauses.push_back(MakeFetchClause(MBB, I));
CfCount++;
LastAlu.back() = nullptr;
continue;
}
MachineBasicBlock::iterator MI = I;
if (MI->getOpcode() != R600::ENDIF)
LastAlu.back() = nullptr;
if (MI->getOpcode() == R600::CF_ALU)
LastAlu.back() = &*MI;
I++;
bool RequiresWorkAround =
CFStack.requiresWorkAroundForInst(MI->getOpcode());
switch (MI->getOpcode()) {
case R600::CF_ALU_PUSH_BEFORE:
if (RequiresWorkAround) {
LLVM_DEBUG(dbgs()
<< "Applying bug work-around for ALU_PUSH_BEFORE\n");
BuildMI(MBB, MI, MBB.findDebugLoc(MI), TII->get(R600::CF_PUSH_EG))
.addImm(CfCount + 1)
.addImm(1);
MI->setDesc(TII->get(R600::CF_ALU));
CfCount++;
CFStack.pushBranch(R600::CF_PUSH_EG);
} else
CFStack.pushBranch(R600::CF_ALU_PUSH_BEFORE);
LLVM_FALLTHROUGH;
case R600::CF_ALU:
I = MI;
AluClauses.push_back(MakeALUClause(MBB, I));
LLVM_DEBUG(dbgs() << CfCount << ":"; MI->dump(););
CfCount++;
break;
case R600::WHILELOOP: {
CFStack.pushLoop();
MachineInstr *MIb = BuildMI(MBB, MI, MBB.findDebugLoc(MI),
getHWInstrDesc(CF_WHILE_LOOP))
.addImm(1);
std::pair<unsigned, std::set<MachineInstr *>> Pair(CfCount,
std::set<MachineInstr *>());
Pair.second.insert(MIb);
LoopStack.push_back(std::move(Pair));
MI->eraseFromParent();
CfCount++;
break;
}
case R600::ENDLOOP: {
CFStack.popLoop();
std::pair<unsigned, std::set<MachineInstr *>> Pair =
std::move(LoopStack.back());
LoopStack.pop_back();
CounterPropagateAddr(Pair.second, CfCount);
BuildMI(MBB, MI, MBB.findDebugLoc(MI), getHWInstrDesc(CF_END_LOOP))
.addImm(Pair.first + 1);
MI->eraseFromParent();
CfCount++;
break;
}
case R600::IF_PREDICATE_SET: {
LastAlu.push_back(nullptr);
MachineInstr *MIb = BuildMI(MBB, MI, MBB.findDebugLoc(MI),
getHWInstrDesc(CF_JUMP))
.addImm(0)
.addImm(0);
IfThenElseStack.push_back(MIb);
LLVM_DEBUG(dbgs() << CfCount << ":"; MIb->dump(););
MI->eraseFromParent();
CfCount++;
break;
}
示例12: runOnMachineFunction
virtual bool runOnMachineFunction(MachineFunction &MF) {
TII=static_cast<const R600InstrInfo *>(MF.getTarget().getInstrInfo());
TRI=static_cast<const R600RegisterInfo *>(MF.getTarget().getRegisterInfo());
unsigned MaxStack = 0;
unsigned CurrentStack = 0;
unsigned CurrentLoopDepth = 0;
bool HasPush = false;
for (MachineFunction::iterator MB = MF.begin(), ME = MF.end(); MB != ME;
++MB) {
MachineBasicBlock &MBB = *MB;
unsigned CfCount = 0;
std::vector<std::pair<unsigned, std::set<MachineInstr *> > > LoopStack;
std::vector<MachineInstr * > IfThenElseStack;
R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
if (MFI->ShaderType == 1) {
BuildMI(MBB, MBB.begin(), MBB.findDebugLoc(MBB.begin()),
getHWInstrDesc(CF_CALL_FS));
CfCount++;
MaxStack = 1;
}
std::vector<ClauseFile> FetchClauses, AluClauses;
std::vector<MachineInstr *> LastAlu(1);
std::vector<MachineInstr *> ToPopAfter;
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E;) {
if (TII->usesTextureCache(I) || TII->usesVertexCache(I)) {
DEBUG(dbgs() << CfCount << ":"; I->dump(););
FetchClauses.push_back(MakeFetchClause(MBB, I));
CfCount++;
continue;
}
MachineBasicBlock::iterator MI = I;
if (MI->getOpcode() != AMDGPU::ENDIF)
LastAlu.back() = 0;
if (MI->getOpcode() == AMDGPU::CF_ALU)
LastAlu.back() = MI;
I++;
switch (MI->getOpcode()) {
case AMDGPU::CF_ALU_PUSH_BEFORE:
CurrentStack++;
MaxStack = std::max(MaxStack, CurrentStack);
HasPush = true;
if (ST.hasCaymanISA() && CurrentLoopDepth > 1) {
BuildMI(MBB, MI, MBB.findDebugLoc(MI), TII->get(AMDGPU::CF_PUSH_CM))
.addImm(CfCount + 1)
.addImm(1);
MI->setDesc(TII->get(AMDGPU::CF_ALU));
CfCount++;
}
case AMDGPU::CF_ALU:
I = MI;
AluClauses.push_back(MakeALUClause(MBB, I));
DEBUG(dbgs() << CfCount << ":"; MI->dump(););
CfCount++;
break;
case AMDGPU::WHILELOOP: {
CurrentStack+=4;
CurrentLoopDepth++;
MaxStack = std::max(MaxStack, CurrentStack);
MachineInstr *MIb = BuildMI(MBB, MI, MBB.findDebugLoc(MI),
getHWInstrDesc(CF_WHILE_LOOP))
.addImm(1);
std::pair<unsigned, std::set<MachineInstr *> > Pair(CfCount,
std::set<MachineInstr *>());
Pair.second.insert(MIb);
LoopStack.push_back(Pair);
MI->eraseFromParent();
CfCount++;
break;
}
case AMDGPU::ENDLOOP: {
CurrentStack-=4;
CurrentLoopDepth--;
std::pair<unsigned, std::set<MachineInstr *> > Pair =
LoopStack.back();
LoopStack.pop_back();
CounterPropagateAddr(Pair.second, CfCount);
BuildMI(MBB, MI, MBB.findDebugLoc(MI), getHWInstrDesc(CF_END_LOOP))
.addImm(Pair.first + 1);
MI->eraseFromParent();
CfCount++;
break;
}
case AMDGPU::IF_PREDICATE_SET: {
LastAlu.push_back(0);
MachineInstr *MIb = BuildMI(MBB, MI, MBB.findDebugLoc(MI),
getHWInstrDesc(CF_JUMP))
.addImm(0)
.addImm(0);
IfThenElseStack.push_back(MIb);
DEBUG(dbgs() << CfCount << ":"; MIb->dump(););
MI->eraseFromParent();
CfCount++;
break;
}
示例13: assert
void
SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Outgoing arguments should be part of the frame");
MachineBasicBlock &MBB = *MI->getParent();
MachineFunction &MF = *MBB.getParent();
auto *TII =
static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
const SystemZFrameLowering *TFI = getFrameLowering(MF);
DebugLoc DL = MI->getDebugLoc();
// Decompose the frame index into a base and offset.
int FrameIndex = MI->getOperand(FIOperandNum).getIndex();
unsigned BasePtr = getFrameRegister(MF);
int64_t Offset = (TFI->getFrameIndexOffset(MF, FrameIndex) +
MI->getOperand(FIOperandNum + 1).getImm());
// Special handling of dbg_value instructions.
if (MI->isDebugValue()) {
MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, /*isDef*/ false);
MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
return;
}
// See if the offset is in range, or if an equivalent instruction that
// accepts the offset exists.
unsigned Opcode = MI->getOpcode();
unsigned OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
if (OpcodeForOffset)
MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
else {
// Create an anchor point that is in range. Start at 0xffff so that
// can use LLILH to load the immediate.
int64_t OldOffset = Offset;
int64_t Mask = 0xffff;
do {
Offset = OldOffset & Mask;
OpcodeForOffset = TII->getOpcodeForOffset(Opcode, Offset);
Mask >>= 1;
assert(Mask && "One offset must be OK");
} while (!OpcodeForOffset);
unsigned ScratchReg =
MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
int64_t HighOffset = OldOffset - Offset;
if (MI->getDesc().TSFlags & SystemZII::HasIndex
&& MI->getOperand(FIOperandNum + 2).getReg() == 0) {
// Load the offset into the scratch register and use it as an index.
// The scratch register then dies here.
TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
MI->getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
MI->getOperand(FIOperandNum + 2).ChangeToRegister(ScratchReg,
false, false, true);
} else {
// Load the anchor address into a scratch register.
unsigned LAOpcode = TII->getOpcodeForOffset(SystemZ::LA, HighOffset);
if (LAOpcode)
BuildMI(MBB, MI, DL, TII->get(LAOpcode),ScratchReg)
.addReg(BasePtr).addImm(HighOffset).addReg(0);
else {
// Load the high offset into the scratch register and use it as
// an index.
TII->loadImmediate(MBB, MI, ScratchReg, HighOffset);
BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg)
.addReg(ScratchReg, RegState::Kill).addReg(BasePtr);
}
// Use the scratch register as the base. It then dies here.
MI->getOperand(FIOperandNum).ChangeToRegister(ScratchReg,
false, false, true);
}
}
MI->setDesc(TII->get(OpcodeForOffset));
MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
}