adjust to changes in InlineAsm interface. Fix a few minor bugs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25865 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-02-01 01:28:23 +00:00
parent e202a253b1
commit 2cc2f66c25
2 changed files with 42 additions and 32 deletions

View File

@ -472,4 +472,8 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
O << AsmStr << "\n"; O << AsmStr << "\n";
// Use a virtual "printAsmOperand" method, which takes the constraint
// string? Must pass the constraint string to here if needed.
} }

View File

@ -1156,8 +1156,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
// could not choose to not chain it. // could not choose to not chain it.
bool hasSideEffects = IA->hasSideEffects(); bool hasSideEffects = IA->hasSideEffects();
std::vector<std::pair<InlineAsm::ConstraintPrefix, std::string> > std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
Constraints = IA->ParseConstraints();
/// AsmNodeOperands - A list of pairs. The first element is a register, the /// 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 /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set
@ -1175,55 +1174,62 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
std::vector<std::pair<unsigned, Value*> > IndirectStoresToEmit; std::vector<std::pair<unsigned, Value*> > IndirectStoresToEmit;
unsigned OpNum = 1; unsigned OpNum = 1;
bool FoundOutputConstraint = false; bool FoundOutputConstraint = false;
//std::set<unsigned> OutputRegs;
//std::set<unsigned> InputRegs;
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
switch (Constraints[i].first) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");
case InlineAsm::isOutput: { std::string &ConstraintCode = Constraints[i].Codes[0];
assert(!FoundOutputConstraint && switch (Constraints[i].Type) {
"Cannot have multiple output constraints yet!"); case InlineAsm::isOutput: {
FoundOutputConstraint = true; bool isEarlyClobber = Constraints[i].isEarlyClobber;
assert(I.getType() != Type::VoidTy && "Bad inline asm!");
// Copy the output from the appropriate register. // Copy the output from the appropriate register.
std::vector<unsigned> Regs = std::vector<unsigned> Regs =
TLI.getRegForInlineAsmConstraint(Constraints[i].second); TLI.getRegForInlineAsmConstraint(ConstraintCode);
assert(Regs.size() == 1 && "Only handle simple regs right now!"); assert(Regs.size() == 1 && "Only handle simple regs right now!");
RetValReg = Regs[0]; unsigned DestReg = Regs[0];
const Type *OpTy;
if (!Constraints[i].isIndirectOutput) {
assert(!FoundOutputConstraint &&
"Cannot have multiple output constraints yet!");
FoundOutputConstraint = true;
assert(I.getType() != Type::VoidTy && "Bad inline asm!");
RetValReg = DestReg;
OpTy = I.getType();
} else {
IndirectStoresToEmit.push_back(std::make_pair(DestReg,
I.getOperand(OpNum)));
OpTy = I.getOperand(OpNum)->getType();
OpTy = cast<PointerType>(OpTy)->getElementType();
OpNum++; // Consumes a call operand.
}
// Add information to the INLINEASM node to know that this register is // Add information to the INLINEASM node to know that this register is
// set. // set.
AsmNodeOperands.push_back(DAG.getRegister(RetValReg, AsmNodeOperands.push_back(DAG.getRegister(DestReg,
TLI.getValueType(I.getType()))); TLI.getValueType(OpTy)));
AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF
break;
}
case InlineAsm::isIndirectOutput: {
// Copy the output from the appropriate register.
std::vector<unsigned> Regs =
TLI.getRegForInlineAsmConstraint(Constraints[i].second);
assert(Regs.size() == 1 && "Only handle simple regs right now!");
IndirectStoresToEmit.push_back(std::make_pair(Regs[0],
I.getOperand(OpNum)));
OpNum++; // Consumes a call operand.
// Add information to the INLINEASM node to know that this register is
// set.
AsmNodeOperands.push_back(DAG.getRegister(Regs[0],
TLI.getValueType(I.getType())));
AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF
break; break;
} }
case InlineAsm::isInput: { case InlineAsm::isInput: {
Value *Operand = I.getOperand(OpNum);
const Type *OpTy = Operand->getType();
// Copy the input into the appropriate register. // Copy the input into the appropriate register.
std::vector<unsigned> Regs = std::vector<unsigned> Regs =
TLI.getRegForInlineAsmConstraint(Constraints[i].second); TLI.getRegForInlineAsmConstraint(ConstraintCode);
assert(Regs.size() == 1 && "Only handle simple regs right now!"); assert(Regs.size() == 1 && "Only handle simple regs right now!");
Chain = DAG.getCopyToReg(Chain, Regs[0], unsigned SrcReg = Regs[0];
getValue(I.getOperand(OpNum)), Flag); Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag);
Flag = Chain.getValue(1); Flag = Chain.getValue(1);
// Add information to the INLINEASM node to know that this register is // Add information to the INLINEASM node to know that this register is
// read. // read.
AsmNodeOperands.push_back(DAG.getRegister(Regs[0], AsmNodeOperands.push_back(DAG.getRegister(SrcReg,TLI.getValueType(OpTy)));
TLI.getValueType(I.getType())));
AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE
break; break;
} }