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,
33bin_file: *link.File,
44arena: Allocator,
55gpa: Allocator,
6symbols: std.StringHashMapUnmanaged(*Module.Decl),
67verbose_air: bool,
78
89const builtin = @import("builtin");
......@@ -30,12 +31,16 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
3031 .arena = arena,
3132 .gpa = comp.gpa,
3233 .verbose_air = comp.verbose_air,
34 .symbols = .{},
3335 };
36 defer c.symbols.deinit(comp.gpa);
3437
3538 const node_tags = tree.nodes.items(.tag);
3639 const node_datas = tree.nodes.items(.data);
37 for (tree.root_decls) |decl| {
38 switch (node_tags[@enumToInt(decl)]) {
40 const node_tys = tree.nodes.items(.ty);
41
42 for (tree.root_decls) |decl_node| {
43 switch (node_tags[@enumToInt(decl_node)]) {
3944 // these produce no code
4045 .static_assert,
4146 .typedef,
......@@ -45,19 +50,30 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
4550 .struct_decl,
4651 .union_decl,
4752 .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,
5269 .static_fn_proto,
5370 .inline_fn_proto,
5471 .inline_static_fn_proto,
5572 .extern_var,
5673 .threadlocal_extern_var,
5774 => {
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);
5976 log.debug("ignoring the opportunity to define a symbol named {s}", .{name});
60 //_ = try c.obj.declareSymbol(.@"undefined", name, .Strong, .external, 0, 0);
6177 },
6278
6379 // function definition
......@@ -65,13 +81,13 @@ pub fn generateTree(comp: *Compilation, aro_comp: *aro.Compilation, tree: aro.Tr
6581 .static_fn_def,
6682 .inline_fn_def,
6783 .inline_static_fn_def,
68 => try c.genFn(decl),
84 => try c.genFn(decl_node),
6985
7086 .@"var",
7187 .static_var,
7288 .threadlocal_var,
7389 .threadlocal_static_var,
74 => try c.genVar(decl),
90 => try c.genVar(decl_node),
7591
7692 else => unreachable,
7793 }
......@@ -213,6 +229,17 @@ const Func = struct {
213229 const coerced = @bitCast([]const u32, refs);
214230 func.air_extra.appendSliceAssumeCapacity(coerced);
215231 }
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 }
216243};
217244
218245fn genFn(c: *Codegen, decl_node: NodeIndex) !void {
......@@ -282,7 +309,6 @@ fn genFn(c: *Codegen, decl_node: NodeIndex) !void {
282309}
283310
284311fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {
285 _ = c;
286312 switch (aro_ty.specifier) {
287313 .void => return Type.void,
288314 .bool => return Type.bool,
......@@ -301,19 +327,47 @@ fn lowerType(c: *Codegen, aro_ty: aro.Type) Allocator.Error!Type {
301327 .double => return Type.initTag(.f64),
302328 .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
304361 .complex_float,
305362 .complex_double,
306363 .complex_long_double,
307364
308365 // data.sub_type
309 .pointer,
310366 .unspecified_variable_len_array,
311367 .decayed_unspecified_variable_len_array,
312368 // data.func
313369 // int foo(int bar, char baz) and int (void)
314370 .func,
315 // int foo(int bar, char baz, ...)
316 .var_args_func,
317371 // int foo(bar, baz) and int foo()
318372 // is also var args, but we can give warnings about incorrect amounts of parameters
319373 .old_style_func,
......@@ -360,12 +414,18 @@ fn lowerValue(c: *Codegen, aro_ty: aro.Type, aro_val: aro.Value) Allocator.Error
360414 switch (aro_val.tag) {
361415 .unavailable => unreachable,
362416 .int => {
363 const is_signed = zig_ty.isSignedInt();
364 if (is_signed) @panic("TODO");
365 return TypedValue{
366 .ty = zig_ty,
367 .val = try Value.Tag.int_u64.create(c.arena, aro_val.data.int),
368 };
417 if (zig_ty.isSignedInt()) {
418 const signed_int = aro_val.signExtend(aro_ty, c.aro_comp);
419 return TypedValue{
420 .ty = zig_ty,
421 .val = try Value.Tag.int_i64.create(c.arena, signed_int),
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 }
369429 },
370430 .float => @panic("TODO"),
371431 .array => @panic("TODO"),
......@@ -424,19 +484,13 @@ fn genNode(func: *Func, block: *Block, node: NodeIndex) Error!Air.Inst.Ref {
424484 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
425485 );
426486
427 return func.addConstant(
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 );
487 return func.declRef(new_decl);
435488 },
436489 .decl_ref_expr => {
437490 // TODO locals and arguments
438491 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);
440494 },
441495 .return_stmt => {
442496 const operand = try genNode(func, block, data.un);