/// union.
unsigned char OpKind; // MachineOperandType
- /// SubReg - Subregister number, only valid for MO_Register. A value of 0
- /// indicates the MO_Register has no subReg.
- unsigned char SubReg;
+ // This union is discriminated by OpKind.
+ union {
+ /// SubReg - Subregister number, only valid for MO_Register. A value of 0
+ /// indicates the MO_Register has no subReg.
+ unsigned char SubReg;
- /// TargetFlags - This is a set of target-specific operand flags.
- unsigned char TargetFlags;
+ /// TargetFlags - This is a set of target-specific operand flags.
+ unsigned char TargetFlags;
+ };
/// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
/// operands.
/// model the GCC inline asm '&' constraint modifier.
bool IsEarlyClobber : 1;
+ /// IsTied - True if this MO_Register operand is tied to another operand on
+ /// the instruction. Tied operands form def-use pairs that must be assigned
+ /// the same physical register by the register allocator, but they will have
+ /// different virtual registers while the code is in SSA form.
+ ///
+ /// See MachineInstr::isRegTiedToUseOperand() and isRegTiedToDefOperand().
+ bool IsTied : 1;
+
/// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
/// not a real instruction. Such uses should be ignored during codegen.
bool IsDebug : 1;
/// This is valid for all operand types, when the operand is in an instr.
MachineInstr *ParentMI;
- // MRI accesses Contents.Reg directly.
- friend class MachineRegisterInfo;
-
/// Contents union - This contains the payload for the various operand types.
union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
struct { // For MO_Register.
// Register number is in SmallContents.RegNo.
- MachineOperand **Prev; // Access list for register.
+ MachineOperand *Prev; // Access list for register. See MRI.
MachineOperand *Next;
} Reg;
///
MachineOperandType getType() const { return (MachineOperandType)OpKind; }
- unsigned char getTargetFlags() const { return TargetFlags; }
- void setTargetFlags(unsigned char F) { TargetFlags = F; }
- void addTargetFlag(unsigned char F) { TargetFlags |= F; }
+ unsigned char getTargetFlags() const {
+ return isReg() ? 0 : TargetFlags;
+ }
+ void setTargetFlags(unsigned char F) {
+ assert(!isReg() && "Register operands can't have target flags");
+ TargetFlags = F;
+ }
+ void addTargetFlag(unsigned char F) {
+ assert(!isReg() && "Register operands can't have target flags");
+ TargetFlags |= F;
+ }
/// getParent - Return the instruction that this operand belongs to.
return IsEarlyClobber;
}
+ bool isTied() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsTied;
+ }
+
bool isDebug() const {
assert(isReg() && "Wrong MachineOperand accessor");
return IsDebug;
///
void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
- void setIsUse(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert((Val || !isDebug()) && "Marking a debug operation as def");
- IsDef = !Val;
- }
+ void setIsUse(bool Val = true) { setIsDef(!Val); }
- void setIsDef(bool Val = true) {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert((!Val || !isDebug()) && "Marking a debug operation as def");
- IsDef = Val;
- }
+ void setIsDef(bool Val = true);
void setImplicit(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
IsEarlyClobber = Val;
}
+ void setIsTied(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ IsTied = Val;
+ }
+
void setIsDebug(bool Val = true) {
assert(isReg() && IsDef && "Wrong MachineOperand accessor");
IsDebug = Val;
int64_t getOffset() const {
assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
isBlockAddress()) && "Wrong MachineOperand accessor");
- return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
+ return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
SmallContents.OffsetLo;
}
Op.IsUndef = isUndef;
Op.IsInternalRead = isInternalRead;
Op.IsEarlyClobber = isEarlyClobber;
+ Op.IsTied = false;
Op.IsDebug = isDebug;
Op.SmallContents.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
assert(isReg() && "Can only add reg operand to use lists");
return Contents.Reg.Prev != 0;
}
-
- /// AddRegOperandToRegInfo - Add this register operand to the specified
- /// MachineRegisterInfo. If it is null, then the next/prev fields should be
- /// explicitly nulled out.
- void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
-
- /// RemoveRegOperandFromRegInfo - Remove this register operand from the
- /// MachineRegisterInfo it is linked with.
- void RemoveRegOperandFromRegInfo();
};
inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {