zig/deps/aro/Codegen_legacy.zig
Veikka Tuominen 5792570197 add Aro sources as a dependency
ref: 5688dbccfb58216468267a0f46b96bed7013715a
2023-10-01 23:51:54 +03:00

109 lines
3.3 KiB
Zig
Vendored

const std = @import("std");
const Compilation = @import("Compilation.zig");
const Tree = @import("Tree.zig");
const NodeIndex = Tree.NodeIndex;
const Object = @import("Object.zig");
const x86_64 = @import("codegen/x86_64.zig");
const Codegen = @This();
comp: *Compilation,
tree: Tree,
obj: *Object,
node_tag: []const Tree.Tag,
node_data: []const Tree.Node.Data,
pub const Error = Compilation.Error || error{CodegenFailed};
/// Generate tree to an object file.
/// Caller is responsible for flushing and freeing the returned object.
pub fn generateTree(comp: *Compilation, tree: Tree) Compilation.Error!*Object {
var c = Codegen{
.comp = comp,
.tree = tree,
.obj = try Object.create(comp),
.node_tag = tree.nodes.items(.tag),
.node_data = tree.nodes.items(.data),
};
errdefer c.obj.deinit();
const node_tags = tree.nodes.items(.tag);
for (tree.root_decls) |decl| {
switch (node_tags[@intFromEnum(decl)]) {
// these produce no code
.static_assert,
.typedef,
.struct_decl_two,
.union_decl_two,
.enum_decl_two,
.struct_decl,
.union_decl,
.enum_decl,
.struct_forward_decl,
.union_forward_decl,
.enum_forward_decl,
=> {},
// define symbol
.fn_proto,
.static_fn_proto,
.inline_fn_proto,
.inline_static_fn_proto,
.extern_var,
.threadlocal_extern_var,
=> {
const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
_ = try c.obj.declareSymbol(.undefined, name, .Strong, .external, 0, 0);
},
// function definition
.fn_def,
.static_fn_def,
.inline_fn_def,
.inline_static_fn_def,
=> c.genFn(decl) catch |err| switch (err) {
error.FatalError => return error.FatalError,
error.OutOfMemory => return error.OutOfMemory,
error.CodegenFailed => continue,
},
.@"var",
.static_var,
.threadlocal_var,
.threadlocal_static_var,
.implicit_static_var,
=> c.genVar(decl) catch |err| switch (err) {
error.FatalError => return error.FatalError,
error.OutOfMemory => return error.OutOfMemory,
error.CodegenFailed => continue,
},
// TODO
.file_scope_asm => {},
else => unreachable,
}
}
return c.obj;
}
fn genFn(c: *Codegen, decl: NodeIndex) Error!void {
const section: Object.Section = .func;
const data = try c.obj.getSection(section);
const start_len = data.items.len;
switch (c.comp.target.cpu.arch) {
.x86_64 => try x86_64.genFn(c, decl, data),
else => unreachable,
}
const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
_ = try c.obj.declareSymbol(section, name, .Strong, .func, start_len, data.items.len - start_len);
}
fn genVar(c: *Codegen, decl: NodeIndex) Error!void {
switch (c.comp.target.cpu.arch) {
.x86_64 => try x86_64.genVar(c, decl),
else => unreachable,
}
}