#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/TypeSymbolTable.h"
/// external functions with the same name.
///
class CBackendNameAllUsedStructsAndMergeFunctions : public ModulePass {
+ public:
+ static char ID;
+ CBackendNameAllUsedStructsAndMergeFunctions()
+ : ModulePass((intptr_t)&ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<FindUsedTypes>();
}
virtual bool runOnModule(Module &M);
};
+ char CBackendNameAllUsedStructsAndMergeFunctions::ID = 0;
+
/// 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> {
const TargetAsmInfo* TAsm;
const TargetData* TD;
std::map<const Type *, std::string> TypeNames;
-
std::map<const ConstantFP *, unsigned> FPConstantMap;
+ std::set<Function*> intrinsicPrototypesAlreadyGenerated;
+
public:
- CWriter(std::ostream &o) : Out(o), IL(0), Mang(0), LI(0), TheModule(0),
- TAsm(0), TD(0) {}
+ static char ID;
+ CWriter(std::ostream &o)
+ : FunctionPass((intptr_t)&ID), Out(o), IL(0), Mang(0), LI(0),
+ TheModule(0), TAsm(0), TD(0) {}
virtual const char *getPassName() const { return "C backend"; }
};
}
+char CWriter::ID = 0;
+
/// This method inserts names for any unnamed structure types that are used by
/// the program, and removes names from structure types that are not used by the
/// program.
FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end();
const Type *RetTy = cast<PointerType>(I->get())->getElementType();
unsigned Idx = 1;
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
for (++I; I != E; ++I) {
if (PrintedType)
FunctionInnards << ", ";
printType(FunctionInnards, *I,
- /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute), "");
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt), "");
PrintedType = true;
}
if (FTy->isVarArg()) {
FunctionInnards << ')';
std::string tstr = FunctionInnards.str();
printType(Out, RetTy,
- /*isSigned=*/FTy->paramHasAttr(0, FunctionType::SExtAttribute), tstr);
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), tstr);
}
std::ostream &
const FunctionType *FTy = cast<FunctionType>(Ty);
std::stringstream FunctionInnards;
FunctionInnards << " (" << NameSoFar << ") (";
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
unsigned Idx = 1;
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) {
if (I != FTy->param_begin())
FunctionInnards << ", ";
printType(FunctionInnards, *I,
- /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute), "");
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt), "");
++Idx;
}
if (FTy->isVarArg()) {
FunctionInnards << ')';
std::string tstr = FunctionInnards.str();
printType(Out, FTy->getReturnType(),
- /*isSigned=*/FTy->paramHasAttr(0, FunctionType::SExtAttribute), tstr);
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), tstr);
return Out;
}
case Type::StructTyID: {
printType(Out, *I, false, "field" + utostr(Idx++));
Out << ";\n";
}
- return Out << '}';
+ Out << '}';
+ if (STy->isPacked())
+ Out << " __attribute__ ((packed))";
+ return Out;
}
case Type::PointerTyID: {
// only deal in IEEE FP).
//
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
+ APFloat APF = APFloat(CFP->getValueAPF()); // copy
+ if (CFP->getType()==Type::FloatTy)
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
#if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
char Buffer[100];
- sprintf(Buffer, "%a", CFP->getValue());
-
+ sprintf(Buffer, "%a", APF.convertToDouble());
if (!strncmp(Buffer, "0x", 2) ||
!strncmp(Buffer, "-0x", 3) ||
!strncmp(Buffer, "+0x", 3))
- return atof(Buffer) == CFP->getValue();
+ return APF.bitwiseIsEqual(APFloat(atof(Buffer)));
return false;
#else
- std::string StrVal = ftostr(CFP->getValue());
+ std::string StrVal = ftostr(APF);
while (StrVal[0] == ' ')
StrVal.erase(StrVal.begin());
((StrVal[0] == '-' || StrVal[0] == '+') &&
(StrVal[1] >= '0' && StrVal[1] <= '9')))
// Reparse stringized version!
- return atof(StrVal.c_str()) == CFP->getValue();
+ return APF.bitwiseIsEqual(APFloat(atof(StrVal.c_str())));
return false;
#endif
}
Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
<< "*)&FPConstant" << I->second << ')';
} else {
- if (IsNAN(FPC->getValue())) {
+ double V = FPC->getType() == Type::FloatTy ?
+ FPC->getValueAPF().convertToFloat() :
+ FPC->getValueAPF().convertToDouble();
+ if (IsNAN(V)) {
// The value is NaN
+ // FIXME the actual NaN bits should be emitted.
// The prefix for a quiet NaN is 0x7FF8. For a signalling NaN,
// it's 0x7ff4.
const unsigned long QuietNaN = 0x7ff8UL;
// We need to grab the first part of the FP #
char Buffer[100];
- uint64_t ll = DoubleToBits(FPC->getValue());
+ uint64_t ll = DoubleToBits(V);
sprintf(Buffer, "0x%llx", static_cast<long long>(ll));
std::string Num(&Buffer[0], &Buffer[6]);
else
Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "(\""
<< Buffer << "\") /*nan*/ ";
- } else if (IsInf(FPC->getValue())) {
+ } else if (IsInf(V)) {
// The value is Inf
- if (FPC->getValue() < 0) Out << '-';
+ if (V < 0) Out << '-';
Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "")
<< " /*inf*/ ";
} else {
#if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
// Print out the constant as a floating point number.
char Buffer[100];
- sprintf(Buffer, "%a", FPC->getValue());
+ sprintf(Buffer, "%a", V);
Num = Buffer;
#else
- Num = ftostr(FPC->getValue());
+ Num = ftostr(FPC->getValueAPF());
#endif
- Out << Num;
+ Out << Num;
}
}
break;
// Alloca is hard to get, and we don't want to include stdlib.h here.
Out << "/* get a declaration for alloca */\n"
<< "#if defined(__CYGWIN__) || defined(__MINGW32__)\n"
- << "extern void *_alloca(unsigned long);\n"
- << "#define alloca(x) _alloca(x)\n"
+ << "#define alloca(x) __builtin_alloca((x))\n"
+ << "#define _alloca(x) __builtin_alloca((x))\n"
<< "#elif defined(__APPLE__)\n"
<< "extern void *__builtin_alloca(unsigned long);\n"
<< "#define alloca(x) __builtin_alloca(x)\n"
<< "#define __ATTRIBUTE_DTOR__\n"
<< "#define LLVM_ASM(X)\n"
<< "#endif\n\n";
+
+ Out << "#if __GNUC__ < 4 /* Old GCC's, or compilers not GCC */ \n"
+ << "#define __builtin_stack_save() 0 /* not implemented */\n"
+ << "#define __builtin_stack_restore(X) /* noop */\n"
+ << "#endif\n\n";
// Output target-specific code that should be inserted into main.
Out << "#define CODE_FOR_MAIN() /* Any target-specific code for main()*/\n";
- // On X86, set the FP control word to 64-bits of precision instead of 80 bits.
- Out << "#if defined(__GNUC__) && !defined(__llvm__)\n"
- << "#if defined(i386) || defined(__i386__) || defined(__i386) || "
- << "defined(__x86_64__)\n"
- << "#undef CODE_FOR_MAIN\n"
- << "#define CODE_FOR_MAIN() \\\n"
- << " {short F;__asm__ (\"fnstcw %0\" : \"=m\" (*&F)); \\\n"
- << " F=(F&~0x300)|0x200;__asm__(\"fldcw %0\"::\"m\"(*&F));}\n"
- << "#endif\n#endif\n";
-
}
/// FindStaticTors - Given a static ctor/dtor list, unpack its contents into
Out << "\n/* External Global Variable Declarations */\n";
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
- if (I->hasExternalLinkage()) {
+
+ if (I->hasExternalLinkage() || I->hasExternalWeakLinkage())
Out << "extern ";
- printType(Out, I->getType()->getElementType(), false,
- GetValueName(I));
- Out << ";\n";
- } else if (I->hasDLLImportLinkage()) {
+ else if (I->hasDLLImportLinkage())
Out << "__declspec(dllimport) ";
- printType(Out, I->getType()->getElementType(), false,
- GetValueName(I));
- Out << ";\n";
- } else if (I->hasExternalWeakLinkage()) {
- Out << "extern ";
- printType(Out, I->getType()->getElementType(), false,
- GetValueName(I));
- Out << " __EXTERNAL_WEAK__ ;\n";
- }
+ else
+ continue; // Internal Global
+
+ // Thread Local Storage
+ if (I->isThreadLocal())
+ Out << "__thread ";
+
+ printType(Out, I->getType()->getElementType(), false, GetValueName(I));
+
+ if (I->hasExternalWeakLinkage())
+ Out << " __EXTERNAL_WEAK__";
+ Out << ";\n";
}
}
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
-
+
if (I->hasInternalLinkage())
Out << "static ";
else
Out << "extern ";
+
+ // Thread Local Storage
+ if (I->isThreadLocal())
+ Out << "__thread ";
+
printType(Out, I->getType()->getElementType(), false,
GetValueName(I));
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
-
+
if (I->hasInternalLinkage())
Out << "static ";
else if (I->hasDLLImportLinkage())
Out << "__declspec(dllimport) ";
else if (I->hasDLLExportLinkage())
Out << "__declspec(dllexport) ";
-
+
+ // Thread Local Storage
+ if (I->isThreadLocal())
+ Out << "__thread ";
+
printType(Out, I->getType()->getElementType(), false,
GetValueName(I));
if (I->hasLinkOnceLinkage())
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
!FPConstantMap.count(FPC)) {
- double Val = FPC->getValue();
-
FPConstantMap[FPC] = FPCounter; // Number the FP constants
if (FPC->getType() == Type::DoubleTy) {
+ double Val = FPC->getValueAPF().convertToDouble();
+ uint64_t i = FPC->getValueAPF().convertToAPInt().getZExtValue();
Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
- << " = 0x" << std::hex << DoubleToBits(Val) << std::dec
+ << " = 0x" << std::hex << i << std::dec
<< "ULL; /* " << Val << " */\n";
} else if (FPC->getType() == Type::FloatTy) {
+ float Val = FPC->getValueAPF().convertToFloat();
+ uint32_t i = (uint32_t)FPC->getValueAPF().convertToAPInt().
+ getZExtValue();
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
- << " = 0x" << std::hex << FloatToBits(Val) << std::dec
+ << " = 0x" << std::hex << i << std::dec
<< "U; /* " << Val << " */\n";
} else
assert(0 && "Unknown float type!");
// Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
+ const ParamAttrsList *Attrs = FT->getParamAttrs();
std::stringstream FunctionInnards;
else
ArgName = "";
printType(FunctionInnards, I->getType(),
- /*isSigned=*/FT->paramHasAttr(Idx, FunctionType::SExtAttribute),
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt),
ArgName);
PrintedArg = true;
++Idx;
for (; I != E; ++I) {
if (PrintedArg) FunctionInnards << ", ";
printType(FunctionInnards, *I,
- /*isSigned=*/FT->paramHasAttr(Idx, FunctionType::SExtAttribute));
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt));
PrintedArg = true;
++Idx;
}
// Print out the return type and the signature built above.
printType(Out, RetTy,
- /*isSigned=*/FT->paramHasAttr(0, FunctionType::SExtAttribute),
+ /*isSigned=*/ Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt),
FunctionInnards.str());
}
void CWriter::lowerIntrinsics(Function &F) {
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ // This is used to keep track of intrinsics that get generated to a lowered
+ // function. We must generate the prototypes before the function body which
+ // will only be expanded on first use (by the loop below).
+ std::vector<Function*> prototypesToGen;
+
+ // Examine all the instructions in this function to find the intrinsics that
+ // need to be lowered.
+ for (Function::iterator BB = F.begin(), EE = F.end(); BB != EE; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
if (CallInst *CI = dyn_cast<CallInst>(I++))
if (Function *F = CI->getCalledFunction())
} else {
I = BB->begin();
}
+ // If the intrinsic got lowered to another call, and that call has
+ // a definition then we need to make sure its prototype is emitted
+ // before any calls to it.
+ if (CallInst *Call = dyn_cast<CallInst>(I))
+ if (Function *NewF = Call->getCalledFunction())
+ if (!NewF->isDeclaration())
+ prototypesToGen.push_back(NewF);
+
break;
}
-}
+ // We may have collected some prototypes to emit in the loop above.
+ // Emit them now, before the function that uses them is emitted. But,
+ // be careful not to emit them twice.
+ std::vector<Function*>::iterator I = prototypesToGen.begin();
+ std::vector<Function*>::iterator E = prototypesToGen.end();
+ for ( ; I != E; ++I) {
+ if (intrinsicPrototypesAlreadyGenerated.insert(*I).second) {
+ Out << '\n';
+ printFunctionSignature(*I, true);
+ Out << ";\n";
+ }
+ }
+}
void CWriter::visitCallInst(CallInst &I) {
++ArgNo;
}
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
bool PrintedArg = false;
unsigned Idx = 1;
for (; AI != AE; ++AI, ++ArgNo, ++Idx) {
(*AI)->getType() != FTy->getParamType(ArgNo)) {
Out << '(';
printType(Out, FTy->getParamType(ArgNo),
- /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute));
+ /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt));
Out << ')';
}
writeOperand(*AI);