class MachineInstr;
class MachineRegisterInfo;
class MDNode;
+class ModuleSlotTracker;
class TargetMachine;
class TargetRegisterInfo;
class hash_code;
///
class MachineOperand {
public:
- enum MachineOperandType {
- MO_Register, ///< Register operand.
- MO_Immediate, ///< Immediate operand
- MO_CImmediate, ///< Immediate >64bit operand
- MO_FPImmediate, ///< Floating-point immediate operand
- MO_MachineBasicBlock, ///< MachineBasicBlock reference
- MO_FrameIndex, ///< Abstract Stack Frame Index
- MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
- MO_TargetIndex, ///< Target-dependent index+offset operand.
- MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
- MO_ExternalSymbol, ///< Name of external global symbol
- MO_GlobalAddress, ///< Address of a global value
- MO_BlockAddress, ///< Address of a basic block
- MO_RegisterMask, ///< Mask of preserved registers.
- MO_Metadata, ///< Metadata reference (for debug info)
- MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
+ enum MachineOperandType : unsigned char {
+ MO_Register, ///< Register operand.
+ MO_Immediate, ///< Immediate operand
+ MO_CImmediate, ///< Immediate >64bit operand
+ MO_FPImmediate, ///< Floating-point immediate operand
+ MO_MachineBasicBlock, ///< MachineBasicBlock reference
+ MO_FrameIndex, ///< Abstract Stack Frame Index
+ MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
+ MO_TargetIndex, ///< Target-dependent index+offset operand.
+ MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
+ MO_ExternalSymbol, ///< Name of external global symbol
+ MO_GlobalAddress, ///< Address of a global value
+ MO_BlockAddress, ///< Address of a basic block
+ MO_RegisterMask, ///< Mask of preserved registers.
+ MO_RegisterLiveOut, ///< Mask of live-out registers.
+ MO_Metadata, ///< Metadata reference (for debug info)
+ MO_MCSymbol, ///< MCSymbol reference (for debug/eh info)
+ MO_CFIIndex ///< MCCFIInstruction index.
};
private:
/// OpKind - Specify what kind of operand this is. This discriminates the
/// union.
- unsigned char OpKind; // MachineOperandType
+ MachineOperandType OpKind : 8;
/// Subregister number for MO_Register. A value of 0 indicates the
/// MO_Register has no subReg.
/// Contents union - This contains the payload for the various operand types.
union {
- MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
- const ConstantFP *CFP; // For MO_FPImmediate.
- const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
- int64_t ImmVal; // For MO_Immediate.
- const uint32_t *RegMask; // For MO_RegisterMask.
- const MDNode *MD; // For MO_Metadata.
- MCSymbol *Sym; // For MO_MCSymbol
+ MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
+ const ConstantFP *CFP; // For MO_FPImmediate.
+ const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
+ int64_t ImmVal; // For MO_Immediate.
+ const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
+ const MDNode *MD; // For MO_Metadata.
+ MCSymbol *Sym; // For MO_MCSymbol.
+ unsigned CFIIndex; // For MO_CFI.
struct { // For MO_Register.
// Register number is in SmallContents.RegNo.
} Contents;
explicit MachineOperand(MachineOperandType K)
- : OpKind(K), SubReg_TargetFlags(0), ParentMI(0) {}
+ : OpKind(K), SubReg_TargetFlags(0), ParentMI(nullptr) {}
public:
/// getType - Returns the MachineOperandType for this operand.
///
///
/// Never call clearParent() on an operand in a MachineInstr.
///
- void clearParent() { ParentMI = 0; }
+ void clearParent() { ParentMI = nullptr; }
- void print(raw_ostream &os, const TargetMachine *TM = 0) const;
+ void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const;
+ void print(raw_ostream &os, ModuleSlotTracker &MST,
+ const TargetRegisterInfo *TRI = nullptr) const;
//===--------------------------------------------------------------------===//
// Accessors that tell you what kind of MachineOperand you're looking at.
bool isReg() const { return OpKind == MO_Register; }
/// isImm - Tests if this is a MO_Immediate operand.
bool isImm() const { return OpKind == MO_Immediate; }
- /// isCImm - Test if t his is a MO_CImmediate operand.
+ /// isCImm - Test if this is a MO_CImmediate operand.
bool isCImm() const { return OpKind == MO_CImmediate; }
/// isFPImm - Tests if this is a MO_FPImmediate operand.
bool isFPImm() const { return OpKind == MO_FPImmediate; }
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
/// isRegMask - Tests if this is a MO_RegisterMask operand.
bool isRegMask() const { return OpKind == MO_RegisterMask; }
+ /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
+ bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
/// isMetadata - Tests if this is a MO_Metadata operand.
bool isMetadata() const { return OpKind == MO_Metadata; }
bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
-
+ bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
//===--------------------------------------------------------------------===//
// Accessors for Register Operands
return Contents.Sym;
}
- /// getOffset - Return the offset from the symbol in this operand. This always
- /// returns 0 for ExternalSymbol operands.
+ unsigned getCFIIndex() const {
+ assert(isCFIIndex() && "Wrong MachineOperand accessor");
+ return Contents.CFIIndex;
+ }
+
+ /// Return the offset from the symbol in this operand. This always returns 0
+ /// for ExternalSymbol operands.
int64_t getOffset() const {
- assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
- isBlockAddress()) && "Wrong MachineOperand accessor");
+ assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() ||
+ isTargetIndex() || isBlockAddress()) &&
+ "Wrong MachineOperand accessor");
return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
SmallContents.OffsetLo;
}
return Contents.RegMask;
}
+ /// getRegLiveOut - Returns a bit mask of live-out registers.
+ const uint32_t *getRegLiveOut() const {
+ assert(isRegLiveOut() && "Wrong MachineOperand accessor");
+ return Contents.RegMask;
+ }
+
const MDNode *getMetadata() const {
assert(isMetadata() && "Wrong MachineOperand accessor");
return Contents.MD;
Contents.ImmVal = immVal;
}
+ void setFPImm(const ConstantFP *CFP) {
+ assert(isFPImm() && "Wrong MachineOperand mutator");
+ Contents.CFP = CFP;
+ }
+
void setOffset(int64_t Offset) {
- assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
- isBlockAddress()) && "Wrong MachineOperand accessor");
+ assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() ||
+ isTargetIndex() || isBlockAddress()) &&
+ "Wrong MachineOperand accessor");
SmallContents.OffsetLo = unsigned(Offset);
Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
}
/// the setImm method should be used.
void ChangeToImmediate(int64_t ImmVal);
+ /// ChangeToFPImmediate - Replace this operand with a new FP immediate operand
+ /// of the specified value. If an operand is known to be an FP immediate
+ /// already, the setFPImm method should be used.
+ void ChangeToFPImmediate(const ConstantFP *FPImm);
+
+ /// ChangeToES - Replace this operand with a new external symbol operand.
+ void ChangeToES(const char *SymName, unsigned char TargetFlags = 0);
+
+ /// ChangeToMCSymbol - Replace this operand with a new MC symbol operand.
+ void ChangeToMCSymbol(MCSymbol *Sym);
+
/// ChangeToRegister - Replace this operand with a new register operand of
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
Op.TiedTo = 0;
Op.IsDebug = isDebug;
Op.SmallContents.RegNo = Reg;
- Op.Contents.Reg.Prev = 0;
- Op.Contents.Reg.Next = 0;
+ Op.Contents.Reg.Prev = nullptr;
+ Op.Contents.Reg.Next = nullptr;
Op.setSubReg(SubReg);
return Op;
}
Op.Contents.RegMask = Mask;
return Op;
}
+ static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
+ assert(Mask && "Missing live-out register mask");
+ MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
+ Op.Contents.RegMask = Mask;
+ return Op;
+ }
static MachineOperand CreateMetadata(const MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
return Op;
}
- static MachineOperand CreateMCSymbol(MCSymbol *Sym) {
+ static MachineOperand CreateMCSymbol(MCSymbol *Sym,
+ unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_MCSymbol);
Op.Contents.Sym = Sym;
+ Op.setOffset(0);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+
+ static MachineOperand CreateCFIIndex(unsigned CFIIndex) {
+ MachineOperand Op(MachineOperand::MO_CFIIndex);
+ Op.Contents.CFIIndex = CFIIndex;
return Op;
}
friend class MachineInstr;
friend class MachineRegisterInfo;
private:
+ void removeRegFromUses();
+
//===--------------------------------------------------------------------===//
// Methods for handling register use/def lists.
//===--------------------------------------------------------------------===//
/// part of a machine instruction.
bool isOnRegUseList() const {
assert(isReg() && "Can only add reg operand to use lists");
- return Contents.Reg.Prev != 0;
+ return Contents.Reg.Prev != nullptr;
}
};
inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
- MO.print(OS, 0);
+ MO.print(OS, nullptr);
return OS;
}