diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-04-04 19:47:22 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-04-04 19:47:22 -0400 |
| commit | 0edc2b19fe684355406d09c9195b353c630d99ed (patch) | |
| tree | 232693ceb5e2ee139825cf95be1054583e8ee82e /src | |
| parent | d97285eb65d56b9e3a1208c4de3b991e93057495 (diff) | |
| download | zig-0edc2b19fe684355406d09c9195b353c630d99ed.tar.gz zig-0edc2b19fe684355406d09c9195b353c630d99ed.zip | |
support module level assembly
closes #256
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 21 |
3 files changed, 27 insertions, 2 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index c92ab364c5..d3d1a907d1 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1460,6 +1460,8 @@ struct CodeGen { ConstExprValue const_void_val; ConstExprValue panic_msg_vals[PanicMsgIdCount]; + + Buf global_asm; }; enum VarLinkage { diff --git a/src/codegen.cpp b/src/codegen.cpp index 5e803795f1..83b7e01614 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -73,6 +73,8 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { g->is_test_build = false; g->want_h_file = true; + buf_resize(&g->global_asm, 0); + // reserve index 0 to indicate no error g->error_decls.append(nullptr); @@ -3725,6 +3727,10 @@ static void do_code_gen(CodeGen *g) { } assert(!g->errors.length); + if (buf_len(&g->global_asm) != 0) { + LLVMSetModuleInlineAsm(g->module, buf_ptr(&g->global_asm)); + } + ZigLLVMDIBuilderFinalize(g->dbuilder); if (g->verbose) { diff --git a/src/ir.cpp b/src/ir.cpp index 4f3f756d49..6f5f5fbbd2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9896,13 +9896,30 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); + AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; + + bool global_scope = (scope_fn_entry(asm_instruction->base.scope) == nullptr); + if (global_scope) { + if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || + asm_expr->clobber_list.length != 0) + { + ir_add_error(ira, &asm_instruction->base, + buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); + return ira->codegen->builtin_types.entry_invalid; + } + + buf_append_char(&ira->codegen->global_asm, '\n'); + buf_append_buf(&ira->codegen->global_asm, asm_expr->asm_template); + + ir_build_const_from(ira, &asm_instruction->base); + return ira->codegen->builtin_types.entry_void; + } + if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) return ira->codegen->builtin_types.entry_invalid; // TODO validate the output types and variable types - AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; - IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); |
