Fix build with LLVM ToT

This commit is contained in:
Matt Pharr
2012-05-18 10:09:09 -07:00
parent 299ae186f1
commit 8d3ac3ac1e

View File

@@ -337,8 +337,6 @@ namespace {
bool IsVolatile, unsigned Alignment); bool IsVolatile, unsigned Alignment);
private : private :
std::string InterpretASMConstraint(InlineAsm::ConstraintInfo& c);
void lowerIntrinsics(Function &F); void lowerIntrinsics(Function &F);
/// Prints the definition of the intrinsic function F. Supports the /// Prints the definition of the intrinsic function F. Supports the
/// intrinsics which need to be explicitly defined in the CBackend. /// intrinsics which need to be explicitly defined in the CBackend.
@@ -3801,181 +3799,11 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID,
} }
} }
//This converts the llvm constraint string to something gcc is expecting.
//TODO: work out platform independent constraints and factor those out
// of the per target tables
// handle multiple constraint codes
std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) {
assert(c.Codes.size() == 1 && "Too many asm constraint codes to handle");
// Grab the translation table from MCAsmInfo if it exists.
const MCAsmInfo *TargetAsm;
std::string Triple = TheModule->getTargetTriple();
if (Triple.empty())
#ifdef LLVM_3_0
Triple = llvm::sys::getHostTriple();
#else
Triple = llvm::sys::getDefaultTargetTriple();
#endif
std::string E;
if (const llvm::Target *Match = TargetRegistry::lookupTarget(Triple, E))
TargetAsm = Match->createMCAsmInfo(Triple);
else
return c.Codes[0];
const char *const *table = TargetAsm->getAsmCBE();
// Search the translation table if it exists.
for (int i = 0; table && table[i]; i += 2)
if (c.Codes[0] == table[i]) {
delete TargetAsm;
return table[i+1];
}
// Default is identity.
delete TargetAsm;
return c.Codes[0];
}
//TODO: import logic from AsmPrinter.cpp
static std::string gccifyAsm(std::string asmstr) {
for (std::string::size_type i = 0; i != asmstr.size(); ++i)
if (asmstr[i] == '\n')
asmstr.replace(i, 1, "\\n");
else if (asmstr[i] == '\t')
asmstr.replace(i, 1, "\\t");
else if (asmstr[i] == '$') {
if (asmstr[i + 1] == '{') {
std::string::size_type a = asmstr.find_first_of(':', i + 1);
std::string::size_type b = asmstr.find_first_of('}', i + 1);
std::string n = "%" +
asmstr.substr(a + 1, b - a - 1) +
asmstr.substr(i + 2, a - i - 2);
asmstr.replace(i, b - i + 1, n);
i += n.size() - 1;
} else
asmstr.replace(i, 1, "%");
}
else if (asmstr[i] == '%')//grr
{ asmstr.replace(i, 1, "%%"); ++i;}
return asmstr;
}
//TODO: assumptions about what consume arguments from the call are likely wrong //TODO: assumptions about what consume arguments from the call are likely wrong
// handle communitivity // handle communitivity
void CWriter::visitInlineAsm(CallInst &CI) { void CWriter::visitInlineAsm(CallInst &CI) {
InlineAsm* as = cast<InlineAsm>(CI.getCalledValue()); assert(!"Inline assembly not supported");
InlineAsm::ConstraintInfoVector Constraints = as->ParseConstraints();
std::vector<std::pair<Value*, int> > ResultVals;
if (CI.getType() == Type::getVoidTy(CI.getContext()))
;
else if (StructType *ST = dyn_cast<StructType>(CI.getType())) {
for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i)
ResultVals.push_back(std::make_pair(&CI, (int)i));
} else {
ResultVals.push_back(std::make_pair(&CI, -1));
}
// Fix up the asm string for gcc and emit it.
Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n";
Out << " :";
unsigned ValueCount = 0;
bool IsFirst = true;
// Convert over all the output constraints.
for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),
E = Constraints.end(); I != E; ++I) {
if (I->Type != InlineAsm::isOutput) {
++ValueCount;
continue; // Ignore non-output constraints.
}
assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
std::string C = InterpretASMConstraint(*I);
if (C.empty()) continue;
if (!IsFirst) {
Out << ", ";
IsFirst = false;
}
// Unpack the dest.
Value *DestVal;
int DestValNo = -1;
if (ValueCount < ResultVals.size()) {
DestVal = ResultVals[ValueCount].first;
DestValNo = ResultVals[ValueCount].second;
} else
DestVal = CI.getArgOperand(ValueCount-ResultVals.size());
if (I->isEarlyClobber)
C = "&"+C;
Out << "\"=" << C << "\"(" << GetValueName(DestVal);
if (DestValNo != -1)
Out << ".field" << DestValNo; // Multiple retvals.
Out << ")";
++ValueCount;
}
// Convert over all the input constraints.
Out << "\n :";
IsFirst = true;
ValueCount = 0;
for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),
E = Constraints.end(); I != E; ++I) {
if (I->Type != InlineAsm::isInput) {
++ValueCount;
continue; // Ignore non-input constraints.
}
assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
std::string C = InterpretASMConstraint(*I);
if (C.empty()) continue;
if (!IsFirst) {
Out << ", ";
IsFirst = false;
}
assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
Value *SrcVal = CI.getArgOperand(ValueCount-ResultVals.size());
Out << "\"" << C << "\"(";
if (!I->isIndirect)
writeOperand(SrcVal);
else
writeOperandDeref(SrcVal);
Out << ")";
}
// Convert over the clobber constraints.
IsFirst = true;
for (InlineAsm::ConstraintInfoVector::iterator I = Constraints.begin(),
E = Constraints.end(); I != E; ++I) {
if (I->Type != InlineAsm::isClobber)
continue; // Ignore non-input constraints.
assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
std::string C = InterpretASMConstraint(*I);
if (C.empty()) continue;
if (!IsFirst) {
Out << ", ";
IsFirst = false;
}
Out << '\"' << C << '"';
}
Out << ")";
} }
void CWriter::visitAllocaInst(AllocaInst &I) { void CWriter::visitAllocaInst(AllocaInst &I) {