Fix support for inline asm input / output operand tying when operand spans across multiple registers (e.g. two i64 operands in 32-bit mode).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74053 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2009-06-24 02:05:51 +00:00
parent e56f4a49b7
commit ef5d070bbe
2 changed files with 42 additions and 11 deletions

View File

@ -716,31 +716,37 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
return false;
// Determine the actual operand no corresponding to this index.
// Determine the actual operand index that corresponds to this index.
unsigned DefNo = 0;
unsigned DefPart = 0;
for (unsigned i = 1, e = getNumOperands(); i < e; ) {
const MachineOperand &FMO = getOperand(i);
assert(FMO.isImm());
// Skip over this def.
i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
if (i > DefOpIdx)
unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
unsigned PrevDef = i + 1;
i = PrevDef + NumOps;
if (i > DefOpIdx) {
DefPart = DefOpIdx - PrevDef;
break;
}
++DefNo;
}
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
const MachineOperand &FMO = getOperand(i);
if (!FMO.isImm())
continue;
if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
continue;
unsigned Idx;
if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
Idx == DefNo) {
if (UseOpIdx)
*UseOpIdx = (unsigned)i + 1;
*UseOpIdx = (unsigned)i + 1 + DefPart;
return true;
}
}
return false;
}
assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
@ -766,10 +772,16 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
assert(UseOpIdx > 0);
const MachineOperand &UFMO = getOperand(UseOpIdx-1);
if (!UFMO.isImm())
return false; // Must be physreg uses.
int FlagIdx = UseOpIdx - 1;
if (FlagIdx < 1)
return false;
while (!getOperand(FlagIdx).isImm()) {
if (--FlagIdx == 0)
return false;
}
const MachineOperand &UFMO = getOperand(FlagIdx);
if (FlagIdx + InlineAsm::getNumOperandRegisters(UFMO.getImm()) < UseOpIdx)
return false;
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
if (!DefOpIdx)
@ -785,7 +797,7 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
--DefNo;
}
*DefOpIdx = DefIdx+1;
*DefOpIdx = DefIdx + UseOpIdx - FlagIdx;
return true;
}
return false;