/// This is only valid on definitions of registers.
bool IsDead : 1;
+ /// IsEarlyClobber flag - this is only valid for MO_Register operands in
+ /// an inline asm.
+
+ /// IsEarlyClobber - True if this operand is marked earlyclobber in an
+ /// inline asm. See gcc doc for description of earlyclobber.
+ bool IsEarlyClobber : 1;
+
/// SubReg - Subregister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg.
unsigned char SubReg;
return IsKill;
}
+ bool isEarlyClobber() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsEarlyClobber;
+ }
+
/// getNextOperandForReg - Return the next MachineOperand in the function that
/// uses or defines this register.
MachineOperand *getNextOperandForReg() const {
IsDead = Val;
}
+ void setIsEarlyClobber(bool Val = true) {
+ assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+ IsEarlyClobber = Val;
+ }
//===--------------------------------------------------------------------===//
// Accessors for various operand types.
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
- bool isKill = false, bool isDead = false);
+ bool isKill = false, bool isDead = false,
+ bool isEarlyClobber = false);
//===--------------------------------------------------------------------===//
// Construction methods.
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
bool isKill = false, bool isDead = false,
- unsigned SubReg = 0) {
+ unsigned SubReg = 0,
+ bool isEarlyClobber = false) {
MachineOperand Op(MachineOperand::MO_Register);
Op.IsDef = isDef;
Op.IsImp = isImp;
Op.IsKill = isKill;
Op.IsDead = isDead;
+ Op.IsEarlyClobber = isEarlyClobber;
Op.Contents.Reg.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
IsImp = MO.IsImp;
IsKill = MO.IsKill;
IsDead = MO.IsDead;
+ IsEarlyClobber = MO.IsEarlyClobber;
SubReg = MO.SubReg;
ParentMI = MO.ParentMI;
Contents = MO.Contents;
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
- bool isKill, bool isDead) {
+ bool isKill, bool isDead,
+ bool isEarlyClobber) {
// If this operand is already a register operand, use setReg to update the
// register's use/def lists.
if (isReg()) {
IsImp = isImp;
IsKill = isKill;
IsDead = isDead;
+ IsEarlyClobber = isEarlyClobber;
SubReg = 0;
}
OS << "%mreg" << getReg();
}
- if (isDef() || isKill() || isDead() || isImplicit()) {
+ if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
OS << "<";
bool NeedComma = false;
if (isImplicit()) {
OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true;
} else if (isDef()) {
+ if (isEarlyClobber())
+ OS << "earlyclobber,";
OS << "def";
NeedComma = true;
}
MI->addOperand(MachineOperand::CreateReg(Reg, true));
}
break;
+ case 6: // Def of earlyclobber register.
+ for (; NumVals; --NumVals, ++i) {
+ unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
+ MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false,
+ false, 0, true));
+ }
+ break;
case 1: // Use of register.
case 3: // Immediate.
case 4: // Addressing mode.
// Add information to the INLINEASM node to know that this register is
// set.
- OpInfo.AssignedRegs.AddInlineAsmOperands(2 /*REGDEF*/, DAG,
- AsmNodeOperands);
+ OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
+ 6 /* EARLYCLOBBER REGDEF */ :
+ 2 /* REGDEF */ ,
+ DAG, AsmNodeOperands);
break;
}
case InlineAsm::isInput: {
unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert(((NumOps & 7) == 2 /*REGDEF*/ ||
+ (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
(NumOps & 7) == 4 /*MEM*/) &&
"Skipped past definitions?");
CurOp += (NumOps>>3)+1;
unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
- if ((NumOps & 7) == 2 /*REGDEF*/) {
+ if ((NumOps & 7) == 2 /*REGDEF*/
+ || (NumOps & 7) == 6 /* EARLYCLOBBER REGDEF */) {
// Add NumOps>>3 registers to MatchedRegs.
RegsForValue MatchedRegs;
MatchedRegs.TLI = &TLI;