Undef = 0x20,
EarlyClobber = 0x40,
Debug = 0x80,
+ InternalRead = 0x100,
+ DefineNoRead = Define | Undef,
ImplicitDefine = Implicit | Define,
ImplicitKill = Implicit | Kill
};
flags & RegState::Undef,
flags & RegState::EarlyClobber,
SubReg,
- flags & RegState::Debug));
+ flags & RegState::Debug,
+ flags & RegState::InternalRead));
return *this;
}
return *this;
}
+ const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags));
+ return *this;
+ }
+
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
unsigned char TargetFlags = 0) const {
MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
return *this;
}
+ const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
+ MI->addOperand(MachineOperand::CreateRegMask(Mask));
+ return *this;
+ }
+
const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
MI->addMemOperand(*MI->getParent()->getParent(), MMO);
return *this;
}
// Add a displacement from an existing MachineOperand with an added offset.
- const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
- int64_t off) const {
+ const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off,
+ unsigned char TargetFlags = 0) const {
switch (Disp.getType()) {
default:
llvm_unreachable("Unhandled operand type in addDisp()");
case MachineOperand::MO_Immediate:
return addImm(Disp.getImm() + off);
- case MachineOperand::MO_GlobalAddress:
- return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
+ case MachineOperand::MO_GlobalAddress: {
+ // If caller specifies new TargetFlags then use it, otherwise the
+ // default behavior is to copy the target flags from the existing
+ // MachineOperand. This means if the caller wants to clear the
+ // target flags it needs to do so explicitly.
+ if (TargetFlags)
+ return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+ TargetFlags);
+ return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+ Disp.getTargetFlags());
+ }
}
}
};
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+}
+
/// BuildMI - This version of the builder inserts the newly-built
/// instruction before the given position in the given MachineBasicBlock, and
/// does NOT take a destination register.
return MachineInstrBuilder(MI);
}
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+}
+
/// BuildMI - This version of the builder inserts the newly-built
/// instruction at the end of the given MachineBasicBlock, and does NOT take a
/// destination register.
inline unsigned getUndefRegState(bool B) {
return B ? RegState::Undef : 0;
}
+inline unsigned getInternalReadRegState(bool B) {
+ return B ? RegState::InternalRead : 0;
+}
+
+
+/// Helper class for constructing bundles of MachineInstrs.
+///
+/// MIBundleBuilder can create a bundle from scratch by inserting new
+/// MachineInstrs one at a time, or it can create a bundle from a sequence of
+/// existing MachineInstrs in a basic block.
+class MIBundleBuilder {
+ MachineBasicBlock &MBB;
+ MachineBasicBlock::instr_iterator Begin;
+ MachineBasicBlock::instr_iterator End;
+
+public:
+ /// Create an MIBundleBuilder that inserts instructions into a new bundle in
+ /// BB above the bundle or instruction at Pos.
+ MIBundleBuilder(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator Pos)
+ : MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {}
+
+ /// Create a bundle from the sequence of instructions between B and E.
+ MIBundleBuilder(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator B,
+ MachineBasicBlock::iterator E)
+ : MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) {
+ assert(B != E && "No instructions to bundle");
+ ++B;
+ while (B != E) {
+ MachineInstr *MI = B;
+ ++B;
+ MI->bundleWithPred();
+ }
+ }
+
+ /// Return true if no instructions have been inserted in this bundle yet.
+ /// Empty bundles aren't representable in a MachineBasicBlock.
+ bool empty() const { return Begin == End; }
+
+ /// Return an iterator to the first bundled instruction.
+ MachineBasicBlock::instr_iterator begin() const { return Begin; }
+
+ /// Return an iterator beyond the last bundled instruction.
+ MachineBasicBlock::instr_iterator end() const { return End; }
+
+ /// Insert MI into MBB by prepending it to the instructions in the bundle.
+ /// MI will become the first instruction in the bundle.
+ MIBundleBuilder &prepend(MachineInstr *MI) {
+ MBB.insert(Begin, MI);
+ if (!empty())
+ MI->bundleWithSucc();
+ Begin = MI;
+ return *this;
+ }
+
+ /// Insert MI into MBB by appending it to the instructions in the bundle.
+ /// MI will become the last instruction in the bundle.
+ MIBundleBuilder &append(MachineInstr *MI) {
+ MBB.insert(End, MI);
+ if (empty())
+ Begin = MI;
+ else
+ MI->bundleWithPred();
+ return *this;
+ }
+};
} // End llvm namespace