diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 933aa70e887..73109004d10 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -881,6 +881,28 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 1), Tmp2); return Op.ResNo ? Tmp2 : Tmp1; } + case ISD::INLINEASM: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize Chain. + Tmp2 = Node->getOperand(Node->getNumOperands()-1); + if (Tmp2.getValueType() != MVT::Flag) // Legalize Flag if it exists. + Tmp2 = Tmp3 = SDOperand(0, 0); + else + Tmp3 = LegalizeOp(Tmp2); + + if (Tmp1 != Node->getOperand(0) || Tmp2 != Tmp3) { + std::vector Ops(Node->op_begin(), Node->op_end()); + Ops[0] = Tmp1; + Ops.back() = Tmp3; + std::vector VTs(Node->value_begin(), Node->value_end()); + Result = DAG.getNode(ISD::INLINEASM, VTs, Ops); + } else { + Result = SDOperand(Node, 0); + } + + // INLINE asm returns a chain and flag, make sure to add both to the map. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); case ISD::TAILCALL: case ISD::CALL: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d864042537f..60f062847fc 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2028,7 +2028,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::CopyFromReg: return "CopyFromReg"; case ISD::UNDEF: return "undef"; case ISD::MERGE_VALUES: return "mergevalues"; - + case ISD::INLINEASM: return "inlineasm"; + // Unary operators case ISD::FABS: return "fabs"; case ISD::FNEG: return "fneg"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index f75bdbeba7c..5f16af6571c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -19,6 +19,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/CodeGen/IntrinsicLowering.h" @@ -468,6 +469,7 @@ public: void visitStore(StoreInst &I); void visitPHI(PHINode &I) { } // PHI nodes are handled specially. void visitCall(CallInst &I); + void visitInlineAsm(CallInst &I); const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic); void visitVAStart(CallInst &I); @@ -1122,6 +1124,9 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } } + } else if (isa(I.getOperand(0))) { + visitInlineAsm(I); + return; } SDOperand Callee; @@ -1148,6 +1153,51 @@ void SelectionDAGLowering::visitCall(CallInst &I) { DAG.setRoot(Result.second); } +/// visitInlineAsm - Handle a call to an InlineAsm object. +/// +void SelectionDAGLowering::visitInlineAsm(CallInst &I) { + InlineAsm *IA = cast(I.getOperand(0)); + + SDOperand AsmStr = DAG.getTargetExternalSymbol(IA->getAsmString().c_str(), + MVT::Other); + + // Note, we treat inline asms both with and without side-effects as the same. + // If an inline asm doesn't have side effects and doesn't access memory, we + // could not choose to not chain it. + bool hasSideEffects = IA->hasSideEffects(); + + std::vector > + Constraints = IA->ParseConstraints(); + + + /// AsmNodeOperands - A list of pairs. The first element is a register, the + /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set + /// if it is a def of that register. + std::vector AsmNodeOperands; + AsmNodeOperands.push_back(SDOperand()); // reserve space for input chain + AsmNodeOperands.push_back(AsmStr); + + SDOperand Chain = getRoot(); + SDOperand Flag; + + // FIXME: input copies. + + // Finish up input operands. + AsmNodeOperands[0] = Chain; + if (Flag.Val) AsmNodeOperands.push_back(Flag); + + std::vector VTs; + VTs.push_back(MVT::Other); + VTs.push_back(MVT::Flag); + Chain = DAG.getNode(ISD::INLINEASM, VTs, AsmNodeOperands); + Flag = Chain.getValue(1); + + // FIXME: Copies out of registers here, setValue(CI). + + DAG.setRoot(Chain); +} + + void SelectionDAGLowering::visitMalloc(MallocInst &I) { SDOperand Src = getValue(I.getOperand(0));