init spork8 backend

This commit is contained in:
Andrew Kelley 2025-05-15 13:11:55 -07:00
parent bc2f7c7547
commit 9f5c1038c3
13 changed files with 719 additions and 9 deletions

View File

@ -104,6 +104,7 @@ pub const Os = struct {
.plan9 => arch.plan9Ext(),
else => switch (arch) {
.wasm32, .wasm64 => ".wasm",
.spork8 => ".spork8",
else => "",
},
};
@ -780,6 +781,22 @@ pub const x86 = @import("Target/x86.zig");
pub const xcore = @import("Target/xcore.zig");
pub const xtensa = @import("Target/xtensa.zig");
pub const spork8 = struct {
pub const Feature = enum {};
pub const featureSet = Cpu.Feature.FeatureSetFns(Feature).featureSet;
pub const featureSetHas = Cpu.Feature.FeatureSetFns(Feature).featureSetHas;
pub const featureSetHasAny = Cpu.Feature.FeatureSetFns(Feature).featureSetHasAny;
pub const featureSetHasAll = Cpu.Feature.FeatureSetFns(Feature).featureSetHasAll;
pub const cpu = struct {
pub const generic: Cpu.Model = .{
.name = "generic",
.llvm_name = null,
.features = .empty,
};
};
};
pub const Abi = enum {
none,
gnu,
@ -1018,6 +1035,7 @@ pub const ObjectFormat = enum {
hex,
/// The Mach object format used by macOS and other Apple platforms.
macho,
spork8,
/// The a.out format used by Plan 9 from Bell Labs.
plan9,
/// Machine code with no metadata.
@ -1038,6 +1056,7 @@ pub const ObjectFormat = enum {
.coff => ".obj",
.elf, .goff, .macho, .wasm, .xcoff => ".o",
.hex => ".ihex",
.spork8 => ".spork8",
.plan9 => arch.plan9Ext(),
.raw => ".bin",
.spirv => ".spv",
@ -1054,6 +1073,7 @@ pub const ObjectFormat = enum {
else => switch (arch) {
.spirv, .spirv32, .spirv64 => .spirv,
.wasm32, .wasm64 => .wasm,
.spork8 => .spork8,
else => .elf,
},
};
@ -1097,6 +1117,7 @@ pub fn toElfMachine(target: Target) std.elf.EM {
.spirv64,
.wasm32,
.wasm64,
.spork8,
=> .NONE,
};
}
@ -1150,6 +1171,7 @@ pub fn toCoffMachine(target: Target) std.coff.MachineType {
.xcore,
.xtensa,
.propeller,
.spork8,
=> .UNKNOWN,
};
}
@ -1369,6 +1391,7 @@ pub const Cpu = struct {
s390x,
sparc,
sparc64,
spork8,
spirv,
spirv32,
spirv64,
@ -1573,6 +1596,7 @@ pub const Cpu = struct {
.sparc64,
.lanai,
.s390x,
.spork8,
=> .big,
};
}
@ -1916,6 +1940,7 @@ pub const Cpu = struct {
.kalimba,
.or1k,
.spork8,
=> &S.generic_model,
};
}
@ -2593,6 +2618,7 @@ pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 {
return switch (cpu.arch) {
.avr,
.msp430,
.spork8,
=> 16,
.arc,
@ -3080,7 +3106,7 @@ pub fn cTypeBitSize(target: Target, c_type: CType) u16 {
pub fn cTypeAlignment(target: Target, c_type: CType) u16 {
// Overrides for unusual alignments
switch (target.cpu.arch) {
.avr => return 1,
.avr, .spork8 => return 1,
.x86 => switch (target.os.tag) {
.windows, .uefi => switch (c_type) {
.longlong, .ulonglong, .double => return 8,
@ -3167,6 +3193,7 @@ pub fn cTypeAlignment(target: Target, c_type: CType) u16 {
=> 16,
.avr,
.spork8,
=> unreachable, // Handled above.
}),
);
@ -3267,7 +3294,9 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 {
pub fn cMaxIntAlignment(target: std.Target) u16 {
return switch (target.cpu.arch) {
.avr => 1,
.avr,
.spork8,
=> 1,
.msp430 => 2,
@ -3390,6 +3419,7 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
.amdgcn => .{ .amdgcn_device = .{} },
.nvptx, .nvptx64 => .nvptx_device,
.spirv, .spirv32, .spirv64 => .spirv_device,
.spork8 => .naked,
};
}

View File

@ -1110,6 +1110,7 @@ pub const CompilerBackend = enum(u64) {
/// The reference implementation self-hosted compiler of Zig, using the
/// spirv backend.
stage2_spirv64 = 11,
stage2_spork8 = 12,
_,
};

View File

@ -26,7 +26,9 @@ comptime {
// decls there get run.
_ = root;
if (simplified_logic) {
if (builtin.cpu.arch == .spork8) {
// always freestanding, even exes
} else if (simplified_logic) {
if (builtin.output_mode == .Exe) {
if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) {
if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) {

View File

@ -223,6 +223,7 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe
.spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}),
.hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}),
.raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
.spork8 => return std.fmt.allocPrint(allocator, "{s}.spork8", .{root_name}),
.plan9 => switch (options.output_mode) {
.Exe => return allocator.dupe(u8, root_name),
.Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{

View File

@ -449,7 +449,7 @@ pub fn resolve(options: Options) ResolveError!Config {
.windows, .uefi => .code_view,
else => .{ .dwarf = .@"32" },
},
.spirv, .hex, .raw, .plan9 => .strip,
.spirv, .hex, .raw, .plan9, .spork8 => .strip,
};
};

View File

@ -3675,6 +3675,8 @@ pub fn atomicPtrAlignment(
) AtomicPtrAlignmentError!Alignment {
const target = zcu.getTarget();
const max_atomic_bits: u16 = switch (target.cpu.arch) {
.spork8 => 8,
.avr,
.msp430,
=> 16,
@ -4368,6 +4370,10 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
.spirv_fragment, .spirv_vertex => target.os.tag == .vulkan,
else => false,
},
.stage2_spork8 => switch (cc) {
.naked => true,
else => false,
},
};
if (!backend_ok) return .{ .bad_backend = backend };
return .ok;

367
src/arch/spork8/CodeGen.zig Normal file
View File

@ -0,0 +1,367 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const CodeGen = @This();
const link = @import("../../link.zig");
const Spork8 = link.File.Spork8;
const Zcu = @import("../../Zcu.zig");
const InternPool = @import("../../InternPool.zig");
const Air = @import("../../Air.zig");
const Liveness = @import("../../Liveness.zig");
const Mir = @import("Mir.zig");
air: Air,
liveness: Liveness,
gpa: Allocator,
spork8: *Spork8,
pt: Zcu.PerThread,
owner_nav: InternPool.Nav.Index,
func_index: InternPool.Index,
mir_instructions: *std.MultiArrayList(Mir.Inst),
/// Contains extra data for MIR
mir_extra: *std.ArrayListUnmanaged(u32),
start_mir_extra_off: u32,
pub const Error = error{
OutOfMemory,
/// Compiler was asked to operate on a number larger than supported.
Overflow,
/// Indicates the error is already stored in Zcu `failed_codegen`.
CodegenFail,
};
pub const Function = extern struct {
/// Index into `Spork8.mir_instructions`.
mir_off: u32,
/// This is unused except for as a safety slice bound and could be removed.
mir_len: u32,
/// Index into `Spork8.mir_extra`.
mir_extra_off: u32,
/// This is unused except for as a safety slice bound and could be removed.
mir_extra_len: u32,
};
pub fn function(
spork8: *Spork8,
pt: Zcu.PerThread,
func_index: InternPool.Index,
air: Air,
liveness: Liveness,
) Error!Function {
const zcu = pt.zcu;
const gpa = zcu.gpa;
const func_info = zcu.funcInfo(func_index);
var code_gen: CodeGen = .{
.gpa = gpa,
.pt = pt,
.air = air,
.liveness = liveness,
.owner_nav = func_info.owner_nav,
.spork8 = spork8,
.func_index = func_index,
.mir_instructions = &spork8.mir_instructions,
.mir_extra = &spork8.mir_extra,
.start_mir_extra_off = @intCast(spork8.mir_extra.items.len),
};
defer code_gen.deinit();
return functionInner(&code_gen) catch |err| switch (err) {
error.CodegenFail => return error.CodegenFail,
else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}),
};
}
fn deinit(cg: *CodeGen) void {
cg.* = undefined;
}
const InnerError = error{
CodegenFail,
OutOfMemory,
};
fn functionInner(cg: *CodeGen) InnerError!Function {
const spork8 = cg.spork8;
const start_mir_off: u32 = @intCast(spork8.mir_instructions.len);
// Generate MIR for function body
try cg.genBody(cg.air.getMainBody());
return .{
.mir_off = start_mir_off,
.mir_len = @intCast(spork8.mir_instructions.len - start_mir_off),
.mir_extra_off = cg.start_mir_extra_off,
.mir_extra_len = cg.extraLen(),
};
}
fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const zcu = cg.pt.zcu;
const ip = &zcu.intern_pool;
for (body) |inst| {
if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;
try cg.genInst(inst);
}
}
fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const air_tags = cg.air.instructions.items(.tag);
return switch (air_tags[@intFromEnum(inst)]) {
.inferred_alloc, .inferred_alloc_comptime => unreachable,
.unreach => cg.airUnreachable(inst),
.add,
.add_sat,
.add_wrap,
.sub,
.sub_sat,
.sub_wrap,
.mul,
.mul_sat,
.mul_wrap,
.div_float,
.div_exact,
.div_trunc,
.div_floor,
.bit_and,
.bit_or,
.bool_and,
.bool_or,
.rem,
.mod,
.shl,
.shl_exact,
.shl_sat,
.shr,
.shr_exact,
.xor,
.max,
.min,
.mul_add,
.sqrt,
.sin,
.cos,
.tan,
.exp,
.exp2,
.log,
.log2,
.log10,
.floor,
.ceil,
.round,
.trunc_float,
.neg,
.abs,
.add_with_overflow,
.sub_with_overflow,
.shl_with_overflow,
.mul_with_overflow,
.clz,
.ctz,
.cmp_eq,
.cmp_gte,
.cmp_gt,
.cmp_lte,
.cmp_lt,
.cmp_neq,
.cmp_vector,
.cmp_lt_errors_len,
.array_elem_val,
.array_to_slice,
.alloc,
.arg,
.bitcast,
.block,
.trap,
.breakpoint,
.br,
.repeat,
.switch_dispatch,
.cond_br,
.intcast,
.fptrunc,
.fpext,
.int_from_float,
.float_from_int,
.get_union_tag,
.@"try",
.try_cold,
.try_ptr,
.try_ptr_cold,
.dbg_stmt,
.dbg_empty_stmt,
.dbg_inline_block,
.dbg_var_ptr,
.dbg_var_val,
.dbg_arg_inline,
.call,
.call_always_tail,
.call_never_tail,
.call_never_inline,
.is_err,
.is_non_err,
.is_null,
.is_non_null,
.is_null_ptr,
.is_non_null_ptr,
.load,
.loop,
.memset,
.memset_safe,
.not,
.optional_payload,
.optional_payload_ptr,
.optional_payload_ptr_set,
.ptr_add,
.ptr_sub,
.ptr_elem_ptr,
.ptr_elem_val,
.ret,
.ret_safe,
.ret_ptr,
.ret_load,
.splat,
.select,
.shuffle,
.reduce,
.aggregate_init,
.union_init,
.prefetch,
.popcount,
.byte_swap,
.bit_reverse,
.slice,
.slice_len,
.slice_elem_val,
.slice_elem_ptr,
.slice_ptr,
.ptr_slice_len_ptr,
.ptr_slice_ptr_ptr,
.store,
.store_safe,
.set_union_tag,
.struct_field_ptr,
.struct_field_ptr_index_0,
.struct_field_ptr_index_1,
.struct_field_ptr_index_2,
.struct_field_ptr_index_3,
.struct_field_val,
.field_parent_ptr,
.switch_br,
.loop_switch_br,
.trunc,
.wrap_optional,
.unwrap_errunion_payload,
.unwrap_errunion_payload_ptr,
.unwrap_errunion_err,
.unwrap_errunion_err_ptr,
.wrap_errunion_payload,
.wrap_errunion_err,
.errunion_payload_ptr_set,
.error_name,
.wasm_memory_size,
.wasm_memory_grow,
.memcpy,
.ret_addr,
.tag_name,
.error_set_has_value,
.frame_addr,
.assembly,
.is_err_ptr,
.is_non_err_ptr,
.err_return_trace,
.set_err_return_trace,
.save_err_return_trace_index,
.is_named_enum_value,
.addrspace_cast,
.vector_store_elem,
.c_va_arg,
.c_va_copy,
.c_va_end,
.c_va_start,
.memmove,
.atomic_load,
.atomic_store_unordered,
.atomic_store_monotonic,
.atomic_store_release,
.atomic_store_seq_cst,
.atomic_rmw,
.cmpxchg_weak,
.cmpxchg_strong,
.add_optimized,
.sub_optimized,
.mul_optimized,
.div_float_optimized,
.div_trunc_optimized,
.div_floor_optimized,
.div_exact_optimized,
.rem_optimized,
.mod_optimized,
.neg_optimized,
.cmp_lt_optimized,
.cmp_lte_optimized,
.cmp_eq_optimized,
.cmp_gte_optimized,
.cmp_gt_optimized,
.cmp_neq_optimized,
.cmp_vector_optimized,
.reduce_optimized,
.int_from_float_optimized,
.add_safe,
.sub_safe,
.mul_safe,
.intcast_safe,
=> |tag| return cg.fail("TODO: implement spork8 inst: {s}", .{@tagName(tag)}),
.work_item_id,
.work_group_size,
.work_group_id,
=> unreachable,
};
}
fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
_ = cg;
_ = inst;
}
fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
const zcu = cg.pt.zcu;
const func = zcu.funcInfo(cg.func_index);
return zcu.codegenFail(func.owner_nav, fmt, args);
}
fn extraLen(cg: *const CodeGen) u32 {
return @intCast(cg.mir_extra.items.len - cg.start_mir_extra_off);
}

46
src/arch/spork8/Mir.zig Normal file
View File

@ -0,0 +1,46 @@
const Mir = @This();
const InternPool = @import("../../InternPool.zig");
const builtin = @import("builtin");
const std = @import("std");
const assert = std.debug.assert;
instruction_tags: []const Inst.Tag,
instruction_datas: []const Inst.Data,
extra: []const u32,
pub const Inst = struct {
tag: Tag,
data: Data,
/// The position of a given MIR isntruction with the instruction list.
pub const Index = enum(u32) {
_,
};
pub const Tag = enum(u8) {
/// imm8
set_page_i = 0x04,
/// imm8
set_addr_i = 0x09,
/// imm8
load_i = 0x10,
/// index
jump,
};
/// All instructions contain a 4-byte payload, which is contained within
/// this union. `Tag` determines which union tag is active, as well as
/// how to interpret the data within.
pub const Data = union {
imm8: u8,
index: Index,
comptime {
switch (builtin.mode) {
.Debug, .ReleaseSafe => {},
.ReleaseFast, .ReleaseSmall => assert(@sizeOf(Data) == 4),
}
}
};
};

View File

@ -100,6 +100,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
.kalimba,
.or1k,
.propeller,
.spork8,
=> unreachable, // Gated by hasLlvmSupport().
};
@ -457,6 +458,7 @@ pub fn dataLayout(target: std.Target) []const u8 {
.kalimba,
.or1k,
.propeller,
.spork8,
=> unreachable, // Gated by hasLlvmSupport().
};
}

View File

@ -34,6 +34,10 @@ pub const Env = enum {
/// - `zig build-* -fno-llvm -fno-lld -target wasm32-* --listen=-`
wasm,
/// - sema
/// - `zig build-* -fno-llvm -fno-lld -target spork8-* --listen=-`
spork8,
pub inline fn supports(comptime dev_env: Env, comptime feature: Feature) bool {
return switch (dev_env) {
.full => true,
@ -73,6 +77,7 @@ pub const Env = enum {
.riscv64_backend,
.sparc64_backend,
.spirv64_backend,
.spork8_backend,
.lld_linker,
.coff_linker,
.elf_linker,
@ -83,6 +88,7 @@ pub const Env = enum {
.plan9_linker,
.goff_linker,
.xcoff_linker,
.spork8_linker,
=> true,
.cc_command,
.translate_c_command,
@ -158,6 +164,14 @@ pub const Env = enum {
=> true,
else => Env.sema.supports(feature),
},
.spork8 => switch (feature) {
.stdio_listen,
.incremental,
.spork8_backend,
.spork8_linker,
=> true,
else => Env.sema.supports(feature),
},
};
}
@ -219,6 +233,7 @@ pub const Feature = enum {
riscv64_backend,
sparc64_backend,
spirv64_backend,
spork8_backend,
lld_linker,
coff_linker,
@ -230,6 +245,7 @@ pub const Feature = enum {
plan9_linker,
goff_linker,
xcoff_linker,
spork8_linker,
};
/// Makes the code following the call to this function unreachable if `feature` is disabled.

View File

@ -598,6 +598,7 @@ pub const File = struct {
});
},
.c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
.spork8 => dev.check(.spork8_linker),
}
}
@ -671,6 +672,7 @@ pub const File = struct {
}
},
.c, .spirv => dev.checkAny(&.{ .c_linker, .spirv_linker }),
.spork8 => dev.check(.spork8_linker),
}
}
@ -1245,6 +1247,7 @@ pub const File = struct {
c,
wasm,
spirv,
spork8,
plan9,
goff,
xcoff,
@ -1260,6 +1263,7 @@ pub const File = struct {
.plan9 => Plan9,
.goff => Goff,
.xcoff => Xcoff,
.spork8 => Spork8,
};
}
@ -1274,6 +1278,7 @@ pub const File = struct {
.spirv => .spirv,
.goff => .goff,
.xcoff => .xcoff,
.spork8 => .spork8,
.hex => @panic("TODO implement hex object format"),
.raw => @panic("TODO implement raw object format"),
};
@ -1373,6 +1378,7 @@ pub const File = struct {
pub const C = @import("link/C.zig");
pub const Coff = @import("link/Coff.zig");
pub const Spork8 = @import("link/Spork8.zig");
pub const Plan9 = @import("link/Plan9.zig");
pub const Elf = @import("link/Elf.zig");
pub const MachO = @import("link/MachO.zig");

228
src/link/Spork8.zig Normal file
View File

@ -0,0 +1,228 @@
const Spork8 = @This();
const builtin = @import("builtin");
const build_options = @import("build_options");
const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const Path = std.Build.Cache.Path;
const log = std.log.scoped(.link);
const Air = @import("../Air.zig");
const InternPool = @import("../InternPool.zig");
const Zcu = @import("../Zcu.zig");
const CodeGen = @import("../arch/spork8/CodeGen.zig");
const Mir = @import("../arch/spork8/Mir.zig");
const link = @import("../link.zig");
const Compilation = @import("../Compilation.zig");
const Liveness = @import("../Liveness.zig");
const dev = @import("../dev.zig");
const Value = @import("../Value.zig");
base: link.File,
funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, CodeGen.Function) = .empty,
/// All MIR instructions for all Zcu functions.
mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
/// Corresponds to `mir_instructions`.
mir_extra: std.ArrayListUnmanaged(u32) = .empty,
pub fn open(
arena: Allocator,
comp: *Compilation,
emit: Path,
options: link.File.OpenOptions,
) !*Spork8 {
// TODO: restore saved linker state, don't truncate the file, and
// participate in incremental compilation.
return createEmpty(arena, comp, emit, options);
}
pub fn createEmpty(
arena: Allocator,
comp: *Compilation,
emit: Path,
options: link.File.OpenOptions,
) !*Spork8 {
const target = comp.root_mod.resolved_target.result;
assert(target.ofmt == .spork8);
assert(comp.config.output_mode == .Exe);
const spork8 = try arena.create(Spork8);
spork8.* = .{
.base = .{
.tag = .spork8,
.comp = comp,
.emit = emit,
.zcu_object_sub_path = null,
.gc_sections = options.gc_sections orelse true,
.print_gc_sections = options.print_gc_sections,
.stack_size = options.stack_size orelse switch (target.os.tag) {
.freestanding => 1 * 1024 * 1024, // 1 MiB
else => 16 * 1024 * 1024, // 16 MiB
},
.allow_shlib_undefined = options.allow_shlib_undefined orelse false,
.file = null,
.disable_lld_caching = options.disable_lld_caching,
.build_id = options.build_id,
},
};
errdefer spork8.base.destroy();
spork8.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{
.truncate = true,
.read = true,
});
return spork8;
}
pub fn deinit(spork8: *Spork8) void {
const gpa = spork8.base.comp.gpa;
_ = gpa;
}
pub fn updateFunc(
spork8: *Spork8,
pt: Zcu.PerThread,
func_index: InternPool.Index,
air: Air,
liveness: Liveness,
) !void {
if (build_options.skip_non_native and builtin.object_format != .spork8) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
dev.check(.spork8_backend);
const zcu = pt.zcu;
const gpa = spork8.base.comp.gpa;
const ip = &zcu.intern_pool;
const owner_nav = zcu.funcInfo(func_index).owner_nav;
log.debug("updateFunc {}", .{ip.getNav(owner_nav).fqn.fmt(ip)});
const function = try CodeGen.function(spork8, pt, func_index, air, liveness);
try spork8.funcs.put(gpa, func_index, function);
}
// Generate code for the "Nav", storing it in memory to be later written to
// the file on flush().
pub fn updateNav(spork8: *Spork8, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
_ = spork8;
if (build_options.skip_non_native and builtin.object_format != .spork8) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const nav = ip.getNav(nav_index);
const nav_init, const chased_nav_index = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
.func => return, // global const which is a function alias
.@"extern" => |ext| {
_ = ext;
@panic("TODO updateNav extern func");
},
.variable => |variable| .{ variable.init, variable.owner_nav },
else => .{ nav.status.fully_resolved.val, nav_index },
};
log.debug("updateNav {} {d}", .{ nav.fqn.fmt(ip), chased_nav_index });
if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) {
return;
}
}
pub fn updateLineNumber(spork8: *Spork8, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
_ = spork8;
_ = pt;
_ = ti_id;
}
pub fn deleteExport(
spork8: *Spork8,
exported: Zcu.Exported,
name: InternPool.NullTerminatedString,
) void {
const zcu = spork8.base.comp.zcu.?;
const ip = &zcu.intern_pool;
const name_slice = name.toSlice(ip);
switch (exported) {
.nav => |nav_index| {
log.debug("deleteExport '{s}' nav={d}", .{ name_slice, @intFromEnum(nav_index) });
},
.uav => |uav_index| {
log.debug("deleteExport '{s}' uav={d}", .{ name_slice, @intFromEnum(uav_index) });
},
}
}
pub fn updateExports(
spork8: *Spork8,
pt: Zcu.PerThread,
exported: Zcu.Exported,
export_indices: []const Zcu.Export.Index,
) !void {
_ = spork8;
if (build_options.skip_non_native and builtin.object_format != .spork8) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
for (export_indices) |export_idx| {
const exp = export_idx.ptr(zcu);
const name_slice = exp.opts.name.toSlice(ip);
switch (exported) {
.nav => |nav_index| {
log.debug("updateExports '{s}' nav={d}", .{ name_slice, @intFromEnum(nav_index) });
},
.uav => |uav_index| {
log.debug("updateExports '{s}' uav={d}", .{ name_slice, @intFromEnum(uav_index) });
},
}
}
}
pub fn loadInput(spork8: *Spork8, input: link.Input) !void {
_ = input;
const comp = spork8.base.comp;
const diags = &comp.link_diags;
return diags.failParse("spork8 does not support linking files together", .{});
}
pub fn flush(
spork8: *Spork8,
arena: Allocator,
tid: Zcu.PerThread.Id,
prog_node: std.Progress.Node,
) link.File.FlushError!void {
return spork8.flushModule(arena, tid, prog_node);
}
pub fn prelink(spork8: *Spork8, prog_node: std.Progress.Node) link.File.FlushError!void {
const sub_prog_node = prog_node.start("Spork8 Prelink", 0);
defer sub_prog_node.end();
_ = spork8;
}
pub fn flushModule(
spork8: *Spork8,
arena: Allocator,
tid: Zcu.PerThread.Id,
prog_node: std.Progress.Node,
) link.File.FlushError!void {
// The goal is to never use this because it's only needed if we need to
// write to InternPool, but flushModule is too late to be writing to the
// InternPool.
_ = tid;
const comp = spork8.base.comp;
const diags = &comp.link_diags;
const sub_prog_node = prog_node.start("Spork8 Flush", 0);
defer sub_prog_node.end();
_ = arena;
return diags.fail("TODO implement flushModule for spork8", .{});
}

View File

@ -133,6 +133,7 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
// LLVM does not support these object formats:
.c,
.plan9,
.spork8,
=> return false,
.coff,
@ -200,6 +201,7 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
.kalimba,
.or1k,
.propeller,
.spork8,
=> false,
};
}
@ -323,6 +325,7 @@ pub fn canBuildLibCompilerRt(target: std.Target, use_llvm: bool, have_llvm: bool
else => {},
}
switch (target.cpu.arch) {
.spork8 => return false,
.spirv, .spirv32, .spirv64 => return false,
// Remove this once https://github.com/ziglang/zig/issues/23714 is fixed
.amdgcn => return false,
@ -336,12 +339,13 @@ pub fn canBuildLibCompilerRt(target: std.Target, use_llvm: bool, have_llvm: bool
}
pub fn canBuildLibUbsanRt(target: std.Target) bool {
switch (target.cpu.arch) {
.spirv, .spirv32, .spirv64 => return false,
return switch (target.cpu.arch) {
.spork8 => false,
.spirv, .spirv32, .spirv64 => false,
// Remove this once https://github.com/ziglang/zig/issues/23715 is fixed
.nvptx, .nvptx64 => return false,
else => return true,
}
.nvptx, .nvptx64 => false,
else => true,
};
}
pub fn hasRedZone(target: std.Target) bool {
@ -804,6 +808,7 @@ pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBacken
.riscv64 => .stage2_riscv64,
.sparc64 => .stage2_sparc64,
.spirv64 => .stage2_spirv64,
.spork8 => .stage2_spork8,
else => .other,
};
}