1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Extract a method for finding the inline asm flag operand.

llvm-svn: 141834
This commit is contained in:
Jakob Stoklund Olesen 2011-10-12 23:37:33 +00:00
parent 3d62f52b22
commit d406c95461
2 changed files with 50 additions and 30 deletions

View File

@ -388,6 +388,18 @@ public:
/// none is found.
int findFirstPredOperandIdx() const;
/// findInlineAsmFlagIdx() - Find the index of the flag word operand that
/// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if
/// getOperand(OpIdx) does not belong to an inline asm operand group.
///
/// If GroupNo is not NULL, it will receive the number of the operand group
/// containing OpIdx.
///
/// The flag operand is an immediate that can be decoded with methods like
/// InlineAsm::hasRegClassConstraint().
///
int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const;
/// isRegTiedToUseOperand - Given the index of a register def operand,
/// check if the register def is tied to a source operand, due to either
/// two-address elimination or inline assembly constraints. Returns the

View File

@ -826,6 +826,34 @@ bool MachineInstr::isStackAligningInlineAsm() const {
return false;
}
int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
unsigned *GroupNo) const {
assert(isInlineAsm() && "Expected an inline asm instruction");
assert(OpIdx < getNumOperands() && "OpIdx out of range");
// Ignore queries about the initial operands.
if (OpIdx < InlineAsm::MIOp_FirstOperand)
return -1;
unsigned Group = 0;
unsigned NumOps;
for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
i += NumOps) {
const MachineOperand &FlagMO = getOperand(i);
// If we reach the implicit register operands, stop looking.
if (!FlagMO.isImm())
return -1;
NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
if (i + NumOps > OpIdx) {
if (GroupNo)
*GroupNo = Group;
return i;
}
++Group;
}
return -1;
}
/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
/// the specific register or -1 if it is not found. It further tightens
/// the search criteria to a use that kills the register if isKill is true.
@ -935,23 +963,13 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
return false;
// Determine the actual operand index that corresponds to this index.
unsigned DefNo = 0;
unsigned DefPart = 0;
for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands();
i < e; ) {
const MachineOperand &FMO = getOperand(i);
// After the normal asm operands there may be additional imp-def regs.
if (!FMO.isImm())
return false;
// Skip over this def.
unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
unsigned PrevDef = i + 1;
i = PrevDef + NumOps;
if (i > DefOpIdx) {
DefPart = DefOpIdx - PrevDef;
break;
}
++DefNo;
}
int FlagIdx = findInlineAsmFlagIdx(DefOpIdx, &DefNo);
if (FlagIdx < 0)
return false;
// Which part of the group is DefOpIdx?
unsigned DefPart = DefOpIdx - (FlagIdx + 1);
for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands();
i != e; ++i) {
const MachineOperand &FMO = getOperand(i);
@ -995,20 +1013,10 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
return false;
// Find the flag operand corresponding to UseOpIdx
unsigned FlagIdx, NumOps=0;
for (FlagIdx = InlineAsm::MIOp_FirstOperand;
FlagIdx < UseOpIdx; FlagIdx += NumOps+1) {
const MachineOperand &UFMO = getOperand(FlagIdx);
// After the normal asm operands there may be additional imp-def regs.
if (!UFMO.isImm())
return false;
NumOps = InlineAsm::getNumOperandRegisters(UFMO.getImm());
assert(NumOps < getNumOperands() && "Invalid inline asm flag");
if (UseOpIdx < FlagIdx+NumOps+1)
break;
}
if (FlagIdx >= UseOpIdx)
int FlagIdx = findInlineAsmFlagIdx(UseOpIdx);
if (FlagIdx < 0)
return false;
const MachineOperand &UFMO = getOperand(FlagIdx);
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {