Mercurial > projects > ldc
diff gen/runtime.cpp @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | 6789050b5ad1 |
children | 44a95ac7368a |
line wrap: on
line diff
--- a/gen/runtime.cpp Fri Jan 04 01:38:42 2008 +0100 +++ b/gen/runtime.cpp Fri Jan 11 17:57:40 2008 +0100 @@ -7,20 +7,31 @@ #include "root.h" #include "mars.h" +#include "lexer.h" +#include "dsymbol.h" +#include "mtype.h" +#include "aggregate.h" #include "gen/runtime.h" #include "gen/logger.h" +#include "gen/tollvm.h" static llvm::Module* M = NULL; static bool runtime_failed = false; +static void LLVM_D_BuildRuntimeModule(); + ////////////////////////////////////////////////////////////////////////////////////////////////// bool LLVM_D_InitRuntime() { - Logger::println("*** Loading D runtime ***"); + Logger::println("*** Initializing D runtime declarations ***"); LOG_SCOPE; + LLVM_D_BuildRuntimeModule(); + return true; + + /* if (!global.params.runtimeImppath) { error("You must set the runtime import path with -E"); fatal(); @@ -47,13 +58,15 @@ delete buffer; return retval; + */ } void LLVM_D_FreeRuntime() { if (M) { - Logger::println("*** Freeing D runtime ***"); + Logger::println("*** Freeing D runtime declarations ***"); delete M; + M = NULL; } } @@ -90,9 +103,6 @@ llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name) { - // TODO maybe check the target module first, to allow overriding the runtime on a pre module basis? - // could be done and seems like it could be neat too :) - llvm::GlobalVariable* gv = target->getNamedGlobal(name); if (gv) { return gv; @@ -118,3 +128,508 @@ const llvm::PointerType* t = g->getType(); return new llvm::GlobalVariable(t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName(),target); } + +////////////////////////////////////////////////////////////////////////////////////////////////// + +static const llvm::Type* rt_ptr(const llvm::Type* t) +{ + return llvm::PointerType::get(t); +} + +static const llvm::Type* rt_array(const llvm::Type* elemty) +{ + std::vector<const llvm::Type*> t; + t.push_back(DtoSize_t()); + t.push_back(rt_ptr(elemty)); + return rt_ptr(llvm::StructType::get(t)); +} + +static const llvm::Type* rt_dg1() +{ + std::vector<const llvm::Type*> types; + types.push_back(rt_ptr(llvm::Type::Int8Ty)); + types.push_back(rt_ptr(llvm::Type::Int8Ty)); + const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false); + + std::vector<const llvm::Type*> t; + t.push_back(rt_ptr(llvm::Type::Int8Ty)); + t.push_back(rt_ptr(fty)); + return rt_ptr(llvm::StructType::get(t)); +} + +static const llvm::Type* rt_dg2() +{ + std::vector<const llvm::Type*> types; + types.push_back(rt_ptr(llvm::Type::Int8Ty)); + types.push_back(rt_ptr(llvm::Type::Int8Ty)); + types.push_back(rt_ptr(llvm::Type::Int8Ty)); + const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false); + + std::vector<const llvm::Type*> t; + t.push_back(rt_ptr(llvm::Type::Int8Ty)); + t.push_back(rt_ptr(fty)); + return rt_ptr(llvm::StructType::get(t)); +} + +static void LLVM_D_BuildRuntimeModule() +{ + M = new llvm::Module("llvmdc internal runtime"); + + const llvm::Type* voidTy = llvm::Type::VoidTy; + const llvm::Type* boolTy = llvm::Type::Int1Ty; + const llvm::Type* byteTy = llvm::Type::Int8Ty; + const llvm::Type* shortTy = llvm::Type::Int16Ty; + const llvm::Type* intTy = llvm::Type::Int32Ty; + const llvm::Type* longTy = llvm::Type::Int64Ty; + const llvm::Type* floatTy = llvm::Type::FloatTy; + const llvm::Type* doubleTy = llvm::Type::DoubleTy; + const llvm::Type* sizeTy = DtoSize_t(); + const llvm::Type* voidPtrTy = rt_ptr(byteTy); + const llvm::Type* stringTy = rt_array(byteTy); + const llvm::Type* wstringTy = rt_array(shortTy); + const llvm::Type* dstringTy = rt_array(intTy); + const llvm::Type* objectTy = rt_ptr(ClassDeclaration::object->type->llvmType->get()); + const llvm::Type* classInfoTy = rt_ptr(ClassDeclaration::classinfo->type->llvmType->get()); + const llvm::Type* typeInfoTy = rt_ptr(Type::typeinfo->type->llvmType->get()); + const llvm::Type* aaTy = rt_ptr(llvm::OpaqueType::get()); + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // assert + // void _d_assert(bool cond, uint line, char[] msg) + { + std::string fname("_d_assert"); + std::vector<const llvm::Type*> types; + types.push_back(boolTy); + types.push_back(intTy); + types.push_back(stringTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // realloc + // void* _d_realloc(void* ptr, size_t n) + { + std::string fname("_d_realloc"); + std::vector<const llvm::Type*> types; + types.push_back(voidPtrTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // free + // void _d_free(void* ptr) + { + std::string fname("_d_free"); + std::vector<const llvm::Type*> types; + types.push_back(voidPtrTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + #define ARRAY_INIT(TY,suffix) \ + { \ + std::string fname("_d_array_init_"); \ + fname.append(suffix); \ + std::vector<const llvm::Type*> types; \ + types.push_back(rt_ptr(TY)); \ + types.push_back(sizeTy); \ + types.push_back(TY); \ + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + } + + ARRAY_INIT(boolTy,"i1") + ARRAY_INIT(byteTy,"i8") + ARRAY_INIT(shortTy,"i16") + ARRAY_INIT(intTy,"i32") + ARRAY_INIT(longTy,"i64") + ARRAY_INIT(floatTy,"float") + ARRAY_INIT(doubleTy,"double") + ARRAY_INIT(voidPtrTy,"pointer") + + #undef ARRAY_INIT + + // array init mem + // void _d_array_init_mem(void* a, size_t na, void* v, size_t nv) + { + std::string fname("_d_array_init_mem"); + std::vector<const llvm::Type*> types; + types.push_back(voidPtrTy); + types.push_back(sizeTy); + types.push_back(voidPtrTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + #define STR_APPLY1(TY,a,b) \ + { \ + std::string fname(a); \ + std::string fname2(b); \ + std::vector<const llvm::Type*> types; \ + types.push_back(TY); \ + types.push_back(rt_dg1()); \ + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + } + STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1") + STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1") + STR_APPLY1(dstringTy, "_aApplydc1", "_aApplydw1") + #undef STR_APPLY + + #define STR_APPLY2(TY,a,b) \ + { \ + std::string fname(a); \ + std::string fname2(b); \ + std::vector<const llvm::Type*> types; \ + types.push_back(TY); \ + types.push_back(rt_dg2()); \ + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + } + STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2") + STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2") + STR_APPLY2(dstringTy, "_aApplydc2", "_aApplydw2") + #undef STR_APPLY2 + + #define STR_APPLY_R1(TY,a,b) \ + { \ + std::string fname(a); \ + std::string fname2(b); \ + std::vector<const llvm::Type*> types; \ + types.push_back(TY); \ + types.push_back(rt_dg1()); \ + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + } + STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1") + STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1") + STR_APPLY_R1(dstringTy, "_aApplyRdc1", "_aApplyRdw1") + #undef STR_APPLY + + #define STR_APPLY_R2(TY,a,b) \ + { \ + std::string fname(a); \ + std::string fname2(b); \ + std::vector<const llvm::Type*> types; \ + types.push_back(TY); \ + types.push_back(rt_dg2()); \ + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + } + STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2") + STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2") + STR_APPLY_R2(dstringTy, "_aApplyRdc2", "_aApplyRdw2") + #undef STR_APPLY2 + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // fixes the length for dynamic array casts + // size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz) + { + std::string fname("_d_array_cast_len"); + std::vector<const llvm::Type*> types; + types.push_back(sizeTy); + types.push_back(sizeTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // builds the d string[] for the D main args from the C main args + // void _d_main_args(uint n, char** args, ref char[][] res) + { + std::string fname("_d_main_args"); + std::vector<const llvm::Type*> types; + types.push_back(intTy); + types.push_back(rt_ptr(rt_ptr(byteTy))); + types.push_back(rt_array(stringTy->getContainedType(0))); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // cast to object + // Object _d_toObject(void* p) + { + std::string fname("_d_toObject"); + std::vector<const llvm::Type*> types; + types.push_back(voidPtrTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // cast interface + // Object _d_interface_cast(void* p, ClassInfo c) + { + std::string fname("_d_interface_cast"); + std::vector<const llvm::Type*> types; + types.push_back(voidPtrTy); + types.push_back(classInfoTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // dynamic cast + // Object _d_dynamic_cast(Object o, ClassInfo c) + { + std::string fname("_d_dynamic_cast"); + std::vector<const llvm::Type*> types; + types.push_back(objectTy); + types.push_back(classInfoTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(objectTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // char[] _adReverseChar(char[] a) + // char[] _adSortChar(char[] a) + { + std::string fname("_adReverseChar"); + std::string fname2("_adSortChar"); + std::vector<const llvm::Type*> types; + types.push_back(stringTy); + types.push_back(stringTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + } + + // wchar[] _adReverseWchar(wchar[] a) + // wchar[] _adSortWchar(wchar[] a) + { + std::string fname("_adReverseWchar"); + std::string fname2("_adSortWchar"); + std::vector<const llvm::Type*> types; + types.push_back(wstringTy); + types.push_back(wstringTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + } + + // Array _adReverse(Array a, size_t szelem) + { + std::string fname("_adReverse"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(rt_array(byteTy)); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // Array _adDupT(TypeInfo ti, Array a) + { + std::string fname("_adDupT"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(typeInfoTy); + types.push_back(rt_array(byteTy)); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // int _adEq(Array a1, Array a2, TypeInfo ti) + // int _adCmp(Array a1, Array a2, TypeInfo ti) + { + std::string fname("_adEq"); + std::string fname2("_adCmp"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(rt_array(byteTy)); + types.push_back(typeInfoTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + } + + // int _adCmpChar(Array a1, Array a2) + { + std::string fname("_adCmpChar"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(rt_array(byteTy)); + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // Array _adSort(Array a, TypeInfo ti) + { + std::string fname("_adSort"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(rt_array(byteTy)); + types.push_back(typeInfoTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // size_t _aaLen(AA aa) + { + std::string fname("_aaLen"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(sizeTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // void* _aaGet(AA* aa, TypeInfo keyti, void* pkey, size_t valuesize) + { + std::string fname("_aaGet"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(typeInfoTy); + types.push_back(voidPtrTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void* pkey) + { + std::string fname("_aaGetRvalue"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(typeInfoTy); + types.push_back(sizeTy); + types.push_back(voidPtrTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // void* _aaIn(AA aa, TypeInfo keyti, void* pkey) + { + std::string fname("_aaIn"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(typeInfoTy); + types.push_back(voidPtrTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // void _aaDel(AA aa, TypeInfo keyti, void* pkey) + { + std::string fname("_aaDel"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(typeInfoTy); + types.push_back(voidPtrTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // ArrayRet_t _aaValues(AA aa, size_t keysize, size_t valuesize) + { + std::string fname("_aaValues"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(aaTy); + types.push_back(sizeTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // void* _aaRehash(AA* paa, TypeInfo keyti) + { + std::string fname("_aaRehash"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(typeInfoTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // ArrayRet_t _aaKeys(AA aa, size_t keysize) + { + std::string fname("_aaKeys"); + std::vector<const llvm::Type*> types; + types.push_back(rt_array(byteTy)); + types.push_back(aaTy); + types.push_back(sizeTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // int _aaApply(AA aa, size_t keysize, dg_t dg) + { + std::string fname("_aaApply"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(sizeTy); + types.push_back(rt_dg1()); + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + // int _aaApply2(AA aa, size_t keysize, dg2_t dg) + { + std::string fname("_aaApply2"); + std::vector<const llvm::Type*> types; + types.push_back(aaTy); + types.push_back(sizeTy); + types.push_back(rt_dg1()); + const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // void _moduleCtor() + // void _moduleDtor() + { + std::string fname("_moduleCtor"); + std::string fname2("_moduleDtor"); + std::vector<const llvm::Type*> types; + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + } + +} + + + + + +