authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-30 14:43:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-30 14:43:23-07:00
logb77c423f773cdf05c95b293f44852ec5a39fc4ed
treee37dcaa0a6f8f48b67736800dc00b73f773cb86e
parentf36255b670f2bcec368a9ce4622af194b5b71d70

all LLVM C++ API contained to one file


3 files changed, 155 insertions(+), 141 deletions(-)

src/codegen.cpp+8-138
......@@ -15,13 +15,7 @@
1515#include "semantic_info.hpp"
1616
1717#include <stdio.h>
18
19#include <llvm/IR/IRBuilder.h>
20#include <llvm/IR/DIBuilder.h>
21#include <llvm/IR/DiagnosticInfo.h>
22#include <llvm/IR/DiagnosticPrinter.h>
23#include <llvm/Target/TargetMachine.h>
24#include <llvm/Support/TargetParser.h>
18#include <errno.h>
2519
2620CodeGen *create_codegen(AstNode *root, Buf *in_full_path) {
2721 CodeGen *g = allocate<CodeGen>(1);
......@@ -460,24 +454,16 @@ static void gen_block(CodeGen *g, AstNode *block_node, bool add_implicit_return)
460454static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto,
461455 LLVMZigDIFile *di_file)
462456{
463 llvm::SmallVector<llvm::Metadata *, 8> types;
464
465 llvm::DIType *return_type = reinterpret_cast<llvm::DIType*>(to_llvm_debug_type(fn_proto->return_type));
466 types.push_back(return_type);
467
457 LLVMZigDIType **types = allocate<LLVMZigDIType*>(1 + fn_proto->params.length);
458 types[0] = to_llvm_debug_type(fn_proto->return_type);
459 int types_len = fn_proto->params.length + 1;
468460 for (int i = 0; i < fn_proto->params.length; i += 1) {
469461 AstNode *param_node = fn_proto->params.at(i);
470462 assert(param_node->type == NodeTypeParamDecl);
471 llvm::DIType *param_type = reinterpret_cast<llvm::DIType*>(to_llvm_debug_type(param_node->data.param_decl.type));
472 types.push_back(param_type);
463 LLVMZigDIType *param_type = to_llvm_debug_type(param_node->data.param_decl.type);
464 types[i + 1] = param_type;
473465 }
474
475 llvm::DIBuilder *dibuilder = reinterpret_cast<llvm::DIBuilder*>(g->dbuilder);
476
477 llvm::DISubroutineType *result = dibuilder->createSubroutineType(
478 reinterpret_cast<llvm::DIFile*>(di_file),
479 dibuilder->getOrCreateTypeArray(types));
480 return reinterpret_cast<LLVMZigDISubroutineType*>(result);
466 return LLVMZigCreateSubroutineType(g->dbuilder, di_file, types, types_len, 0);
481467}
482468
483469void code_gen(CodeGen *g) {
......@@ -596,122 +582,6 @@ ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g) {
596582 return &g->errors;
597583}
598584
599enum FloatAbi {
600 FloatAbiHard,
601 FloatAbiSoft,
602 FloatAbiSoftFp,
603};
604
605
606static int get_arm_sub_arch_version(const llvm::Triple &triple) {
607 return llvm::ARMTargetParser::parseArchVersion(triple.getArchName());
608}
609
610static FloatAbi get_float_abi(const llvm::Triple &triple) {
611 switch (triple.getOS()) {
612 case llvm::Triple::Darwin:
613 case llvm::Triple::MacOSX:
614 case llvm::Triple::IOS:
615 if (get_arm_sub_arch_version(triple) == 6 ||
616 get_arm_sub_arch_version(triple) == 7)
617 {
618 return FloatAbiSoftFp;
619 } else {
620 return FloatAbiSoft;
621 }
622 case llvm::Triple::Win32:
623 return FloatAbiHard;
624 case llvm::Triple::FreeBSD:
625 switch (triple.getEnvironment()) {
626 case llvm::Triple::GNUEABIHF:
627 return FloatAbiHard;
628 default:
629 return FloatAbiSoft;
630 }
631 default:
632 switch (triple.getEnvironment()) {
633 case llvm::Triple::GNUEABIHF:
634 return FloatAbiHard;
635 case llvm::Triple::GNUEABI:
636 return FloatAbiSoftFp;
637 case llvm::Triple::EABIHF:
638 return FloatAbiHard;
639 case llvm::Triple::EABI:
640 return FloatAbiSoftFp;
641 case llvm::Triple::Android:
642 if (get_arm_sub_arch_version(triple) == 7) {
643 return FloatAbiSoftFp;
644 } else {
645 return FloatAbiSoft;
646 }
647 default:
648 return FloatAbiSoft;
649 }
650 }
651}
652
653static Buf *get_dynamic_linker(CodeGen *g) {
654 llvm::TargetMachine *target_machine = reinterpret_cast<llvm::TargetMachine*>(g->target_machine);
655 const llvm::Triple &triple = target_machine->getTargetTriple();
656
657 const llvm::Triple::ArchType arch = triple.getArch();
658
659 if (triple.getEnvironment() == llvm::Triple::Android) {
660 if (triple.isArch64Bit()) {
661 return buf_create_from_str("/system/bin/linker64");
662 } else {
663 return buf_create_from_str("/system/bin/linker");
664 }
665 } else if (arch == llvm::Triple::x86 ||
666 arch == llvm::Triple::sparc ||
667 arch == llvm::Triple::sparcel)
668 {
669 return buf_create_from_str("/lib/ld-linux.so.2");
670 } else if (arch == llvm::Triple::aarch64) {
671 return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
672 } else if (arch == llvm::Triple::aarch64_be) {
673 return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
674 } else if (arch == llvm::Triple::arm || arch == llvm::Triple::thumb) {
675 if (triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
676 get_float_abi(triple) == FloatAbiHard)
677 {
678 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
679 } else {
680 return buf_create_from_str("/lib/ld-linux.so.3");
681 }
682 } else if (arch == llvm::Triple::armeb || arch == llvm::Triple::thumbeb) {
683 if (triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
684 get_float_abi(triple) == FloatAbiHard)
685 {
686 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
687 } else {
688 return buf_create_from_str("/lib/ld-linux.so.3");
689 }
690 } else if (arch == llvm::Triple::mips || arch == llvm::Triple::mipsel ||
691 arch == llvm::Triple::mips64 || arch == llvm::Triple::mips64el)
692 {
693 // when you want to solve this TODO, grep clang codebase for
694 // getLinuxDynamicLinker
695 zig_panic("TODO figure out MIPS dynamic linker name");
696 } else if (arch == llvm::Triple::ppc) {
697 return buf_create_from_str("/lib/ld.so.1");
698 } else if (arch == llvm::Triple::ppc64) {
699 return buf_create_from_str("/lib64/ld64.so.2");
700 } else if (arch == llvm::Triple::ppc64le) {
701 return buf_create_from_str("/lib64/ld64.so.2");
702 } else if (arch == llvm::Triple::systemz) {
703 return buf_create_from_str("/lib64/ld64.so.1");
704 } else if (arch == llvm::Triple::sparcv9) {
705 return buf_create_from_str("/lib64/ld-linux.so.2");
706 } else if (arch == llvm::Triple::x86_64 &&
707 triple.getEnvironment() == llvm::Triple::GNUX32)
708 {
709 return buf_create_from_str("/libx32/ld-linux-x32.so.2");
710 } else {
711 return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
712 }
713}
714
715585static Buf *to_c_type(CodeGen *g, AstNode *type_node) {
716586 assert(type_node->type == NodeTypeType);
717587 assert(type_node->codegen_node);
......@@ -865,7 +735,7 @@ void code_gen_link(CodeGen *g, const char *out_file) {
865735 }
866736 } else {
867737 args.append("-dynamic-linker");
868 args.append(buf_ptr(get_dynamic_linker(g)));
738 args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
869739 }
870740
871741 if (g->out_type == OutTypeLib) {
src/zig_llvm.cpp+136-3
......@@ -19,6 +19,7 @@
1919#include <llvm/MC/SubtargetFeature.h>
2020#include <llvm/Support/raw_ostream.h>
2121#include <llvm/Support/FileSystem.h>
22#include <llvm/Support/TargetParser.h>
2223#include <llvm/Target/TargetMachine.h>
2324#include <llvm/IR/LegacyPassManager.h>
2425#include <llvm/IR/Module.h>
......@@ -148,6 +149,22 @@ LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const ch
148149 return reinterpret_cast<LLVMZigDIType*>(di_type);
149150}
150151
152LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
153 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags)
154{
155 SmallVector<Metadata *, 8> types;
156 for (int i = 0; i < types_array_len; i += 1) {
157 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
158 types.push_back(ditype);
159 }
160 DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
161 DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
162 reinterpret_cast<DIFile*>(file),
163 dibuilder->getOrCreateTypeArray(types),
164 flags);
165 return reinterpret_cast<LLVMZigDISubroutineType*>(subroutine_type);
166}
167
151168unsigned LLVMZigEncoding_DW_ATE_unsigned(void) {
152169 return dwarf::DW_ATE_unsigned;
153170}
......@@ -161,12 +178,12 @@ unsigned LLVMZigLang_DW_LANG_C99(void) {
161178}
162179
163180LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
164 DIBuilder *di_builder = new DIBuilder(*llvm::unwrap(module), allow_unresolved);
181 DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
165182 return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);
166183}
167184
168185void LLVMZigSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, LLVMZigDIScope *scope) {
169 unwrap(builder)->SetCurrentDebugLocation(llvm::DebugLoc::get(
186 unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get(
170187 line, column, reinterpret_cast<DIScope*>(scope)));
171188}
172189
......@@ -223,7 +240,7 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD
223240 LLVMZigDISubroutineType *ty, bool is_local_to_unit, bool is_definition, unsigned scope_line,
224241 unsigned flags, bool is_optimized, LLVMValueRef function)
225242{
226 llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(unwrap(function));
243 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(function));
227244 DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
228245 reinterpret_cast<DIScope*>(scope),
229246 name, linkage_name,
......@@ -237,3 +254,119 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD
237254void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder) {
238255 reinterpret_cast<DIBuilder*>(dibuilder)->finalize();
239256}
257
258enum FloatAbi {
259 FloatAbiHard,
260 FloatAbiSoft,
261 FloatAbiSoftFp,
262};
263
264static int get_arm_sub_arch_version(const Triple &triple) {
265 return ARMTargetParser::parseArchVersion(triple.getArchName());
266}
267
268static FloatAbi get_float_abi(const Triple &triple) {
269 switch (triple.getOS()) {
270 case Triple::Darwin:
271 case Triple::MacOSX:
272 case Triple::IOS:
273 if (get_arm_sub_arch_version(triple) == 6 ||
274 get_arm_sub_arch_version(triple) == 7)
275 {
276 return FloatAbiSoftFp;
277 } else {
278 return FloatAbiSoft;
279 }
280 case Triple::Win32:
281 return FloatAbiHard;
282 case Triple::FreeBSD:
283 switch (triple.getEnvironment()) {
284 case Triple::GNUEABIHF:
285 return FloatAbiHard;
286 default:
287 return FloatAbiSoft;
288 }
289 default:
290 switch (triple.getEnvironment()) {
291 case Triple::GNUEABIHF:
292 return FloatAbiHard;
293 case Triple::GNUEABI:
294 return FloatAbiSoftFp;
295 case Triple::EABIHF:
296 return FloatAbiHard;
297 case Triple::EABI:
298 return FloatAbiSoftFp;
299 case Triple::Android:
300 if (get_arm_sub_arch_version(triple) == 7) {
301 return FloatAbiSoftFp;
302 } else {
303 return FloatAbiSoft;
304 }
305 default:
306 return FloatAbiSoft;
307 }
308 }
309}
310
311Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {
312 TargetMachine *target_machine = reinterpret_cast<TargetMachine*>(target_machine_ref);
313 const Triple &triple = target_machine->getTargetTriple();
314
315 const Triple::ArchType arch = triple.getArch();
316
317 if (triple.getEnvironment() == Triple::Android) {
318 if (triple.isArch64Bit()) {
319 return buf_create_from_str("/system/bin/linker64");
320 } else {
321 return buf_create_from_str("/system/bin/linker");
322 }
323 } else if (arch == Triple::x86 ||
324 arch == Triple::sparc ||
325 arch == Triple::sparcel)
326 {
327 return buf_create_from_str("/lib/ld-linux.so.2");
328 } else if (arch == Triple::aarch64) {
329 return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
330 } else if (arch == Triple::aarch64_be) {
331 return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
332 } else if (arch == Triple::arm || arch == Triple::thumb) {
333 if (triple.getEnvironment() == Triple::GNUEABIHF ||
334 get_float_abi(triple) == FloatAbiHard)
335 {
336 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
337 } else {
338 return buf_create_from_str("/lib/ld-linux.so.3");
339 }
340 } else if (arch == Triple::armeb || arch == Triple::thumbeb) {
341 if (triple.getEnvironment() == Triple::GNUEABIHF ||
342 get_float_abi(triple) == FloatAbiHard)
343 {
344 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
345 } else {
346 return buf_create_from_str("/lib/ld-linux.so.3");
347 }
348 } else if (arch == Triple::mips || arch == Triple::mipsel ||
349 arch == Triple::mips64 || arch == Triple::mips64el)
350 {
351 // when you want to solve this TODO, grep clang codebase for
352 // getLinuxDynamicLinker
353 zig_panic("TODO figure out MIPS dynamic linker name");
354 } else if (arch == Triple::ppc) {
355 return buf_create_from_str("/lib/ld.so.1");
356 } else if (arch == Triple::ppc64) {
357 return buf_create_from_str("/lib64/ld64.so.2");
358 } else if (arch == Triple::ppc64le) {
359 return buf_create_from_str("/lib64/ld64.so.2");
360 } else if (arch == Triple::systemz) {
361 return buf_create_from_str("/lib64/ld64.so.1");
362 } else if (arch == Triple::sparcv9) {
363 return buf_create_from_str("/lib64/ld-linux.so.2");
364 } else if (arch == Triple::x86_64 &&
365 triple.getEnvironment() == Triple::GNUX32)
366 {
367 return buf_create_from_str("/libx32/ld-linux-x32.so.2");
368 } else {
369 return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
370 }
371}
372
src/zig_llvm.hpp+11
......@@ -42,6 +42,9 @@ LLVMZigDIType *LLVMZigCreateDebugPointerType(LLVMZigDIBuilder *dibuilder, LLVMZi
4242LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const char *name,
4343 uint64_t size_in_bits, uint64_t align_in_bits, unsigned encoding);
4444
45LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
46 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags);
47
4548unsigned LLVMZigEncoding_DW_ATE_unsigned(void);
4649unsigned LLVMZigEncoding_DW_ATE_signed(void);
4750unsigned LLVMZigLang_DW_LANG_C99(void);
......@@ -72,4 +75,12 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD
7275
7376void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder);
7477
78
79/*
80 * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here.
81 */
82#include "buffer.hpp"
83
84Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine);
85
7586#endif