authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-06 23:25:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-06 23:25:08-07:00
log8a545069a48d466f812cbfc165fcd059f7585765
treefa67e41864a43e9b23ee235ae33c7dbed7143d67
parent376d443ae314e6e999fb58fd6d8e8a4adc4fbdeb

hello-world.c is producing Zig AIR


1 files changed, 82 insertions(+), 28 deletions(-)

src/aro/Codegen.zig+82-28
...@@ -3,6 +3,7 @@ tree: aro.Tree,...@@ -3,6 +3,7 @@ tree: aro.Tree,
3bin_file: *link.File,3bin_file: *link.File,
4arena: Allocator,4arena: Allocator,
5gpa: Allocator,5gpa: Allocator,
6symbols: std.StringHashMapUnmanaged(*Module.Decl),
6verbose_air: bool,7verbose_air: bool,
78
8const builtin = @import("builtin");9const builtin = @import("builtin");
...@@ -30,12 +31,16 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr...@@ -30,12 +31,16 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
30 .arena = arena,31 .arena = arena,
31 .gpa = comp.gpa,32 .gpa = comp.gpa,
32 .verbose_air = comp.verbose_air,33 .verbose_air = comp.verbose_air,
34 .symbols = .{},
33 };35 };
36 defer c.symbols.deinit(comp.gpa);
3437
35 const node_tags = tree.nodes.items(.tag);38 const node_tags = tree.nodes.items(.tag);
36 const node_datas = tree.nodes.items(.data);39 const node_datas = tree.nodes.items(.data);
37 for (tree.root_decls) |decl| {40 const node_tys = tree.nodes.items(.ty);
38 switch (node_tags[@enumToInt(decl)]) {41
42 for (tree.root_decls) |decl_node| {
43 switch (node_tags[@enumToInt(decl_node)]) {
39 // these produce no code44 // these produce no code
40 .static_assert,45 .static_assert,
41 .typedef,46 .typedef,
...@@ -45,19 +50,30 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr...@@ -45,19 +50,30 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
45 .struct_decl,50 .struct_decl,
46 .union_decl,51 .union_decl,
47 .enum_decl,52 .enum_decl,
48 => {},53 => continue,
54
55 // symbol definitions
56 .fn_proto => {
57 const mod = comp.bin_file.options.module.?;
58 const name = c.tree.tokSlice(node_datas[@enumToInt(decl_node)].decl.name);
59 const fn_proto_ty = node_tys[@enumToInt(decl_node)];
60 const zig_fn_ty = try c.lowerType(fn_proto_ty);
61 const new_decl = try mod.createAnonymousDecl2(.{
62 .ty = zig_fn_ty,
63 .val = undefined,
64 }, name);
65 new_decl.val = try Value.Tag.extern_fn.create(c.arena, new_decl);
66 try c.symbols.put(c.gpa, name, new_decl);
67 },
4968
50 // define symbol
51 .fn_proto,
52 .static_fn_proto,69 .static_fn_proto,
53 .inline_fn_proto,70 .inline_fn_proto,
54 .inline_static_fn_proto,71 .inline_static_fn_proto,
55 .extern_var,72 .extern_var,
56 .threadlocal_extern_var,73 .threadlocal_extern_var,
57 => {74 => {
58 const name = c.tree.tokSlice(node_datas[@enumToInt(decl)].decl.name);75 const name = c.tree.tokSlice(node_datas[@enumToInt(decl_node)].decl.name);
59 log.debug("ignoring the opportunity to define a symbol named {s}", .{name});76 log.debug("ignoring the opportunity to define a symbol named {s}", .{name});
60 //_ = try c.obj.declareSymbol(.@"undefined", name, .Strong, .external, 0, 0);
61 },77 },
6278
63 // function definition79 // function definition
...@@ -65,13 +81,13 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr...@@ -65,13 +81,13 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
65 .static_fn_def,81 .static_fn_def,
66 .inline_fn_def,82 .inline_fn_def,
67 .inline_static_fn_def,83 .inline_static_fn_def,
68 => try c.genFn(decl),84 => try c.genFn(decl_node),
6985
70 .@"var",86 .@"var",
71 .static_var,87 .static_var,
72 .threadlocal_var,88 .threadlocal_var,
73 .threadlocal_static_var,89 .threadlocal_static_var,
74 => try c.genVar(decl),90 => try c.genVar(decl_node),
7591
76 else => unreachable,92 else => unreachable,
77 }93 }
...@@ -213,6 +229,17 @@ const Func = struct {...@@ -213,6 +229,17 @@ const Func = struct {
213 const coerced = @bitCast([]const u32, refs);229 const coerced = @bitCast([]const u32, refs);
214 func.air_extra.appendSliceAssumeCapacity(coerced);230 func.air_extra.appendSliceAssumeCapacity(coerced);
215 }231 }
232
233 fn declRef(func: *Func, decl: *Module.Decl) !Air.Inst.Ref {
234 return func.addConstant(
235 try Type.ptr(func.codegen.arena, .{
236 .pointee_type = decl.ty,
237 .mutable = false,
238 .@"addrspace" = decl.@"addrspace",
239 }),
240 try Value.Tag.decl_ref.create(func.codegen.arena, decl),
241 );
242 }
216};243};
217244
218fn genFn(c: *Codegen, decl_node: NodeIndex) !void {245fn genFn(c: *Codegen, decl_node: NodeIndex) !void {
...@@ -282,7 +309,6 @@ fn genFn(c: *Codegen, decl_node: NodeIndex) !void {...@@ -282,7 +309,6 @@ fn genFn(c: *Codegen, decl_node: NodeIndex) !void {
282}309}
283310
284fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {311fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {
285 _ = c;
286 switch (aro_ty.specifier) {312 switch (aro_ty.specifier) {
287 .void => return Type.void,313 .void => return Type.void,
288 .bool => return Type.bool,314 .bool => return Type.bool,
...@@ -301,19 +327,47 @@ fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {...@@ -301,19 +327,47 @@ fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {
301 .double => return Type.initTag(.f64),327 .double => return Type.initTag(.f64),
302 .long_double => return Type.initTag(.c_longdouble),328 .long_double => return Type.initTag(.c_longdouble),
303329
330 // int foo(int bar, char baz, ...)
331 .var_args_func => {
332 const param_types = try c.arena.alloc(Type, aro_ty.data.func.params.len);
333 for (param_types) |*ty, i| {
334 ty.* = try c.lowerType(aro_ty.data.func.params[i].ty);
335 }
336
337 const zig_ty = try Type.Tag.function.create(c.arena, .{
338 .param_types = param_types,
339 .comptime_params = undefined,
340 .return_type = try c.lowerType(aro_ty.data.func.return_type),
341 .alignment = 0,
342 .cc = .C,
343 .is_var_args = true,
344 .is_generic = false,
345 });
346 return zig_ty;
347 },
348
349 .pointer => {
350 const zig_ty = try Type.ptr(c.arena, .{
351 .pointee_type = try c.lowerType(aro_ty.data.sub_type.*),
352 .@"addrspace" = .generic,
353 .mutable = !aro_ty.qual.@"const",
354 .@"volatile" = aro_ty.qual.@"volatile",
355 .@"allowzero" = true,
356 .size = .C,
357 });
358 return zig_ty;
359 },
360
304 .complex_float,361 .complex_float,
305 .complex_double,362 .complex_double,
306 .complex_long_double,363 .complex_long_double,
307364
308 // data.sub_type365 // data.sub_type
309 .pointer,
310 .unspecified_variable_len_array,366 .unspecified_variable_len_array,
311 .decayed_unspecified_variable_len_array,367 .decayed_unspecified_variable_len_array,
312 // data.func368 // data.func
313 // int foo(int bar, char baz) and int (void)369 // int foo(int bar, char baz) and int (void)
314 .func,370 .func,
315 // int foo(int bar, char baz, ...)
316 .var_args_func,
317 // int foo(bar, baz) and int foo()371 // int foo(bar, baz) and int foo()
318 // is also var args, but we can give warnings about incorrect amounts of parameters372 // is also var args, but we can give warnings about incorrect amounts of parameters
319 .old_style_func,373 .old_style_func,
...@@ -360,12 +414,18 @@ fn lowerValue(c: *Codegen, aro_ty: aro.Type, aro_val: aro.Value) Allocator.Error...@@ -360,12 +414,18 @@ fn lowerValue(c: *Codegen, aro_ty: aro.Type, aro_val: aro.Value) Allocator.Error
360 switch (aro_val.tag) {414 switch (aro_val.tag) {
361 .unavailable => unreachable,415 .unavailable => unreachable,
362 .int => {416 .int => {
363 const is_signed = zig_ty.isSignedInt();417 if (zig_ty.isSignedInt()) {
364 if (is_signed) @panic("TODO");418 const signed_int = aro_val.signExtend(aro_ty, c.aro_comp);
365 return TypedValue{419 return TypedValue{
366 .ty = zig_ty,420 .ty = zig_ty,
367 .val = try Value.Tag.int_u64.create(c.arena, aro_val.data.int),421 .val = try Value.Tag.int_i64.create(c.arena, signed_int),
368 };422 };
423 } else {
424 return TypedValue{
425 .ty = zig_ty,
426 .val = try Value.Tag.int_u64.create(c.arena, aro_val.data.int),
427 };
428 }
369 },429 },
370 .float => @panic("TODO"),430 .float => @panic("TODO"),
371 .array => @panic("TODO"),431 .array => @panic("TODO"),
...@@ -424,19 +484,13 @@ fn genNode(func: *Func, block: *Block, node: NodeIndex) Error!Air.Inst.Ref {...@@ -424,19 +484,13 @@ fn genNode(func: *Func, block: *Block, node: NodeIndex) Error!Air.Inst.Ref {
424 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),484 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
425 );485 );
426486
427 return func.addConstant(487 return func.declRef(new_decl);
428 try Type.ptr(func.codegen.arena, .{
429 .pointee_type = new_decl.ty,
430 .mutable = false,
431 .@"addrspace" = new_decl.@"addrspace",
432 }),
433 try Value.Tag.decl_ref.create(func.codegen.arena, new_decl),
434 );
435 },488 },
436 .decl_ref_expr => {489 .decl_ref_expr => {
437 // TODO locals and arguments490 // TODO locals and arguments
438 const name = tree.tokSlice(data.decl_ref);491 const name = tree.tokSlice(data.decl_ref);
439 std.debug.panic("TODO decl_ref_expr {s}", .{name});492 const decl = func.codegen.symbols.get(name).?;
493 return func.declRef(decl);
440 },494 },
441 .return_stmt => {495 .return_stmt => {
442 const operand = try genNode(func, block, data.un);496 const operand = try genNode(func, block, data.un);