initial selectiondag support for new INLINEASM node. Note that inline asms

with outputs or inputs are not supported yet. :)

llvm-svn: 25664
This commit is contained in:
Chris Lattner 2006-01-26 22:24:51 +00:00
parent 63041f7215
commit 476e67be14
3 changed files with 74 additions and 1 deletions

View File

@ -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<SDOperand> Ops(Node->op_begin(), Node->op_end());
Ops[0] = Tmp1;
Ops.back() = Tmp3;
std::vector<MVT::ValueType> 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.

View File

@ -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";

View File

@ -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<InlineAsm>(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<InlineAsm>(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<std::pair<InlineAsm::ConstraintPrefix, std::string> >
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<SDOperand> 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<MVT::ValueType> 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));