mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Fix pr3954. The register scavenger asserts for inline assembly with
register destinations that are tied to source operands. The TargetInstrDescr::findTiedToSrcOperand method silently fails for inline assembly. The existing MachineInstr::isRegReDefinedByTwoAddr was very close to doing what is needed, so this revision makes a few changes to that method and also renames it to isRegTiedToUseOperand (for consistency with the very similar isRegTiedToDefOperand and because it handles both two-address instructions and inline assembly with tied registers). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68714 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -690,12 +690,14 @@ int MachineInstr::findFirstPredOperandIdx() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// isRegReDefinedByTwoAddr - Given the index of a register operand,
|
||||
/// check if the register def is a re-definition due to two addr elimination.
|
||||
bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) 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
|
||||
/// first tied use operand index by reference is UseOpIdx is not null.
|
||||
bool MachineInstr::isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx){
|
||||
if (getOpcode() == TargetInstrInfo::INLINEASM) {
|
||||
assert(DefIdx >= 2);
|
||||
const MachineOperand &MO = getOperand(DefIdx);
|
||||
assert(DefOpIdx >= 2);
|
||||
const MachineOperand &MO = getOperand(DefOpIdx);
|
||||
if (!MO.isReg() || !MO.isDef())
|
||||
return false;
|
||||
// Determine the actual operand no corresponding to this index.
|
||||
@@ -705,7 +707,7 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
|
||||
assert(FMO.isImm());
|
||||
// Skip over this def.
|
||||
i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
|
||||
if (i > DefIdx)
|
||||
if (i > DefOpIdx)
|
||||
break;
|
||||
++DefNo;
|
||||
}
|
||||
@@ -717,18 +719,24 @@ bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
|
||||
continue;
|
||||
unsigned Idx;
|
||||
if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
|
||||
Idx == DefNo)
|
||||
Idx == DefNo) {
|
||||
if (UseOpIdx)
|
||||
*UseOpIdx = (unsigned)i + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!");
|
||||
assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
|
||||
const TargetInstrDesc &TID = getDesc();
|
||||
for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = getOperand(i);
|
||||
if (MO.isReg() && MO.isUse() &&
|
||||
TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefIdx)
|
||||
TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefOpIdx) {
|
||||
if (UseOpIdx)
|
||||
*UseOpIdx = (unsigned)i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user