#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
// Register the target.
-static RegisterTarget<CTargetMachine> X("c", "C backend");
+static RegisterTarget<CTargetMachine> X(TheCBackendTarget, "c", "C backend");
+
+// Force static initialization.
+extern "C" void LLVMInitializeCBackendTarget() { }
namespace {
/// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for
/// CWriter - This class is the main chunk of code that converts an LLVM
/// module to a C translation unit.
class CWriter : public FunctionPass, public InstVisitor<CWriter> {
- raw_ostream &Out;
+ formatted_raw_ostream &Out;
IntrinsicLowering *IL;
Mangler *Mang;
LoopInfo *LI;
std::map<const ConstantFP *, unsigned> FPConstantMap;
std::set<Function*> intrinsicPrototypesAlreadyGenerated;
std::set<const Argument*> ByValParams;
+ unsigned FPCounter;
+ unsigned OpaqueCounter;
+ DenseMap<const Value*, unsigned> AnonValueNumbers;
+ unsigned NextAnonValueNumber;
public:
static char ID;
- explicit CWriter(raw_ostream &o)
+ explicit CWriter(formatted_raw_ostream &o)
: FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0),
- TheModule(0), TAsm(0), TD(0) {}
+ TheModule(0), TAsm(0), TD(0), OpaqueCounter(0), NextAnonValueNumber(0) {
+ FPCounter = 0;
+ }
virtual const char *getPassName() const { return "C backend"; }
virtual bool doInitialization(Module &M);
bool runOnFunction(Function &F) {
+ // Do not codegen any 'available_externally' functions at all, they have
+ // definitions outside the translation unit.
+ if (F.hasAvailableExternallyLinkage())
+ return false;
+
LI = &getAnalysis<LoopInfo>();
// Get rid of intrinsics we can't handle.
virtual bool doFinalization(Module &M) {
// Free memory...
+ delete IL;
+ delete TD;
delete Mang;
FPConstantMap.clear();
TypeNames.clear();
return false;
}
- raw_ostream &printType(raw_ostream &Out, const Type *Ty,
- bool isSigned = false,
- const std::string &VariableName = "",
- bool IgnoreName = false,
- const AttrListPtr &PAL = AttrListPtr());
+ raw_ostream &printType(formatted_raw_ostream &Out,
+ const Type *Ty,
+ bool isSigned = false,
+ const std::string &VariableName = "",
+ bool IgnoreName = false,
+ const AttrListPtr &PAL = AttrListPtr());
std::ostream &printType(std::ostream &Out, const Type *Ty,
bool isSigned = false,
const std::string &VariableName = "",
bool IgnoreName = false,
const AttrListPtr &PAL = AttrListPtr());
- raw_ostream &printSimpleType(raw_ostream &Out, const Type *Ty,
- bool isSigned,
- const std::string &NameSoFar = "");
+ raw_ostream &printSimpleType(formatted_raw_ostream &Out,
+ const Type *Ty,
+ bool isSigned,
+ const std::string &NameSoFar = "");
std::ostream &printSimpleType(std::ostream &Out, const Type *Ty,
bool isSigned,
const std::string &NameSoFar = "");
- void printStructReturnPointerFunctionType(raw_ostream &Out,
+ void printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
const AttrListPtr &PAL,
const PointerType *Ty);
void printModuleTypes(const TypeSymbolTable &ST);
void printContainedStructs(const Type *Ty, std::set<const Type *> &);
void printFloatingPointConstants(Function &F);
+ void printFloatingPointConstants(const Constant *C);
void printFunctionSignature(const Function *F, bool Prototype);
void printFunction(Function &);
void visitBranchInst(BranchInst &I);
void visitSwitchInst(SwitchInst &I);
void visitInvokeInst(InvokeInst &I) {
- assert(0 && "Lowerinvoke pass didn't work!");
+ llvm_unreachable("Lowerinvoke pass didn't work!");
}
void visitUnwindInst(UnwindInst &I) {
- assert(0 && "Lowerinvoke pass didn't work!");
+ llvm_unreachable("Lowerinvoke pass didn't work!");
}
void visitUnreachableInst(UnreachableInst &I);
void visitExtractValueInst(ExtractValueInst &I);
void visitInstruction(Instruction &I) {
+#ifndef NDEBUG
cerr << "C Writer does not know about " << I;
- abort();
+#endif
+ llvm_unreachable(0);
}
void outputLValue(Instruction *I) {
/// printStructReturnPointerFunctionType - This is like printType for a struct
/// return type, except, instead of printing the type as void (*)(Struct*, ...)
/// print it as "Struct (*)(...)", for struct return functions.
-void CWriter::printStructReturnPointerFunctionType(raw_ostream &Out,
+void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out,
const AttrListPtr &PAL,
const PointerType *TheTy) {
const FunctionType *FTy = cast<FunctionType>(TheTy->getElementType());
}
raw_ostream &
-CWriter::printSimpleType(raw_ostream &Out, const Type *Ty, bool isSigned,
+CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty,
+ bool isSigned,
const std::string &NameSoFar) {
assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) &&
"Invalid type for printSimpleType");
const VectorType *VTy = cast<VectorType>(Ty);
return printSimpleType(Out, VTy->getElementType(), isSigned,
" __attribute__((vector_size(" +
- utostr(TD->getABITypeSize(VTy)) + " ))) " + NameSoFar);
+ utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar);
}
default:
+#ifndef NDEBUG
cerr << "Unknown primitive type: " << *Ty << "\n";
- abort();
+#endif
+ llvm_unreachable(0);
}
}
const VectorType *VTy = cast<VectorType>(Ty);
return printSimpleType(Out, VTy->getElementType(), isSigned,
" __attribute__((vector_size(" +
- utostr(TD->getABITypeSize(VTy)) + " ))) " + NameSoFar);
+ utostr(TD->getTypeAllocSize(VTy)) + " ))) " + NameSoFar);
}
default:
+#ifndef NDEBUG
cerr << "Unknown primitive type: " << *Ty << "\n";
- abort();
+#endif
+ llvm_unreachable(0);
}
}
// Pass the Type* and the variable name and this prints out the variable
// declaration.
//
-raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty,
- bool isSigned, const std::string &NameSoFar,
- bool IgnoreName, const AttrListPtr &PAL) {
+raw_ostream &CWriter::printType(formatted_raw_ostream &Out,
+ const Type *Ty,
+ bool isSigned, const std::string &NameSoFar,
+ bool IgnoreName, const AttrListPtr &PAL) {
if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
}
case Type::OpaqueTyID: {
- static int Count = 0;
- std::string TyName = "struct opaque_" + itostr(Count++);
+ std::string TyName = "struct opaque_" + itostr(OpaqueCounter++);
assert(TypeNames.find(Ty) == TypeNames.end());
TypeNames[Ty] = TyName;
return Out << TyName << ' ' << NameSoFar;
}
default:
- assert(0 && "Unhandled case in getTypeProps!");
- abort();
+ llvm_unreachable("Unhandled case in getTypeProps!");
}
return Out;
}
case Type::OpaqueTyID: {
- static int Count = 0;
- std::string TyName = "struct opaque_" + itostr(Count++);
+ std::string TyName = "struct opaque_" + itostr(OpaqueCounter++);
assert(TypeNames.find(Ty) == TypeNames.end());
TypeNames[Ty] = TyName;
return Out << TyName << ' ' << NameSoFar;
}
default:
- assert(0 && "Unhandled case in getTypeProps!");
- abort();
+ llvm_unreachable("Unhandled case in getTypeProps!");
}
return Out;
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
bool ignored;
// Do long doubles in hex for now.
- if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
+ if (CFP->getType() != Type::FloatTy && CFP->getType() != Type::DoubleTy)
return false;
APFloat APF = APFloat(CFP->getValueAPF()); // copy
- if (CFP->getType()==Type::FloatTy)
+ if (CFP->getType() == Type::FloatTy)
APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
#if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
char Buffer[100];
Out << ')';
break;
default:
- assert(0 && "Invalid cast opcode");
+ llvm_unreachable("Invalid cast opcode");
}
// Print the source type cast
case Instruction::FPToUI:
break; // These don't need a source cast.
default:
- assert(0 && "Invalid cast opcode");
+ llvm_unreachable("Invalid cast opcode");
break;
}
}
Out << ')';
return;
case Instruction::Add:
+ case Instruction::FAdd:
case Instruction::Sub:
+ case Instruction::FSub:
case Instruction::Mul:
+ case Instruction::FMul:
case Instruction::SDiv:
case Instruction::UDiv:
case Instruction::FDiv:
bool NeedsClosingParens = printConstExprCast(CE, Static);
printConstantWithCast(CE->getOperand(0), CE->getOpcode());
switch (CE->getOpcode()) {
- case Instruction::Add: Out << " + "; break;
- case Instruction::Sub: Out << " - "; break;
- case Instruction::Mul: Out << " * "; break;
+ case Instruction::Add:
+ case Instruction::FAdd: Out << " + "; break;
+ case Instruction::Sub:
+ case Instruction::FSub: Out << " - "; break;
+ case Instruction::Mul:
+ case Instruction::FMul: Out << " * "; break;
case Instruction::URem:
case Instruction::SRem:
case Instruction::FRem: Out << " % "; break;
case ICmpInst::ICMP_UGT: Out << " > "; break;
case ICmpInst::ICMP_SGE:
case ICmpInst::ICMP_UGE: Out << " >= "; break;
- default: assert(0 && "Illegal ICmp predicate");
+ default: llvm_unreachable("Illegal ICmp predicate");
}
break;
- default: assert(0 && "Illegal opcode here!");
+ default: llvm_unreachable("Illegal opcode here!");
}
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
if (NeedsClosingParens)
else {
const char* op = 0;
switch (CE->getPredicate()) {
- default: assert(0 && "Illegal FCmp predicate");
+ default: llvm_unreachable("Illegal FCmp predicate");
case FCmpInst::FCMP_ORD: op = "ord"; break;
case FCmpInst::FCMP_UNO: op = "uno"; break;
case FCmpInst::FCMP_UEQ: op = "ueq"; break;
return;
}
default:
+#ifndef NDEBUG
cerr << "CWriter Error: Unhandled constant expression: "
<< *CE << "\n";
- abort();
+#endif
+ llvm_unreachable(0);
}
} else if (isa<UndefValue>(CPV) && CPV->getType()->isSingleValueType()) {
Out << "((";
Out << CI->getZExtValue() << 'u';
else
Out << CI->getSExtValue();
- Out << ')';
+ Out << ')';
}
return;
}
"long double")
<< "*)&FPConstant" << I->second << ')';
} else {
- assert(FPC->getType() == Type::FloatTy ||
- FPC->getType() == Type::DoubleTy);
- double V = FPC->getType() == Type::FloatTy ?
- FPC->getValueAPF().convertToFloat() :
- FPC->getValueAPF().convertToDouble();
+ double V;
+ if (FPC->getType() == Type::FloatTy)
+ V = FPC->getValueAPF().convertToFloat();
+ else if (FPC->getType() == Type::DoubleTy)
+ V = FPC->getValueAPF().convertToDouble();
+ else {
+ // Long double. Convert the number to double, discarding precision.
+ // This is not awesome, but it at least makes the CBE output somewhat
+ // useful.
+ APFloat Tmp = FPC->getValueAPF();
+ bool LosesInfo;
+ Tmp.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &LosesInfo);
+ V = Tmp.convertToDouble();
+ }
+
if (IsNAN(V)) {
// The value is NaN
Out << '{';
if (AT->getNumElements()) {
Out << ' ';
- Constant *CZ = Constant::getNullValue(AT->getElementType());
+ Constant *CZ = CPV->getContext().getNullValue(AT->getElementType());
printConstant(CZ, Static);
for (unsigned i = 1, e = AT->getNumElements(); i != e; ++i) {
Out << ", ";
assert(isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV));
const VectorType *VT = cast<VectorType>(CPV->getType());
Out << "{ ";
- Constant *CZ = Constant::getNullValue(VT->getElementType());
+ Constant *CZ = CPV->getContext().getNullValue(VT->getElementType());
printConstant(CZ, Static);
for (unsigned i = 1, e = VT->getNumElements(); i != e; ++i) {
Out << ", ";
Out << '{';
if (ST->getNumElements()) {
Out << ' ';
- printConstant(Constant::getNullValue(ST->getElementType(0)), Static);
+ printConstant(
+ CPV->getContext().getNullValue(ST->getElementType(0)), Static);
for (unsigned i = 1, e = ST->getNumElements(); i != e; ++i) {
Out << ", ";
- printConstant(Constant::getNullValue(ST->getElementType(i)), Static);
+ printConstant(
+ CPV->getContext().getNullValue(ST->getElementType(i)), Static);
}
}
Out << " }";
}
// FALL THROUGH
default:
+#ifndef NDEBUG
cerr << "Unknown constant type: " << *CPV << "\n";
- abort();
+#endif
+ llvm_unreachable(0);
}
}
case Instruction::Mul:
// We need to cast integer arithmetic so that it is always performed
// as unsigned, to avoid undefined behavior on overflow.
- if (!Ty->isIntOrIntVector()) break;
- // FALL THROUGH
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv: NeedsExplicitCast = true; break;
case Instruction::Mul:
// We need to cast integer arithmetic so that it is always performed
// as unsigned, to avoid undefined behavior on overflow.
- if (!OpTy->isIntOrIntVector()) break;
- // FALL THROUGH
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem:
}
std::string CWriter::GetValueName(const Value *Operand) {
- std::string Name;
-
- if (!isa<GlobalValue>(Operand) && Operand->getName() != "") {
- std::string VarName;
-
- Name = Operand->getName();
- VarName.reserve(Name.capacity());
-
- for (std::string::iterator I = Name.begin(), E = Name.end();
- I != E; ++I) {
- char ch = *I;
+ // Mangle globals with the standard mangler interface for LLC compatibility.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand))
+ return Mang->getMangledName(GV);
+
+ std::string Name = Operand->getName();
+
+ if (Name.empty()) { // Assign unique names to local temporaries.
+ unsigned &No = AnonValueNumbers[Operand];
+ if (No == 0)
+ No = ++NextAnonValueNumber;
+ Name = "tmp__" + utostr(No);
+ }
+
+ std::string VarName;
+ VarName.reserve(Name.capacity());
- if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') || ch == '_')) {
- char buffer[5];
- sprintf(buffer, "_%x_", ch);
- VarName += buffer;
- } else
- VarName += ch;
- }
+ for (std::string::iterator I = Name.begin(), E = Name.end();
+ I != E; ++I) {
+ char ch = *I;
- Name = "llvm_cbe_" + VarName;
- } else {
- Name = Mang->getValueName(Operand);
+ if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') || ch == '_')) {
+ char buffer[5];
+ sprintf(buffer, "_%x_", ch);
+ VarName += buffer;
+ } else
+ VarName += ch;
}
- return Name;
+ return "llvm_cbe_" + VarName;
}
/// writeInstComputationInline - Emit the computation for the specified
/// instruction inline, with no destination provided.
void CWriter::writeInstComputationInline(Instruction &I) {
+ // We can't currently support integer types other than 1, 8, 16, 32, 64.
+ // Validate this.
+ const Type *Ty = I.getType();
+ if (Ty->isInteger() && (Ty!=Type::Int1Ty && Ty!=Type::Int8Ty &&
+ Ty!=Type::Int16Ty && Ty!=Type::Int32Ty && Ty!=Type::Int64Ty)) {
+ llvm_report_error("The C backend does not currently support integer "
+ "types of widths other than 1, 8, 16, 32, 64.\n"
+ "This is being tracked as PR 4158.");
+ }
+
// If this is a non-trivial bool computation, make sure to truncate down to
// a 1 bit value. This is important because we want "add i1 x, y" to return
// "0" when x and y are true, not "2" for example.
case Instruction::Mul:
// We need to cast integer arithmetic so that it is always performed
// as unsigned, to avoid undefined behavior on overflow.
- if (!Ty->isIntOrIntVector()) break;
- // FALL THROUGH
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv:
case Instruction::Mul:
// We need to cast integer arithmetic so that it is always performed
// as unsigned, to avoid undefined behavior on overflow.
- if (!OpTy->isIntOrIntVector()) break;
- // FALL THROUGH
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem: // Cast to unsigned first
// generateCompilerSpecificCode - This is where we add conditional compilation
// directives to cater to specific compilers as need be.
//
-static void generateCompilerSpecificCode(raw_ostream& Out,
+static void generateCompilerSpecificCode(formatted_raw_ostream& Out,
const TargetData *TD) {
// Alloca is hard to get, and we don't want to include stdlib.h here.
Out << "/* get a declaration for alloca */\n"
bool CWriter::doInitialization(Module &M) {
+ FunctionPass::doInitialization(M);
+
// Initialize
TheModule = &M;
if (getGlobalVariableClass(I))
continue;
- if (I->hasInternalLinkage())
+ if (I->hasLocalLinkage())
Out << "static ";
else
Out << "extern ";
if (getGlobalVariableClass(I))
continue;
- if (I->hasInternalLinkage())
+ if (I->hasLocalLinkage())
Out << "static ";
else if (I->hasDLLImportLinkage())
Out << "__declspec(dllimport) ";
// the precision of the printed form, unless the printed form preserves
// precision.
//
- static unsigned FPCounter = 0;
for (constant_iterator I = constant_begin(&F), E = constant_end(&F);
I != E; ++I)
- if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
- if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
- !FPConstantMap.count(FPC)) {
- FPConstantMap[FPC] = FPCounter; // Number the FP constants
-
- if (FPC->getType() == Type::DoubleTy) {
- double Val = FPC->getValueAPF().convertToDouble();
- uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue();
- Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
- << " = 0x" << utohexstr(i)
- << "ULL; /* " << Val << " */\n";
- } else if (FPC->getType() == Type::FloatTy) {
- float Val = FPC->getValueAPF().convertToFloat();
- uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt().
- getZExtValue();
- Out << "static const ConstantFloatTy FPConstant" << FPCounter++
- << " = 0x" << utohexstr(i)
- << "U; /* " << Val << " */\n";
- } else if (FPC->getType() == Type::X86_FP80Ty) {
- // api needed to prevent premature destruction
- APInt api = FPC->getValueAPF().bitcastToAPInt();
- const uint64_t *p = api.getRawData();
- Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
- << " = { 0x"
- << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16)
- << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}"
- << "}; /* Long double constant */\n";
- } else if (FPC->getType() == Type::PPC_FP128Ty) {
- APInt api = FPC->getValueAPF().bitcastToAPInt();
- const uint64_t *p = api.getRawData();
- Out << "static const ConstantFP128Ty FPConstant" << FPCounter++
- << " = { 0x"
- << utohexstr(p[0]) << ", 0x" << utohexstr(p[1])
- << "}; /* Long double constant */\n";
-
- } else
- assert(0 && "Unknown float type!");
- }
+ printFloatingPointConstants(*I);
Out << '\n';
}
+void CWriter::printFloatingPointConstants(const Constant *C) {
+ // If this is a constant expression, recursively check for constant fp values.
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
+ printFloatingPointConstants(CE->getOperand(i));
+ return;
+ }
+
+ // Otherwise, check for a FP constant that we need to print.
+ const ConstantFP *FPC = dyn_cast<ConstantFP>(C);
+ if (FPC == 0 ||
+ // Do not put in FPConstantMap if safe.
+ isFPCSafeToPrint(FPC) ||
+ // Already printed this constant?
+ FPConstantMap.count(FPC))
+ return;
+
+ FPConstantMap[FPC] = FPCounter; // Number the FP constants
+
+ if (FPC->getType() == Type::DoubleTy) {
+ double Val = FPC->getValueAPF().convertToDouble();
+ uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue();
+ Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
+ << " = 0x" << utohexstr(i)
+ << "ULL; /* " << Val << " */\n";
+ } else if (FPC->getType() == Type::FloatTy) {
+ float Val = FPC->getValueAPF().convertToFloat();
+ uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt().
+ getZExtValue();
+ Out << "static const ConstantFloatTy FPConstant" << FPCounter++
+ << " = 0x" << utohexstr(i)
+ << "U; /* " << Val << " */\n";
+ } else if (FPC->getType() == Type::X86_FP80Ty) {
+ // api needed to prevent premature destruction
+ APInt api = FPC->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = api.getRawData();
+ Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
+ << " = { 0x" << utohexstr(p[0])
+ << "ULL, 0x" << utohexstr((uint16_t)p[1]) << ",{0,0,0}"
+ << "}; /* Long double constant */\n";
+ } else if (FPC->getType() == Type::PPC_FP128Ty) {
+ APInt api = FPC->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = api.getRawData();
+ Out << "static const ConstantFP128Ty FPConstant" << FPCounter++
+ << " = { 0x"
+ << utohexstr(p[0]) << ", 0x" << utohexstr(p[1])
+ << "}; /* Long double constant */\n";
+
+ } else {
+ llvm_unreachable("Unknown float type!");
+ }
+}
+
+
/// printSymbolTable - Run through symbol table looking for type names. If a
/// type name is found, emit its declaration...
/// isStructReturn - Should this function actually return a struct by-value?
bool isStructReturn = F->hasStructRetAttr();
- if (F->hasInternalLinkage()) Out << "static ";
+ if (F->hasLocalLinkage()) Out << "static ";
if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
if (F->hasDLLExportLinkage()) Out << "__declspec(dllexport) ";
switch (F->getCallingConv()) {
case CallingConv::X86_StdCall:
- Out << "__stdcall ";
+ Out << "__attribute__((stdcall)) ";
break;
case CallingConv::X86_FastCall:
- Out << "__fastcall ";
+ Out << "__attribute__((fastcall)) ";
break;
}
Out << "-(";
writeOperand(BinaryOperator::getNegArgument(cast<BinaryOperator>(&I)));
Out << ")";
+ } else if (BinaryOperator::isFNeg(&I)) {
+ Out << "-(";
+ writeOperand(BinaryOperator::getFNegArgument(cast<BinaryOperator>(&I)));
+ Out << ")";
} else if (I.getOpcode() == Instruction::FRem) {
// Output a call to fmod/fmodf instead of emitting a%b
if (I.getType() == Type::FloatTy)
writeOperandWithCast(I.getOperand(0), I.getOpcode());
switch (I.getOpcode()) {
- case Instruction::Add: Out << " + "; break;
- case Instruction::Sub: Out << " - "; break;
- case Instruction::Mul: Out << " * "; break;
+ case Instruction::Add:
+ case Instruction::FAdd: Out << " + "; break;
+ case Instruction::Sub:
+ case Instruction::FSub: Out << " - "; break;
+ case Instruction::Mul:
+ case Instruction::FMul: Out << " * "; break;
case Instruction::URem:
case Instruction::SRem:
case Instruction::FRem: Out << " % "; break;
case Instruction::Shl : Out << " << "; break;
case Instruction::LShr:
case Instruction::AShr: Out << " >> "; break;
- default: cerr << "Invalid operator type!" << I; abort();
+ default:
+#ifndef NDEBUG
+ cerr << "Invalid operator type!" << I;
+#endif
+ llvm_unreachable(0);
}
writeOperandWithCast(I.getOperand(1), I.getOpcode());
case ICmpInst::ICMP_SLT: Out << " < "; break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT: Out << " > "; break;
- default: cerr << "Invalid icmp predicate!" << I; abort();
+ default:
+#ifndef NDEBUG
+ cerr << "Invalid icmp predicate!" << I;
+#endif
+ llvm_unreachable(0);
}
writeOperandWithCast(I.getOperand(1), I);
const char* op = 0;
switch (I.getPredicate()) {
- default: assert(0 && "Illegal FCmp predicate");
+ default: llvm_unreachable("Illegal FCmp predicate");
case FCmpInst::FCMP_ORD: op = "ord"; break;
case FCmpInst::FCMP_UNO: op = "uno"; break;
case FCmpInst::FCMP_UEQ: op = "ueq"; break;
static const char * getFloatBitCastField(const Type *Ty) {
switch (Ty->getTypeID()) {
- default: assert(0 && "Invalid Type");
+ default: llvm_unreachable("Invalid Type");
case Type::FloatTyID: return "Float";
case Type::DoubleTyID: return "Double";
case Type::IntegerTyID: {
Out << ", ";
// Output the last argument to the enclosing function.
if (I.getParent()->getParent()->arg_empty()) {
- cerr << "The C backend does not currently support zero "
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "The C backend does not currently support zero "
<< "argument varargs functions, such as '"
- << I.getParent()->getParent()->getName() << "'!\n";
- abort();
+ << I.getParent()->getParent()->getName() << "'!";
+ llvm_report_error(Msg.str());
}
writeOperand(--I.getParent()->getParent()->arg_end());
Out << ')';
Out << ')';
// Multiple GCC builtins multiplex onto this intrinsic.
switch (cast<ConstantInt>(I.getOperand(3))->getZExtValue()) {
- default: assert(0 && "Invalid llvm.x86.sse.cmp!");
+ default: llvm_unreachable("Invalid llvm.x86.sse.cmp!");
case 0: Out << "__builtin_ia32_cmpeq"; break;
case 1: Out << "__builtin_ia32_cmplt"; break;
case 2: Out << "__builtin_ia32_cmple"; break;
const char *const *table = 0;
- //Grab the translation table from TargetAsmInfo if it exists
+ // Grab the translation table from TargetAsmInfo if it exists.
if (!TAsm) {
std::string E;
- const TargetMachineRegistry::entry* Match =
- TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, E);
+ const Target *Match =
+ TargetRegistry::getClosestStaticTargetForModule(*TheModule, E);
if (Match) {
- //Per platform Target Machines don't exist, so create it
- // this must be done only once
- const TargetMachine* TM = Match->CtorFn(*TheModule, "");
+ // Per platform Target Machines don't exist, so create it;
+ // this must be done only once.
+ const TargetMachine* TM = Match->createTargetMachine(*TheModule, "");
TAsm = TM->getTargetAsmInfo();
}
}
if (TAsm)
table = TAsm->getAsmCBE();
- //Search the translation table if it exists
+ // Search the translation table if it exists.
for (int i = 0; table && table[i]; i += 2)
if (c.Codes[0] == table[i])
return table[i+1];
- //default is identity
+ // Default is identity.
return c.Codes[0];
}
}
void CWriter::visitMallocInst(MallocInst &I) {
- assert(0 && "lowerallocations pass didn't work!");
+ llvm_unreachable("lowerallocations pass didn't work!");
}
void CWriter::visitAllocaInst(AllocaInst &I) {
}
void CWriter::visitFreeInst(FreeInst &I) {
- assert(0 && "lowerallocations pass didn't work!");
+ llvm_unreachable("lowerallocations pass didn't work!");
}
void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I,
if (!ITy->isPowerOf2ByteWidth())
// We have a bit width that doesn't match an even power-of-2 byte
// size. Consequently we must & the value with the type's bit mask
- BitMask = ConstantInt::get(ITy, ITy->getBitMask());
+ BitMask = I.getContext().getConstantInt(ITy, ITy->getBitMask());
if (BitMask)
Out << "((";
writeOperand(Operand);
//===----------------------------------------------------------------------===//
bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
- raw_ostream &o,
+ formatted_raw_ostream &o,
CodeGenFileType FileType,
- bool Fast) {
+ CodeGenOpt::Level OptLevel) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(createGCLoweringPass());