diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-02-24 02:13:54 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-02-24 02:13:54 +0000 |
| commit | dcf785bf46266fc48657c6395309a0981c8f09e2 (patch) | |
| tree | 98618721fd6b4cdfbd5d43c27d3bad619b51d591 /llvm/lib/CodeGen/SelectionDAG | |
| parent | dc445eadc00ae3fe3f1698725b6c9c27d71cdbaa (diff) | |
| download | bcm5719-llvm-dcf785bf46266fc48657c6395309a0981c8f09e2.tar.gz bcm5719-llvm-dcf785bf46266fc48657c6395309a0981c8f09e2.zip | |
Implement (most of) selection of inline asm memory operands.
llvm-svn: 26350
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index aa8bbee3dd0..a6e3fd0388f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2437,3 +2437,45 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { BB = SL->Run(); delete SL; } + +/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated +/// by tblgen. Others should not call it. +void SelectionDAGISel:: +SelectInlineAsmMemoryOperands(std::vector<SDOperand> &Ops, SelectionDAG &DAG) { + std::vector<SDOperand> InOps; + std::swap(InOps, Ops); + + Ops.push_back(InOps[0]); // input chain. + Ops.push_back(InOps[1]); // input asm string. + + const char *AsmStr = cast<ExternalSymbolSDNode>(InOps[1])->getSymbol(); + unsigned i = 2, e = InOps.size(); + if (InOps[e-1].getValueType() == MVT::Flag) + --e; // Don't process a flag operand if it is here. + + while (i != e) { + unsigned Flags = cast<ConstantSDNode>(InOps[i])->getValue(); + 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; + } else { + assert((Flags >> 3) == 1 && "Memory operand with multiple values?"); + // Otherwise, this is a memory operand. Ask the target to select it. + std::vector<SDOperand> SelOps; + if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps, DAG)) { + std::cerr << "Could not match memory address. Inline asm failure!\n"; + exit(1); + } + + // Add this to the output node. + Ops.push_back(DAG.getConstant(4/*MEM*/ | (SelOps.size() << 3), MVT::i32)); + Ops.insert(Ops.end(), SelOps.begin(), SelOps.end()); + i += 2; + } + } + + // Add the flag input back if present. + if (e != InOps.size()) + Ops.push_back(InOps.back()); +} |

