aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-03-20 18:03:34 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-03-20 18:03:34 +0000
commit697cbbfb00c318f98d6eb51945f077e2bfe8781e (patch)
tree5e9badf081c1c2df5cee211ca2efe5451a07faf4 /lib/CodeGen/SelectionDAG
parente9d81f0ad8a7fa75776e1bc4cf396061d2ab041c (diff)
downloadexternal_llvm-697cbbfb00c318f98d6eb51945f077e2bfe8781e.zip
external_llvm-697cbbfb00c318f98d6eb51945f077e2bfe8781e.tar.gz
external_llvm-697cbbfb00c318f98d6eb51945f077e2bfe8781e.tar.bz2
For inline asm output operand that matches an input. Encode the input operand index in the high bits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67387 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp56
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp8
5 files changed, 43 insertions, 28 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index fd08ee6..888eeda 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1974,7 +1974,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
bool HasInFlag = Ops.back().getValueType() == MVT::Flag;
for (unsigned i = 2, e = Ops.size()-HasInFlag; i < e; ) {
- unsigned NumVals = cast<ConstantSDNode>(Ops[i])->getZExtValue() >> 3;
+ unsigned NumVals = InlineAsm::
+ getNumOperandRegisters(cast<ConstantSDNode>(Ops[i])->getZExtValue());
for (++i; NumVals; ++i, --NumVals) {
SDValue Op = LegalizeOp(Ops[i]);
if (Op != Ops[i]) {
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index b2f6ddf..7ae56d7 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -632,7 +632,7 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU,
for (unsigned i = 2; i != NumOps;) {
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
- unsigned NumVals = Flags >> 3;
+ unsigned NumVals = (Flags & 0xffff) >> 3;
++i; // Skip the ID value.
if ((Flags & 7) == 2 || (Flags & 7) == 6) {
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
index 5dfd5c3..4ad36da 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
@@ -561,7 +561,7 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
for (unsigned i = 2; i != NumOps;) {
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
- unsigned NumVals = Flags >> 3;
+ unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
MI->addOperand(MachineOperand::CreateImm(Flags));
++i; // Skip the ID value.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 0e8d9be..cbfdb79 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -228,10 +228,11 @@ namespace llvm {
SDValue &Chain, SDValue *Flag) const;
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
- /// operand list. This adds the code marker and includes the number of
- /// values added into it.
- void AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
- std::vector<SDValue> &Ops) const;
+ /// operand list. This adds the code marker, matching input operand index
+ /// (if applicable), and includes the number of values added into it.
+ void AddInlineAsmOperands(unsigned Code,
+ bool HasMatching, unsigned MatchingIdx,
+ SelectionDAG &DAG, std::vector<SDValue> &Ops) const;
};
}
@@ -4659,10 +4660,16 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker and includes the number of
/// values added into it.
-void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
+void RegsForValue::AddInlineAsmOperands(unsigned Code,
+ bool HasMatching,unsigned MatchingIdx,
+ SelectionDAG &DAG,
std::vector<SDValue> &Ops) const {
MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
- Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
+ assert(Regs.size() < (1 << 13) && "Too many inline asm outputs!");
+ unsigned Flag = Code | (Regs.size() << 3);
+ if (HasMatching)
+ Flag |= 0x80000000 | (MatchingIdx << 16);
+ Ops.push_back(DAG.getTargetConstant(Flag, IntPtrTy));
for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
unsigned NumRegs = TLI->getNumRegisters(ValueVTs[Value]);
MVT RegisterVT = RegVTs[Value];
@@ -5230,6 +5237,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
6 /* EARLYCLOBBER REGDEF */ :
2 /* REGDEF */ ,
+ OpInfo.hasMatchingInput(),
+ OpInfo.MatchingInput,
DAG, AsmNodeOperands);
break;
}
@@ -5246,25 +5255,26 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
unsigned CurOp = 2; // The first operand.
for (; OperandNo; --OperandNo) {
// Advance to the next operand.
- unsigned NumOps =
+ unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
- assert(((NumOps & 7) == 2 /*REGDEF*/ ||
- (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
- (NumOps & 7) == 4 /*MEM*/) &&
+ assert(((OpFlag & 7) == 2 /*REGDEF*/ ||
+ (OpFlag & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
+ (OpFlag & 7) == 4 /*MEM*/) &&
"Skipped past definitions?");
- CurOp += (NumOps>>3)+1;
+ CurOp += InlineAsm::getNumOperandRegisters(OpFlag)+1;
}
- unsigned NumOps =
+ unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
- if ((NumOps & 7) == 2 /*REGDEF*/
- || (NumOps & 7) == 6 /* EARLYCLOBBER REGDEF */) {
- // Add NumOps>>3 registers to MatchedRegs.
+ if ((OpFlag & 7) == 2 /*REGDEF*/
+ || (OpFlag & 7) == 6 /* EARLYCLOBBER REGDEF */) {
+ // Add (OpFlag&0xffff)>>3 registers to MatchedRegs.
RegsForValue MatchedRegs;
MatchedRegs.TLI = &TLI;
MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
MatchedRegs.RegVTs.push_back(AsmNodeOperands[CurOp+1].getValueType());
- for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
+ for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag);
+ i != e; ++i) {
unsigned Reg =
cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
MatchedRegs.Regs.push_back(Reg);
@@ -5273,13 +5283,15 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// Use the produced MatchedRegs object to
MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
- MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+ MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, false, 0,
+ DAG, AsmNodeOperands);
break;
} else {
- assert(((NumOps & 7) == 4) && "Unknown matching constraint!");
- assert((NumOps >> 3) == 1 && "Unexpected number of operands");
+ assert(((OpFlag & 7) == 4) && "Unknown matching constraint!");
+ assert((InlineAsm::getNumOperandRegisters(OpFlag)) == 1 &&
+ "Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
- AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps,
+ AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
TLI.getPointerTy()));
AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
break;
@@ -5334,7 +5346,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
- OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/,
+ OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, false, 0,
DAG, AsmNodeOperands);
break;
}
@@ -5343,7 +5355,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
// allocator is aware that the physreg got clobbered.
if (!OpInfo.AssignedRegs.Regs.empty())
OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
- DAG, AsmNodeOperands);
+ false, 0, DAG,AsmNodeOperands);
break;
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index fd2eb06..fdabd4c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1168,10 +1168,12 @@ SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
if ((Flags & 7) != 4 /*MEM*/) {
// Just skip over this operand, copying the operands verbatim.
- Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
- i += (Flags >> 3) + 1;
+ Ops.insert(Ops.end(), InOps.begin()+i,
+ InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
+ i += InlineAsm::getNumOperandRegisters(Flags) + 1;
} else {
- assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+ assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+ "Memory operand with multiple values?");
// Otherwise, this is a memory operand. Ask the target to select it.
std::vector<SDValue> SelOps;
if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {