mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
MC/AsmMatcher: Add support for creating tied operands when constructing MCInsts.
- Pretty messy, but we need to rework how we handle tied operands in MCInst anyway. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95774 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5dccfadbf4
commit
af61681ced
@ -944,10 +944,29 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
|||||||
OperandName.str() + "'");
|
OperandName.str() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
const CodeGenInstruction::OperandInfo &OI = II->Instr->OperandList[Idx];
|
// FIXME: This is annoying, the named operand may be tied (e.g.,
|
||||||
|
// XCHG8rm). What we want is the untied operand, which we now have to
|
||||||
|
// grovel for. Only worry about this for single entry operands, we have to
|
||||||
|
// clean this up anyway.
|
||||||
|
const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
|
||||||
|
if (OI->Constraints[0].isTied()) {
|
||||||
|
unsigned TiedOp = OI->Constraints[0].getTiedOperand();
|
||||||
|
|
||||||
|
// The tied operand index is an MIOperand index, find the operand that
|
||||||
|
// contains it.
|
||||||
|
for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
|
||||||
|
if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
|
||||||
|
OI = &II->Instr->OperandList[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(OI && "Unable to find tied operand target!");
|
||||||
|
}
|
||||||
|
|
||||||
InstructionInfo::Operand Op;
|
InstructionInfo::Operand Op;
|
||||||
Op.Class = getOperandClass(Token, OI);
|
Op.Class = getOperandClass(Token, *OI);
|
||||||
Op.OperandInfo = &OI;
|
Op.OperandInfo = OI;
|
||||||
II->Operands.push_back(Op);
|
II->Operands.push_back(Op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -996,6 +1015,19 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
if (Op.OperandInfo)
|
if (Op.OperandInfo)
|
||||||
MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
|
MIOperandList.push_back(std::make_pair(Op.OperandInfo->MIOperandNo, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find any tied operands.
|
||||||
|
SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
|
||||||
|
for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
|
||||||
|
const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
|
||||||
|
for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
|
||||||
|
const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
|
||||||
|
if (CI.isTied())
|
||||||
|
TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
|
||||||
|
CI.getTiedOperand()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::sort(MIOperandList.begin(), MIOperandList.end());
|
std::sort(MIOperandList.begin(), MIOperandList.end());
|
||||||
|
|
||||||
// Compute the total number of operands.
|
// Compute the total number of operands.
|
||||||
@ -1014,14 +1046,23 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
|
assert(CurIndex <= Op.OperandInfo->MIOperandNo &&
|
||||||
"Duplicate match for instruction operand!");
|
"Duplicate match for instruction operand!");
|
||||||
|
|
||||||
Signature += "_";
|
|
||||||
|
|
||||||
// Skip operands which weren't matched by anything, this occurs when the
|
// Skip operands which weren't matched by anything, this occurs when the
|
||||||
// .td file encodes "implicit" operands as explicit ones.
|
// .td file encodes "implicit" operands as explicit ones.
|
||||||
//
|
//
|
||||||
// FIXME: This should be removed from the MCInst structure.
|
// FIXME: This should be removed from the MCInst structure.
|
||||||
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
|
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
|
||||||
Signature += "Imp";
|
// See if this is a tied operand.
|
||||||
|
unsigned i, e = TiedOperands.size();
|
||||||
|
for (i = 0; i != e; ++i)
|
||||||
|
if (CurIndex == TiedOperands[i].first)
|
||||||
|
break;
|
||||||
|
if (i == e)
|
||||||
|
Signature += "__Imp";
|
||||||
|
else
|
||||||
|
Signature += "__Tie" + utostr(TiedOperands[i].second);
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature += "__";
|
||||||
|
|
||||||
// Registers are always converted the same, don't duplicate the conversion
|
// Registers are always converted the same, don't duplicate the conversion
|
||||||
// function based on them.
|
// function based on them.
|
||||||
@ -1060,8 +1101,25 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
|
InstructionInfo::Operand &Op = II.Operands[MIOperandList[i].second];
|
||||||
|
|
||||||
// Add the implicit operands.
|
// Add the implicit operands.
|
||||||
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
|
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex) {
|
||||||
CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
|
// See if this is a tied operand.
|
||||||
|
unsigned i, e = TiedOperands.size();
|
||||||
|
for (i = 0; i != e; ++i)
|
||||||
|
if (CurIndex == TiedOperands[i].first)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == e) {
|
||||||
|
// If not, this is some implicit operand. Just assume it is a register
|
||||||
|
// for now.
|
||||||
|
CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
|
||||||
|
} else {
|
||||||
|
// Copy the tied operand.
|
||||||
|
assert(TiedOperands[i].first > TiedOperands[i].second &&
|
||||||
|
"Tied operand preceeds its target!");
|
||||||
|
CvtOS << " Inst.addOperand(Inst.getOperand("
|
||||||
|
<< TiedOperands[i].second << "));\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CvtOS << " ((" << TargetOperandClass << "*)Operands["
|
CvtOS << " ((" << TargetOperandClass << "*)Operands["
|
||||||
<< MIOperandList[i].second
|
<< MIOperandList[i].second
|
||||||
|
Loading…
Reference in New Issue
Block a user