authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-04 19:47:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-04 19:47:22-04:00
log0edc2b19fe684355406d09c9195b353c630d99ed
tree232693ceb5e2ee139825cf95be1054583e8ee82e
parentd97285eb65d56b9e3a1208c4de3b991e93057495

support module level assembly

closes #256

6 files changed, 65 insertions(+), 2 deletions(-)

src/all_types.hpp+2
......@@ -1460,6 +1460,8 @@ struct CodeGen {
14601460 ConstExprValue const_void_val;
14611461
14621462 ConstExprValue panic_msg_vals[PanicMsgIdCount];
1463
1464 Buf global_asm;
14631465};
14641466
14651467enum VarLinkage {
src/codegen.cpp+6
......@@ -73,6 +73,8 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
7373 g->is_test_build = false;
7474 g->want_h_file = true;
7575
76 buf_resize(&g->global_asm, 0);
77
7678 // reserve index 0 to indicate no error
7779 g->error_decls.append(nullptr);
7880
......@@ -3725,6 +3727,10 @@ static void do_code_gen(CodeGen *g) {
37253727 }
37263728 assert(!g->errors.length);
37273729
3730 if (buf_len(&g->global_asm) != 0) {
3731 LLVMSetModuleInlineAsm(g->module, buf_ptr(&g->global_asm));
3732 }
3733
37283734 ZigLLVMDIBuilderFinalize(g->dbuilder);
37293735
37303736 if (g->verbose) {
src/ir.cpp+19-2
......@@ -9896,13 +9896,30 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
98969896static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) {
98979897 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr);
98989898
9899 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr;
9900
9901 bool global_scope = (scope_fn_entry(asm_instruction->base.scope) == nullptr);
9902 if (global_scope) {
9903 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 ||
9904 asm_expr->clobber_list.length != 0)
9905 {
9906 ir_add_error(ira, &asm_instruction->base,
9907 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers"));
9908 return ira->codegen->builtin_types.entry_invalid;
9909 }
9910
9911 buf_append_char(&ira->codegen->global_asm, '\n');
9912 buf_append_buf(&ira->codegen->global_asm, asm_expr->asm_template);
9913
9914 ir_build_const_from(ira, &asm_instruction->base);
9915 return ira->codegen->builtin_types.entry_void;
9916 }
9917
98999918 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base))
99009919 return ira->codegen->builtin_types.entry_invalid;
99019920
99029921 // TODO validate the output types and variable types
99039922
9904 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr;
9905
99069923 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length);
99079924 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length);
99089925
test/cases/asm.zig created+23
......@@ -0,0 +1,23 @@
1const assert = @import("std").debug.assert;
2
3comptime {
4 if (@compileVar("arch") == Arch.x86_64) {
5 asm volatile (
6 \\.globl aoeu;
7 \\.type aoeu, @function;
8 \\.set aoeu, derp;
9 );
10 }
11}
12
13test "module level assembly" {
14 if (@compileVar("arch") == Arch.x86_64) {
15 assert(aoeu() == 1234);
16 }
17}
18
19extern fn aoeu() -> i32;
20
21export fn derp() -> i32 {
22 return 1234;
23}
test/run_tests.cpp+14
......@@ -1834,6 +1834,20 @@ fn foo(e: error) -> u2 {
18341834}
18351835export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
18361836 )SOURCE", 1, ".tmp_source.zig:5:14: error: too many error values to fit in 'u2'");
1837
1838 add_compile_fail_case("asm at compile time", R"SOURCE(
1839comptime {
1840 doSomeAsm();
1841}
1842
1843fn doSomeAsm() {
1844 asm volatile (
1845 \\.globl aoeu;
1846 \\.type aoeu, @function;
1847 \\.set aoeu, derp;
1848 );
1849}
1850 )SOURCE", 1, ".tmp_source.zig:7:5: error: unable to evaluate constant expression");
18371851}
18381852
18391853//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+1
......@@ -1,5 +1,6 @@
11comptime {
22 _ = @import("cases/array.zig");
3 _ = @import("cases/asm.zig");
34 _ = @import("cases/atomics.zig");
45 _ = @import("cases/bool.zig");
56 _ = @import("cases/cast.zig");