diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-03-20 18:03:34 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-03-20 18:03:34 +0000 |
commit | 2e55923fba87e9f0f1b5841b6a164c207cc9004d (patch) | |
tree | 0ea18d2b90ffeaaaa94d20b5f79af1c562a69afa /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | |
parent | 4ed32352c94037831355486bd6f449e77910e5e7 (diff) | |
download | bcm5719-llvm-2e55923fba87e9f0f1b5841b6a164c207cc9004d.tar.gz bcm5719-llvm-2e55923fba87e9f0f1b5841b6a164c207cc9004d.zip |
For inline asm output operand that matches an input. Encode the input operand index in the high bits.
llvm-svn: 67387
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 0e8d9bee5ed..cbfdb793ede 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/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; } } |