summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-29 22:02:00 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-29 22:02:00 +0000
commit66390805ad58871cde3f5ccd72a7dcac9b1cd4d8 (patch)
tree49b462a63e96ed6aad356af2e9121a6660c87962 /lib/CodeGen/SelectionDAG/InstrEmitter.cpp
parentb1b97833aeaf8a7ef6dd3b314a502a1521b02657 (diff)
downloadllvm-66390805ad58871cde3f5ccd72a7dcac9b1cd4d8.tar.gz
llvm-66390805ad58871cde3f5ccd72a7dcac9b1cd4d8.tar.bz2
llvm-66390805ad58871cde3f5ccd72a7dcac9b1cd4d8.tar.xz
Set the isTied flags when building INLINEASM MachineInstrs.
For normal instructions, isTied() is set automatically by addOperand(), based on MCInstrDesc, but inline asm has tied operands outside the descriptor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162869 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/InstrEmitter.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index f8f1b05099..5927838b53 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -893,19 +893,23 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
getZExtValue();
MI->addOperand(MachineOperand::CreateImm(ExtraInfo));
+ // Remember to operand index of the group flags.
+ SmallVector<unsigned, 8> GroupIdx;
+
// Add all of the operand registers to the instruction.
for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
- unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
+ const unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
+ GroupIdx.push_back(MI->getNumOperands());
MI->addOperand(MachineOperand::CreateImm(Flags));
++i; // Skip the ID value.
switch (InlineAsm::getKind(Flags)) {
default: llvm_unreachable("Bad flags!");
case InlineAsm::Kind_RegDef:
- for (; NumVals; --NumVals, ++i) {
+ for (unsigned j = 0; j != NumVals; ++j, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
// FIXME: Add dead flags for physical and virtual registers defined.
// For now, mark physical register defs as implicit to help fast
@@ -916,7 +920,7 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
break;
case InlineAsm::Kind_RegDefEarlyClobber:
case InlineAsm::Kind_Clobber:
- for (; NumVals; --NumVals, ++i) {
+ for (unsigned j = 0; j != NumVals; ++j, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
MI->addOperand(MachineOperand::CreateReg(Reg, /*isDef=*/ true,
/*isImp=*/ TargetRegisterInfo::isPhysicalRegister(Reg),
@@ -931,9 +935,22 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
case InlineAsm::Kind_Mem: // Addressing mode.
// The addressing mode has been selected, just add all of the
// operands to the machine instruction.
- for (; NumVals; --NumVals, ++i)
+ for (unsigned j = 0; j != NumVals; ++j, ++i)
AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap,
/*IsDebug=*/false, IsClone, IsCloned);
+
+ // Manually set isTied bits.
+ if (InlineAsm::getKind(Flags) == InlineAsm::Kind_RegUse) {
+ unsigned DefGroup = 0;
+ if (InlineAsm::isUseOperandTiedToDef(Flags, DefGroup)) {
+ unsigned DefIdx = GroupIdx[DefGroup] + 1;
+ unsigned UseIdx = GroupIdx.back() + 1;
+ for (unsigned j = 0; j != NumVals; ++j) {
+ MI->getOperand(DefIdx + j).setIsTied();
+ MI->getOperand(UseIdx + j).setIsTied();
+ }
+ }
+ }
break;
}
}