aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig61
1 files changed, 48 insertions, 13 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 9bddc51963..17e3c8504a 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -22,6 +22,8 @@ const Zir = std.zig.Zir;
const Alignment = InternPool.Alignment;
const dev = @import("dev.zig");
+pub const aarch64 = @import("codegen/aarch64.zig");
+
pub const CodeGenError = GenerateSymbolError || error{
/// Indicates the error is already stored in Zcu `failed_codegen`.
CodegenFail,
@@ -48,7 +50,7 @@ fn devFeatureForBackend(backend: std.builtin.CompilerBackend) dev.Feature {
fn importBackend(comptime backend: std.builtin.CompilerBackend) type {
return switch (backend) {
.other, .stage1 => unreachable,
- .stage2_aarch64 => unreachable,
+ .stage2_aarch64 => aarch64,
.stage2_arm => unreachable,
.stage2_c => @import("codegen/c.zig"),
.stage2_llvm => @import("codegen/llvm.zig"),
@@ -71,6 +73,7 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co
.stage2_c,
.stage2_wasm,
.stage2_x86_64,
+ .stage2_aarch64,
.stage2_x86,
.stage2_riscv64,
.stage2_sparc64,
@@ -82,20 +85,29 @@ pub fn legalizeFeatures(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) ?*co
}
}
+pub fn wantsLiveness(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) bool {
+ const zcu = pt.zcu;
+ const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
+ return switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) {
+ else => true,
+ .stage2_aarch64 => false,
+ };
+}
+
/// Every code generation backend has a different MIR representation. However, we want to pass
/// MIR from codegen to the linker *regardless* of which backend is in use. So, we use this: a
/// union of all MIR types. The active tag is known from the backend in use; see `AnyMir.tag`.
pub const AnyMir = union {
- riscv64: @import("arch/riscv64/Mir.zig"),
- sparc64: @import("arch/sparc64/Mir.zig"),
- x86_64: @import("arch/x86_64/Mir.zig"),
- wasm: @import("arch/wasm/Mir.zig"),
- c: @import("codegen/c.zig").Mir,
+ aarch64: if (dev.env.supports(.aarch64_backend)) @import("codegen/aarch64/Mir.zig") else noreturn,
+ riscv64: if (dev.env.supports(.riscv64_backend)) @import("arch/riscv64/Mir.zig") else noreturn,
+ sparc64: if (dev.env.supports(.sparc64_backend)) @import("arch/sparc64/Mir.zig") else noreturn,
+ x86_64: if (dev.env.supports(.x86_64_backend)) @import("arch/x86_64/Mir.zig") else noreturn,
+ wasm: if (dev.env.supports(.wasm_backend)) @import("arch/wasm/Mir.zig") else noreturn,
+ c: if (dev.env.supports(.c_backend)) @import("codegen/c.zig").Mir else noreturn,
pub inline fn tag(comptime backend: std.builtin.CompilerBackend) []const u8 {
return switch (backend) {
.stage2_aarch64 => "aarch64",
- .stage2_arm => "arm",
.stage2_riscv64 => "riscv64",
.stage2_sparc64 => "sparc64",
.stage2_x86_64 => "x86_64",
@@ -110,7 +122,8 @@ pub const AnyMir = union {
const backend = target_util.zigBackend(&zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm);
switch (backend) {
else => unreachable,
- inline .stage2_riscv64,
+ inline .stage2_aarch64,
+ .stage2_riscv64,
.stage2_sparc64,
.stage2_x86_64,
.stage2_wasm,
@@ -131,14 +144,15 @@ pub fn generateFunction(
src_loc: Zcu.LazySrcLoc,
func_index: InternPool.Index,
air: *const Air,
- liveness: *const Air.Liveness,
+ liveness: *const ?Air.Liveness,
) CodeGenError!AnyMir {
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
switch (target_util.zigBackend(target, false)) {
else => unreachable,
- inline .stage2_riscv64,
+ inline .stage2_aarch64,
+ .stage2_riscv64,
.stage2_sparc64,
.stage2_x86_64,
.stage2_wasm,
@@ -173,7 +187,8 @@ pub fn emitFunction(
const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
switch (target_util.zigBackend(target, zcu.comp.config.use_llvm)) {
else => unreachable,
- inline .stage2_riscv64,
+ inline .stage2_aarch64,
+ .stage2_riscv64,
.stage2_sparc64,
.stage2_x86_64,
=> |backend| {
@@ -420,7 +435,7 @@ pub fn generateSymbol(
const int_tag_ty = ty.intTagType(zcu);
try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
},
- .float => |float| switch (float.storage) {
+ .float => |float| storage: switch (float.storage) {
.f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(gpa, 2)),
.f32 => |f32_val| writeFloat(f32, f32_val, target, endian, try code.addManyAsArray(gpa, 4)),
.f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(gpa, 8)),
@@ -429,7 +444,13 @@ pub fn generateSymbol(
const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
try code.appendNTimes(gpa, 0, abi_size - 10);
},
- .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(gpa, 16)),
+ .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) {
+ else => unreachable,
+ 16 => continue :storage .{ .f16 = @floatCast(f128_val) },
+ 32 => continue :storage .{ .f32 = @floatCast(f128_val) },
+ 64 => continue :storage .{ .f64 = @floatCast(f128_val) },
+ 128 => writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(gpa, 16)),
+ },
},
.ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
.slice => |slice| {
@@ -1218,3 +1239,17 @@ pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
return 0;
}
}
+
+pub fn fieldOffset(ptr_agg_ty: Type, ptr_field_ty: Type, field_index: u32, zcu: *Zcu) u64 {
+ const agg_ty = ptr_agg_ty.childType(zcu);
+ return switch (agg_ty.containerLayout(zcu)) {
+ .auto, .@"extern" => agg_ty.structFieldOffset(field_index, zcu),
+ .@"packed" => @divExact(@as(u64, ptr_agg_ty.ptrInfo(zcu).packed_offset.bit_offset) +
+ (if (zcu.typeToPackedStruct(agg_ty)) |loaded_struct| zcu.structPackedFieldBitOffset(loaded_struct, field_index) else 0) -
+ ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8),
+ };
+}
+
+test {
+ _ = aarch64;
+}