mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
Merge pull request #15505 from jacobly0/x86_64-behavior
x86_64: fixes for behavior tests
This commit is contained in:
commit
a2e2e25165
@ -18,7 +18,7 @@ const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start";
|
||||
// Until then, we have simplified logic here for self-hosted. TODO remove this once
|
||||
// self-hosted is capable enough to handle all of the real start.zig logic.
|
||||
pub const simplified_logic =
|
||||
(builtin.zig_backend == .stage2_x86_64 and (builtin.link_libc or builtin.os.tag == .plan9)) or
|
||||
(builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .plan9) or
|
||||
builtin.zig_backend == .stage2_x86 or
|
||||
builtin.zig_backend == .stage2_aarch64 or
|
||||
builtin.zig_backend == .stage2_arm or
|
||||
|
||||
@ -13,7 +13,6 @@ var fba = std.heap.FixedBufferAllocator.init(&cmdline_buffer);
|
||||
|
||||
pub fn main() void {
|
||||
if (builtin.zig_backend == .stage2_wasm or
|
||||
(builtin.zig_backend == .stage2_x86_64 and builtin.os.tag != .linux) or
|
||||
builtin.zig_backend == .stage2_aarch64)
|
||||
{
|
||||
return mainSimple() catch @panic("test failure");
|
||||
@ -234,25 +233,33 @@ pub fn log(
|
||||
/// work-in-progress backends can handle it.
|
||||
pub fn mainSimple() anyerror!void {
|
||||
const enable_print = false;
|
||||
const print_all = false;
|
||||
|
||||
var passed: u64 = 0;
|
||||
var skipped: u64 = 0;
|
||||
var failed: u64 = 0;
|
||||
const stderr = if (enable_print) std.io.getStdErr() else {};
|
||||
for (builtin.test_functions) |test_fn| {
|
||||
if (enable_print and print_all) {
|
||||
stderr.writeAll(test_fn.name) catch {};
|
||||
stderr.writeAll("... ") catch {};
|
||||
}
|
||||
test_fn.func() catch |err| {
|
||||
if (enable_print) stderr.writeAll(test_fn.name) catch {};
|
||||
if (enable_print and !print_all) {
|
||||
stderr.writeAll(test_fn.name) catch {};
|
||||
stderr.writeAll("... ") catch {};
|
||||
}
|
||||
if (err != error.SkipZigTest) {
|
||||
if (enable_print) stderr.writeAll("... FAIL\n") catch {};
|
||||
if (enable_print) stderr.writeAll("FAIL\n") catch {};
|
||||
failed += 1;
|
||||
if (!enable_print) return err;
|
||||
continue;
|
||||
}
|
||||
if (enable_print) stderr.writeAll("... SKIP\n") catch {};
|
||||
if (enable_print) stderr.writeAll("SKIP\n") catch {};
|
||||
skipped += 1;
|
||||
continue;
|
||||
};
|
||||
//if (enable_print) stderr.writeAll("... PASS\n") catch {};
|
||||
if (enable_print and print_all) stderr.writeAll("PASS\n") catch {};
|
||||
passed += 1;
|
||||
}
|
||||
if (enable_print) {
|
||||
|
||||
@ -23287,8 +23287,7 @@ fn panicWithMsg(
|
||||
const arena = sema.arena;
|
||||
|
||||
if (!mod.backendSupportsFeature(.panic_fn)) {
|
||||
_ = try block.addNoOp(.breakpoint);
|
||||
_ = try block.addNoOp(.unreach);
|
||||
_ = try block.addNoOp(.trap);
|
||||
return;
|
||||
}
|
||||
const panic_fn = try sema.getBuiltin("panic");
|
||||
@ -23336,8 +23335,7 @@ fn panicUnwrapError(
|
||||
|
||||
{
|
||||
if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {
|
||||
_ = try fail_block.addNoOp(.breakpoint);
|
||||
_ = try fail_block.addNoOp(.unreach);
|
||||
_ = try fail_block.addNoOp(.trap);
|
||||
} else {
|
||||
const panic_fn = try sema.getBuiltin("panicUnwrapError");
|
||||
const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
|
||||
@ -23462,8 +23460,7 @@ fn safetyCheckFormatted(
|
||||
defer fail_block.instructions.deinit(gpa);
|
||||
|
||||
if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {
|
||||
_ = try fail_block.addNoOp(.breakpoint);
|
||||
_ = try fail_block.addNoOp(.unreach);
|
||||
_ = try fail_block.addNoOp(.trap);
|
||||
} else {
|
||||
const panic_fn = try sema.getBuiltin(func);
|
||||
_ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@ pub fn findByMnemonic(
|
||||
next: for (mnemonic_to_encodings_map[@enumToInt(mnemonic)]) |data| {
|
||||
switch (data.mode) {
|
||||
.rex => if (!rex_required) continue,
|
||||
.long, .sse2_long => {},
|
||||
.long, .sse_long, .sse2_long => {},
|
||||
else => if (rex_required) continue,
|
||||
}
|
||||
for (input_ops, data.ops) |input_op, data_op|
|
||||
@ -90,7 +90,7 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {
|
||||
if (prefixes.rex.w) {
|
||||
switch (data.mode) {
|
||||
.short, .fpu, .sse, .sse2, .sse4_1, .none => continue,
|
||||
.long, .sse2_long, .rex => {},
|
||||
.long, .sse_long, .sse2_long, .rex => {},
|
||||
}
|
||||
} else if (prefixes.rex.present and !prefixes.rex.isSet()) {
|
||||
switch (data.mode) {
|
||||
@ -138,7 +138,7 @@ pub fn modRmExt(encoding: Encoding) u3 {
|
||||
pub fn operandBitSize(encoding: Encoding) u64 {
|
||||
switch (encoding.data.mode) {
|
||||
.short => return 16,
|
||||
.long, .sse2_long => return 64,
|
||||
.long, .sse_long, .sse2_long => return 64,
|
||||
else => {},
|
||||
}
|
||||
const bit_size: u64 = switch (encoding.data.op_en) {
|
||||
@ -163,7 +163,7 @@ pub fn format(
|
||||
_ = options;
|
||||
_ = fmt;
|
||||
switch (encoding.data.mode) {
|
||||
.long, .sse2_long => try writer.writeAll("REX.W + "),
|
||||
.long, .sse_long, .sse2_long => try writer.writeAll("REX.W + "),
|
||||
else => {},
|
||||
}
|
||||
|
||||
@ -269,21 +269,25 @@ pub const Mnemonic = enum {
|
||||
// SSE
|
||||
addss,
|
||||
cmpss,
|
||||
cvtsi2ss,
|
||||
divss,
|
||||
maxss, minss,
|
||||
movss,
|
||||
mulss,
|
||||
subss,
|
||||
ucomiss,
|
||||
xorps,
|
||||
// SSE2
|
||||
addsd,
|
||||
//cmpsd,
|
||||
cvtsd2ss, cvtsi2sd, cvtss2sd,
|
||||
divsd,
|
||||
maxsd, minsd,
|
||||
movq, //movd, movsd,
|
||||
mulsd,
|
||||
subsd,
|
||||
ucomisd,
|
||||
xorpd,
|
||||
// SSE4.1
|
||||
roundss,
|
||||
roundsd,
|
||||
@ -318,7 +322,7 @@ pub const Op = enum {
|
||||
m,
|
||||
moffs,
|
||||
sreg,
|
||||
xmm, xmm_m32, xmm_m64,
|
||||
xmm, xmm_m32, xmm_m64, xmm_m128,
|
||||
// zig fmt: on
|
||||
|
||||
pub fn fromOperand(operand: Instruction.Operand) Op {
|
||||
@ -400,7 +404,7 @@ pub const Op = enum {
|
||||
.imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,
|
||||
.imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64,
|
||||
.m80 => 80,
|
||||
.m128, .xmm => 128,
|
||||
.m128, .xmm, .xmm_m128 => 128,
|
||||
};
|
||||
}
|
||||
|
||||
@ -423,8 +427,8 @@ pub const Op = enum {
|
||||
.al, .ax, .eax, .rax,
|
||||
.r8, .r16, .r32, .r64,
|
||||
.rm8, .rm16, .rm32, .rm64,
|
||||
.xmm, .xmm_m32, .xmm_m64,
|
||||
=> true,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
// zig fmt: on
|
||||
@ -449,7 +453,7 @@ pub const Op = enum {
|
||||
.rm8, .rm16, .rm32, .rm64,
|
||||
.m8, .m16, .m32, .m64, .m80, .m128,
|
||||
.m,
|
||||
.xmm_m32, .xmm_m64,
|
||||
.xmm_m32, .xmm_m64, .xmm_m128,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
@ -470,13 +474,13 @@ pub const Op = enum {
|
||||
.r8, .r16, .r32, .r64 => .general_purpose,
|
||||
.rm8, .rm16, .rm32, .rm64 => .general_purpose,
|
||||
.sreg => .segment,
|
||||
.xmm, .xmm_m32, .xmm_m64 => .floating_point,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isFloatingPointRegister(op: Op) bool {
|
||||
return switch (op) {
|
||||
.xmm, .xmm_m32, .xmm_m64 => true,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128 => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
@ -535,6 +539,7 @@ pub const Mode = enum {
|
||||
rex,
|
||||
long,
|
||||
sse,
|
||||
sse_long,
|
||||
sse2,
|
||||
sse2_long,
|
||||
sse4_1,
|
||||
|
||||
@ -95,6 +95,7 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction {
|
||||
|
||||
.addss,
|
||||
.cmpss,
|
||||
.cvtsi2ss,
|
||||
.divss,
|
||||
.maxss,
|
||||
.minss,
|
||||
@ -103,8 +104,12 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction {
|
||||
.roundss,
|
||||
.subss,
|
||||
.ucomiss,
|
||||
.xorps,
|
||||
.addsd,
|
||||
.cmpsd,
|
||||
.cvtsd2ss,
|
||||
.cvtsi2sd,
|
||||
.cvtss2sd,
|
||||
.divsd,
|
||||
.maxsd,
|
||||
.minsd,
|
||||
@ -113,6 +118,7 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction {
|
||||
.roundsd,
|
||||
.subsd,
|
||||
.ucomisd,
|
||||
.xorpd,
|
||||
=> try lower.mirGeneric(inst),
|
||||
|
||||
.cmps,
|
||||
|
||||
@ -170,6 +170,8 @@ pub const Inst = struct {
|
||||
addss,
|
||||
/// Compare scalar single-precision floating-point values
|
||||
cmpss,
|
||||
/// Convert doubleword integer to scalar single-precision floating-point value
|
||||
cvtsi2ss,
|
||||
/// Divide scalar single-precision floating-point values
|
||||
divss,
|
||||
/// Return maximum single-precision floating-point value
|
||||
@ -186,10 +188,18 @@ pub const Inst = struct {
|
||||
subss,
|
||||
/// Unordered compare scalar single-precision floating-point values
|
||||
ucomiss,
|
||||
/// Bitwise logical xor of packed single precision floating-point values
|
||||
xorps,
|
||||
/// Add double precision floating point values
|
||||
addsd,
|
||||
/// Compare scalar double-precision floating-point values
|
||||
cmpsd,
|
||||
/// Convert scalar double-precision floating-point value to scalar single-precision floating-point value
|
||||
cvtsd2ss,
|
||||
/// Convert doubleword integer to scalar double-precision floating-point value
|
||||
cvtsi2sd,
|
||||
/// Convert scalar single-precision floating-point value to scalar double-precision floating-point value
|
||||
cvtss2sd,
|
||||
/// Divide scalar double-precision floating-point values
|
||||
divsd,
|
||||
/// Return maximum double-precision floating-point value
|
||||
@ -206,6 +216,8 @@ pub const Inst = struct {
|
||||
subsd,
|
||||
/// Unordered compare scalar double-precision floating-point values
|
||||
ucomisd,
|
||||
/// Bitwise logical xor of packed double precision floating-point values
|
||||
xorpd,
|
||||
|
||||
/// Compare string operands
|
||||
cmps,
|
||||
|
||||
@ -323,7 +323,7 @@ pub const Instruction = struct {
|
||||
var rex = Rex{};
|
||||
rex.present = inst.encoding.data.mode == .rex;
|
||||
switch (inst.encoding.data.mode) {
|
||||
.long, .sse2_long => rex.w = true,
|
||||
.long, .sse_long, .sse2_long => rex.w = true,
|
||||
else => {},
|
||||
}
|
||||
|
||||
|
||||
@ -834,6 +834,9 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse },
|
||||
|
||||
.{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .sse },
|
||||
.{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .sse_long },
|
||||
|
||||
.{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse },
|
||||
|
||||
.{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse },
|
||||
@ -849,11 +852,20 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .sse },
|
||||
|
||||
.{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .sse },
|
||||
|
||||
// SSE2
|
||||
.{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 },
|
||||
|
||||
.{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 },
|
||||
|
||||
.{ .cvtsd2ss, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .sse2 },
|
||||
|
||||
.{ .cvtsi2sd, .rm, &.{ .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .sse2 },
|
||||
.{ .cvtsi2sd, .rm, &.{ .xmm, .rm64 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .sse2_long },
|
||||
|
||||
.{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .sse2 },
|
||||
|
||||
.{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 },
|
||||
|
||||
.{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 },
|
||||
@ -878,6 +890,8 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .ucomisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 },
|
||||
|
||||
.{ .xorpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .sse2 },
|
||||
|
||||
// SSE4.1
|
||||
.{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 },
|
||||
.{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 },
|
||||
|
||||
157
src/codegen.zig
157
src/codegen.zig
@ -7,6 +7,7 @@ const link = @import("link.zig");
|
||||
const log = std.log.scoped(.codegen);
|
||||
const mem = std.mem;
|
||||
const math = std.math;
|
||||
const target_util = @import("target.zig");
|
||||
const trace = @import("tracy.zig").trace;
|
||||
|
||||
const Air = @import("Air.zig");
|
||||
@ -89,25 +90,36 @@ pub fn generateFunction(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateLazyFunction(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
switch (bin_file.options.target.cpu.arch) {
|
||||
.x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(bin_file, src_loc, lazy_sym, code, debug_output),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian, code: []u8) void {
|
||||
_ = target;
|
||||
const Int = @Type(.{ .Int = .{
|
||||
.signedness = .unsigned,
|
||||
.bits = @typeInfo(F).Float.bits,
|
||||
} });
|
||||
const bits = @typeInfo(F).Float.bits;
|
||||
const Int = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = bits } });
|
||||
const int = @bitCast(Int, f);
|
||||
mem.writeInt(Int, code[0..@sizeOf(Int)], int, endian);
|
||||
mem.writeInt(Int, code[0..@divExact(bits, 8)], int, endian);
|
||||
}
|
||||
|
||||
pub fn generateLazySymbol(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
alignment: *u32,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
reloc_info: RelocInfo,
|
||||
) CodeGenError!Result {
|
||||
_ = debug_output;
|
||||
_ = reloc_info;
|
||||
|
||||
const tracy = trace(@src());
|
||||
@ -122,7 +134,13 @@ pub fn generateLazySymbol(
|
||||
lazy_sym.ty.fmt(mod),
|
||||
});
|
||||
|
||||
if (lazy_sym.kind == .const_data and lazy_sym.ty.isAnyError()) {
|
||||
if (lazy_sym.kind == .code) {
|
||||
alignment.* = target_util.defaultFunctionAlignment(target);
|
||||
return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);
|
||||
}
|
||||
|
||||
if (lazy_sym.ty.isAnyError()) {
|
||||
alignment.* = 4;
|
||||
const err_names = mod.error_name_list.items;
|
||||
mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
|
||||
var offset = code.items.len;
|
||||
@ -136,6 +154,14 @@ pub fn generateLazySymbol(
|
||||
}
|
||||
mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
|
||||
return Result.ok;
|
||||
} else if (lazy_sym.ty.zigTypeTag() == .Enum) {
|
||||
alignment.* = 1;
|
||||
for (lazy_sym.ty.enumFields().keys()) |tag_name| {
|
||||
try code.ensureUnusedCapacity(tag_name.len + 1);
|
||||
code.appendSliceAssumeCapacity(tag_name);
|
||||
code.appendAssumeCapacity(0);
|
||||
}
|
||||
return Result.ok;
|
||||
} else return .{ .fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
@ -187,18 +213,14 @@ pub fn generateSymbol(
|
||||
};
|
||||
},
|
||||
.Float => {
|
||||
const float_bits = typed_value.ty.floatBits(target);
|
||||
switch (float_bits) {
|
||||
switch (typed_value.ty.floatBits(target)) {
|
||||
16 => writeFloat(f16, typed_value.val.toFloat(f16), target, endian, try code.addManyAsArray(2)),
|
||||
32 => writeFloat(f32, typed_value.val.toFloat(f32), target, endian, try code.addManyAsArray(4)),
|
||||
64 => writeFloat(f64, typed_value.val.toFloat(f64), target, endian, try code.addManyAsArray(8)),
|
||||
80 => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO handle f80 in generateSymbol",
|
||||
.{},
|
||||
),
|
||||
80 => {
|
||||
writeFloat(f80, typed_value.val.toFloat(f80), target, endian, try code.addManyAsArray(10));
|
||||
const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
|
||||
try code.appendNTimes(0, abi_size - 10);
|
||||
},
|
||||
128 => writeFloat(f128, typed_value.val.toFloat(f128), target, endian, try code.addManyAsArray(16)),
|
||||
else => unreachable,
|
||||
@ -291,6 +313,20 @@ pub fn generateSymbol(
|
||||
},
|
||||
},
|
||||
.Pointer => switch (typed_value.val.tag()) {
|
||||
.null_value => {
|
||||
switch (target.cpu.arch.ptrBitWidth()) {
|
||||
32 => {
|
||||
mem.writeInt(u32, try code.addManyAsArray(4), 0, endian);
|
||||
if (typed_value.ty.isSlice()) try code.appendNTimes(0xaa, 4);
|
||||
},
|
||||
64 => {
|
||||
mem.writeInt(u64, try code.addManyAsArray(8), 0, endian);
|
||||
if (typed_value.ty.isSlice()) try code.appendNTimes(0xaa, 8);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
return Result.ok;
|
||||
},
|
||||
.zero, .one, .int_u64, .int_big_positive => {
|
||||
switch (target.cpu.arch.ptrBitWidth()) {
|
||||
32 => {
|
||||
@ -397,30 +433,15 @@ pub fn generateSymbol(
|
||||
},
|
||||
}
|
||||
},
|
||||
.elem_ptr => {
|
||||
const elem_ptr = typed_value.val.castTag(.elem_ptr).?.data;
|
||||
const elem_size = typed_value.ty.childType().abiSize(target);
|
||||
const addend = @intCast(u32, elem_ptr.index * elem_size);
|
||||
const array_ptr = elem_ptr.array_ptr;
|
||||
|
||||
switch (array_ptr.tag()) {
|
||||
.decl_ref => {
|
||||
const decl_index = array_ptr.castTag(.decl_ref).?.data;
|
||||
return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{
|
||||
.parent_atom_index = reloc_info.parent_atom_index,
|
||||
.addend = (reloc_info.addend orelse 0) + addend,
|
||||
});
|
||||
},
|
||||
else => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement generateSymbol for pointer type value: '{s}'",
|
||||
.{@tagName(typed_value.val.tag())},
|
||||
),
|
||||
},
|
||||
}
|
||||
},
|
||||
.elem_ptr => return lowerParentPtr(
|
||||
bin_file,
|
||||
src_loc,
|
||||
typed_value,
|
||||
typed_value.val,
|
||||
code,
|
||||
debug_output,
|
||||
reloc_info,
|
||||
),
|
||||
else => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
@ -838,9 +859,62 @@ pub fn generateSymbol(
|
||||
}
|
||||
}
|
||||
|
||||
fn lowerParentPtr(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
typed_value: TypedValue,
|
||||
parent_ptr: Value,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
reloc_info: RelocInfo,
|
||||
) CodeGenError!Result {
|
||||
const target = bin_file.options.target;
|
||||
|
||||
switch (parent_ptr.tag()) {
|
||||
.elem_ptr => {
|
||||
const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data;
|
||||
return lowerParentPtr(
|
||||
bin_file,
|
||||
src_loc,
|
||||
typed_value,
|
||||
elem_ptr.array_ptr,
|
||||
code,
|
||||
debug_output,
|
||||
reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))),
|
||||
);
|
||||
},
|
||||
.decl_ref => {
|
||||
const decl_index = parent_ptr.castTag(.decl_ref).?.data;
|
||||
return lowerDeclRef(
|
||||
bin_file,
|
||||
src_loc,
|
||||
typed_value,
|
||||
decl_index,
|
||||
code,
|
||||
debug_output,
|
||||
reloc_info,
|
||||
);
|
||||
},
|
||||
else => |t| {
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement lowerParentPtr for type '{s}'",
|
||||
.{@tagName(t)},
|
||||
),
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const RelocInfo = struct {
|
||||
parent_atom_index: u32,
|
||||
addend: ?u32 = null,
|
||||
|
||||
fn offset(ri: RelocInfo, addend: u32) RelocInfo {
|
||||
return .{ .parent_atom_index = ri.parent_atom_index, .addend = (ri.addend orelse 0) + addend };
|
||||
}
|
||||
};
|
||||
|
||||
fn lowerDeclRef(
|
||||
@ -1095,6 +1169,9 @@ pub fn genTypedValue(
|
||||
.Slice => {},
|
||||
else => {
|
||||
switch (typed_value.val.tag()) {
|
||||
.null_value => {
|
||||
return GenResult.mcv(.{ .immediate = 0 });
|
||||
},
|
||||
.int_u64 => {
|
||||
return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(target) });
|
||||
},
|
||||
|
||||
@ -1120,8 +1120,8 @@ pub const File = struct {
|
||||
kind: Kind,
|
||||
ty: Type,
|
||||
|
||||
pub fn initDecl(kind: Kind, decl: Module.Decl.OptionalIndex, mod: *Module) LazySymbol {
|
||||
return .{ .kind = kind, .ty = if (decl.unwrap()) |decl_index|
|
||||
pub fn initDecl(kind: Kind, decl: ?Module.Decl.Index, mod: *Module) LazySymbol {
|
||||
return .{ .kind = kind, .ty = if (decl) |decl_index|
|
||||
mod.declPtr(decl_index).val.castTag(.ty).?.data
|
||||
else
|
||||
Type.anyerror };
|
||||
|
||||
@ -143,9 +143,11 @@ const Section = struct {
|
||||
const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
|
||||
|
||||
const LazySymbolMetadata = struct {
|
||||
text_atom: ?Atom.Index = null,
|
||||
rdata_atom: ?Atom.Index = null,
|
||||
alignment: u32,
|
||||
const State = enum { unused, pending_flush, flushed };
|
||||
text_atom: Atom.Index = undefined,
|
||||
rdata_atom: Atom.Index = undefined,
|
||||
text_state: State = .unused,
|
||||
rdata_state: State = .unused,
|
||||
};
|
||||
|
||||
const DeclMetadata = struct {
|
||||
@ -1137,7 +1139,11 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
|
||||
return atom.getSymbolIndex().?;
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
pub fn updateDecl(
|
||||
self: *Coff,
|
||||
module: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
) link.File.UpdateDeclError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
@ -1189,32 +1195,16 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbol(self: *Coff, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
|
||||
const mod = self.base.options.module.?;
|
||||
if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
|
||||
link.File.LazySymbol.initDecl(.code, decl, mod),
|
||||
atom,
|
||||
self.text_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
if (metadata.rdata_atom) |atom| try self.updateLazySymbolAtom(
|
||||
link.File.LazySymbol.initDecl(.const_data, decl, mod),
|
||||
atom,
|
||||
self.rdata_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
self: *Coff,
|
||||
sym: link.File.LazySymbol,
|
||||
atom_index: Atom.Index,
|
||||
section_index: u16,
|
||||
required_alignment: u32,
|
||||
) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
|
||||
var required_alignment: u32 = undefined;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -1235,9 +1225,15 @@ fn updateLazySymbolAtom(
|
||||
.parent_decl_node = undefined,
|
||||
.lazy = .unneeded,
|
||||
};
|
||||
const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
|
||||
.parent_atom_index = local_sym_index,
|
||||
});
|
||||
const res = try codegen.generateLazySymbol(
|
||||
&self.base,
|
||||
src,
|
||||
sym,
|
||||
&required_alignment,
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .parent_atom_index = local_sym_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
@ -1265,20 +1261,27 @@ fn updateLazySymbolAtom(
|
||||
try self.writeAtom(atom_index, code);
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(
|
||||
self: *Coff,
|
||||
sym: link.File.LazySymbol,
|
||||
alignment: u32,
|
||||
) !Atom.Index {
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
errdefer _ = self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
|
||||
const atom = switch (sym.kind) {
|
||||
.code => &gop.value_ptr.text_atom,
|
||||
.const_data => &gop.value_ptr.rdata_atom,
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
.code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },
|
||||
.const_data => .{ .atom = &gop.value_ptr.rdata_atom, .state = &gop.value_ptr.rdata_state },
|
||||
};
|
||||
if (atom.* == null) atom.* = try self.createAtom();
|
||||
return atom.*.?;
|
||||
switch (metadata.state.*) {
|
||||
.unused => metadata.atom.* = try self.createAtom(),
|
||||
.pending_flush => return metadata.atom.*,
|
||||
.flushed => {},
|
||||
}
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.rdata_section_index.?,
|
||||
});
|
||||
return atom;
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {
|
||||
@ -1410,7 +1413,7 @@ pub fn updateDeclExports(
|
||||
module: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
) link.File.UpdateDeclExportsError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
@ -1605,16 +1608,34 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
sub_prog_node.activate();
|
||||
defer sub_prog_node.end();
|
||||
|
||||
// Most lazy symbols can be updated when the corresponding decl is,
|
||||
// so we only have to worry about the one without an associated decl.
|
||||
if (self.lazy_syms.get(.none)) |metadata| {
|
||||
self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.FlushFailure,
|
||||
else => |e| return e,
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
|
||||
if (self.lazy_syms.getPtr(.none)) |metadata| {
|
||||
// Most lazy symbols can be updated on first use, but
|
||||
// anyerror needs to wait for everything to be flushed.
|
||||
if (metadata.text_state != .unused) self.updateLazySymbolAtom(
|
||||
link.File.LazySymbol.initDecl(.code, null, module),
|
||||
metadata.text_atom,
|
||||
self.text_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(
|
||||
link.File.LazySymbol.initDecl(.const_data, null, module),
|
||||
metadata.rdata_atom,
|
||||
self.rdata_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
}
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
for (self.lazy_syms.values()) |*metadata| {
|
||||
if (metadata.text_state != .unused) metadata.text_state = .flushed;
|
||||
if (metadata.rdata_state != .unused) metadata.rdata_state = .flushed;
|
||||
}
|
||||
|
||||
while (self.unresolved.popOrNull()) |entry| {
|
||||
assert(entry.value); // We only expect imports generated by the incremental linker for now.
|
||||
|
||||
107
src/link/Elf.zig
107
src/link/Elf.zig
@ -65,9 +65,11 @@ const Section = struct {
|
||||
};
|
||||
|
||||
const LazySymbolMetadata = struct {
|
||||
text_atom: ?Atom.Index = null,
|
||||
rodata_atom: ?Atom.Index = null,
|
||||
alignment: u32,
|
||||
const State = enum { unused, pending_flush, flushed };
|
||||
text_atom: Atom.Index = undefined,
|
||||
rodata_atom: Atom.Index = undefined,
|
||||
text_state: State = .unused,
|
||||
rodata_state: State = .unused,
|
||||
};
|
||||
|
||||
const DeclMetadata = struct {
|
||||
@ -1033,19 +1035,35 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
sub_prog_node.activate();
|
||||
defer sub_prog_node.end();
|
||||
|
||||
// Most lazy symbols can be updated when the corresponding decl is,
|
||||
// so we only have to worry about the one without an associated decl.
|
||||
if (self.lazy_syms.get(.none)) |metadata| {
|
||||
self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.FlushFailure,
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO This linker code currently assumes there is only 1 compilation unit and it
|
||||
// corresponds to the Zig source code.
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
|
||||
if (self.lazy_syms.getPtr(.none)) |metadata| {
|
||||
// Most lazy symbols can be updated on first use, but
|
||||
// anyerror needs to wait for everything to be flushed.
|
||||
if (metadata.text_state != .unused) self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.code, null, module),
|
||||
metadata.text_atom,
|
||||
self.text_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.const_data, null, module),
|
||||
metadata.rodata_atom,
|
||||
self.rodata_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
}
|
||||
for (self.lazy_syms.values()) |*metadata| {
|
||||
if (metadata.text_state != .unused) metadata.text_state = .flushed;
|
||||
if (metadata.rodata_state != .unused) metadata.rodata_state = .flushed;
|
||||
}
|
||||
|
||||
const target_endian = self.base.options.target.cpu.arch.endian();
|
||||
const foreign_endian = target_endian != builtin.cpu.arch.endian();
|
||||
|
||||
@ -2377,16 +2395,27 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol, alignment: u32) !Atom.Index {
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
errdefer _ = self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
|
||||
const atom = switch (sym.kind) {
|
||||
.code => &gop.value_ptr.text_atom,
|
||||
.const_data => &gop.value_ptr.rodata_atom,
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
.code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },
|
||||
.const_data => .{ .atom = &gop.value_ptr.rodata_atom, .state = &gop.value_ptr.rodata_state },
|
||||
};
|
||||
if (atom.* == null) atom.* = try self.createAtom();
|
||||
return atom.*.?;
|
||||
switch (metadata.state.*) {
|
||||
.unused => metadata.atom.* = try self.createAtom(),
|
||||
.pending_flush => return metadata.atom.*,
|
||||
.flushed => {},
|
||||
}
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.rodata_section_index.?,
|
||||
});
|
||||
return atom;
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {
|
||||
@ -2580,7 +2609,11 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
pub fn updateDecl(
|
||||
self: *Elf,
|
||||
module: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
) File.UpdateDeclError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .elf) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
@ -2657,32 +2690,16 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
|
||||
return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbol(self: *Elf, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
|
||||
const mod = self.base.options.module.?;
|
||||
if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.code, decl, mod),
|
||||
atom,
|
||||
self.text_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
if (metadata.rodata_atom) |atom| try self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.const_data, decl, mod),
|
||||
atom,
|
||||
self.rodata_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
self: *Elf,
|
||||
sym: File.LazySymbol,
|
||||
atom_index: Atom.Index,
|
||||
shdr_index: u16,
|
||||
required_alignment: u32,
|
||||
) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
|
||||
var required_alignment: u32 = undefined;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -2707,9 +2724,15 @@ fn updateLazySymbolAtom(
|
||||
.parent_decl_node = undefined,
|
||||
.lazy = .unneeded,
|
||||
};
|
||||
const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
|
||||
.parent_atom_index = local_sym_index,
|
||||
});
|
||||
const res = try codegen.generateLazySymbol(
|
||||
&self.base,
|
||||
src,
|
||||
sym,
|
||||
&required_alignment,
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .parent_atom_index = local_sym_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
@ -2814,7 +2837,7 @@ pub fn updateDeclExports(
|
||||
module: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
) File.UpdateDeclExportsError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .elf) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
||||
@ -236,9 +236,11 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {
|
||||
const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
|
||||
|
||||
const LazySymbolMetadata = struct {
|
||||
text_atom: ?Atom.Index = null,
|
||||
data_const_atom: ?Atom.Index = null,
|
||||
alignment: u32,
|
||||
const State = enum { unused, pending_flush, flushed };
|
||||
text_atom: Atom.Index = undefined,
|
||||
data_const_atom: Atom.Index = undefined,
|
||||
text_state: State = .unused,
|
||||
data_const_state: State = .unused,
|
||||
};
|
||||
|
||||
const TlvSymbolTable = std.AutoArrayHashMapUnmanaged(SymbolWithLoc, Atom.Index);
|
||||
@ -494,16 +496,32 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
sub_prog_node.activate();
|
||||
defer sub_prog_node.end();
|
||||
|
||||
// Most lazy symbols can be updated when the corresponding decl is,
|
||||
// so we only have to worry about the one without an associated decl.
|
||||
if (self.lazy_syms.get(.none)) |metadata| {
|
||||
self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.FlushFailure,
|
||||
else => |e| return e,
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
|
||||
if (self.lazy_syms.getPtr(.none)) |metadata| {
|
||||
// Most lazy symbols can be updated on first use, but
|
||||
// anyerror needs to wait for everything to be flushed.
|
||||
if (metadata.text_state != .unused) self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.code, null, module),
|
||||
metadata.text_atom,
|
||||
self.text_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
if (metadata.data_const_state != .unused) self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.const_data, null, module),
|
||||
metadata.data_const_atom,
|
||||
self.data_const_section_index.?,
|
||||
) catch |err| return switch (err) {
|
||||
error.CodegenFail => error.FlushFailure,
|
||||
else => |e| e,
|
||||
};
|
||||
}
|
||||
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
for (self.lazy_syms.values()) |*metadata| {
|
||||
if (metadata.text_state != .unused) metadata.text_state = .flushed;
|
||||
if (metadata.data_const_state != .unused) metadata.data_const_state = .flushed;
|
||||
}
|
||||
|
||||
if (self.d_sym) |*d_sym| {
|
||||
try d_sym.dwarf.flushModule(module);
|
||||
@ -2037,32 +2055,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
|
||||
try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateLazySymbol(self: *MachO, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
|
||||
const mod = self.base.options.module.?;
|
||||
if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.code, decl, mod),
|
||||
atom,
|
||||
self.text_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
if (metadata.data_const_atom) |atom| try self.updateLazySymbolAtom(
|
||||
File.LazySymbol.initDecl(.const_data, decl, mod),
|
||||
atom,
|
||||
self.data_const_section_index.?,
|
||||
metadata.alignment,
|
||||
);
|
||||
}
|
||||
|
||||
fn updateLazySymbolAtom(
|
||||
self: *MachO,
|
||||
sym: File.LazySymbol,
|
||||
atom_index: Atom.Index,
|
||||
section_index: u8,
|
||||
required_alignment: u32,
|
||||
) !void {
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
|
||||
var required_alignment: u32 = undefined;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
@ -2087,9 +2089,15 @@ fn updateLazySymbolAtom(
|
||||
.parent_decl_node = undefined,
|
||||
.lazy = .unneeded,
|
||||
};
|
||||
const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
|
||||
.parent_atom_index = local_sym_index,
|
||||
});
|
||||
const res = try codegen.generateLazySymbol(
|
||||
&self.base,
|
||||
src,
|
||||
sym,
|
||||
&required_alignment,
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .parent_atom_index = local_sym_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
@ -2108,7 +2116,7 @@ fn updateLazySymbolAtom(
|
||||
errdefer self.freeAtom(atom_index);
|
||||
|
||||
log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
|
||||
log.debug(" (required alignment 0x{x}", .{required_alignment});
|
||||
log.debug(" (required alignment 0x{x})", .{required_alignment});
|
||||
|
||||
atom.size = code.len;
|
||||
symbol.n_value = vaddr;
|
||||
@ -2117,16 +2125,30 @@ fn updateLazySymbolAtom(
|
||||
try self.writeAtom(atom_index, code);
|
||||
}
|
||||
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignment: u32) !Atom.Index {
|
||||
pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.Index {
|
||||
const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
|
||||
errdefer _ = self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
|
||||
const atom = switch (sym.kind) {
|
||||
.code => &gop.value_ptr.text_atom,
|
||||
.const_data => &gop.value_ptr.data_const_atom,
|
||||
errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
|
||||
.code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },
|
||||
.const_data => .{
|
||||
.atom = &gop.value_ptr.data_const_atom,
|
||||
.state = &gop.value_ptr.data_const_state,
|
||||
},
|
||||
};
|
||||
if (atom.* == null) atom.* = try self.createAtom();
|
||||
return atom.*.?;
|
||||
switch (metadata.state.*) {
|
||||
.unused => metadata.atom.* = try self.createAtom(),
|
||||
.pending_flush => return metadata.atom.*,
|
||||
.flushed => {},
|
||||
}
|
||||
metadata.state.* = .pending_flush;
|
||||
const atom = metadata.atom.*;
|
||||
// anyerror needs to be deferred until flushModule
|
||||
if (sym.getDecl() != .none) try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
|
||||
.code => self.text_section_index.?,
|
||||
.const_data => self.data_const_section_index.?,
|
||||
});
|
||||
return atom;
|
||||
}
|
||||
|
||||
fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
|
||||
@ -2357,7 +2379,7 @@ pub fn updateDeclExports(
|
||||
module: *Module,
|
||||
decl_index: Module.Decl.Index,
|
||||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
) File.UpdateDeclExportsError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .macho) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
@ -4147,9 +4169,6 @@ pub fn logSymtab(self: *MachO) void {
|
||||
|
||||
log.debug("stubs entries:", .{});
|
||||
log.debug("{}", .{self.stub_table});
|
||||
|
||||
// log.debug("threadlocal entries:", .{});
|
||||
// log.debug("{}", .{self.tlv_table});
|
||||
}
|
||||
|
||||
pub fn logAtoms(self: *MachO) void {
|
||||
@ -4189,6 +4208,6 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void {
|
||||
sym.n_value,
|
||||
atom.size,
|
||||
atom.file,
|
||||
sym.n_sect,
|
||||
sym.n_sect + 1,
|
||||
});
|
||||
}
|
||||
|
||||
@ -94,14 +94,20 @@ const Writer = struct {
|
||||
for (w.air.instructions.items(.tag), 0..) |tag, i| {
|
||||
const inst = @intCast(Air.Inst.Index, i);
|
||||
switch (tag) {
|
||||
.constant, .const_ty => try w.writeInst(s, inst),
|
||||
.constant, .const_ty => {
|
||||
try w.writeInst(s, inst);
|
||||
try s.writeByte('\n');
|
||||
},
|
||||
else => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn writeBody(w: *Writer, s: anytype, body: []const Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
for (body) |inst| try w.writeInst(s, inst);
|
||||
for (body) |inst| {
|
||||
try w.writeInst(s, inst);
|
||||
try s.writeByte('\n');
|
||||
}
|
||||
}
|
||||
|
||||
fn writeInst(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
@ -336,7 +342,7 @@ const Writer = struct {
|
||||
.work_group_id,
|
||||
=> try w.writeWorkDimension(s, inst),
|
||||
}
|
||||
try s.writeAll(")\n");
|
||||
try s.writeByte(')');
|
||||
}
|
||||
|
||||
fn writeBinOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
|
||||
@ -282,7 +282,6 @@ fn give() anyerror!u128 {
|
||||
|
||||
test "page aligned array on stack" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -491,10 +490,6 @@ test "read 128-bit field from default aligned struct in global memory" {
|
||||
}
|
||||
|
||||
test "struct field explicit alignment" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) {
|
||||
// Careful enabling this test, fails randomly.
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -112,7 +112,6 @@ test "128-bit cmpxchg" {
|
||||
if (!supports_128_bit_atomics) return error.SkipZigTest;
|
||||
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -363,7 +363,8 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
|
||||
}
|
||||
|
||||
test "take address of parameter" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -391,7 +392,8 @@ test "array 2D const double ptr" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const rect_2d_vertexes = [_][1]f32{
|
||||
@ -405,7 +407,8 @@ test "array 2D const double ptr with offset" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
|
||||
const rect_2d_vertexes = [_][2]f32{
|
||||
@ -419,7 +422,8 @@ test "array 3D const double ptr with offset" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const rect_3d_vertexes = [_][2][2]f32{
|
||||
|
||||
@ -6,6 +6,8 @@ test {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
var opt_x: ?[3]f32 = [_]f32{0.0} ** 3;
|
||||
|
||||
|
||||
@ -95,7 +95,9 @@ test "comptime_int @intToFloat" {
|
||||
|
||||
test "@intToFloat" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -634,7 +636,8 @@ test "vector casts" {
|
||||
}
|
||||
|
||||
test "@floatCast cast down" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -940,6 +940,8 @@ test "constant enum initialization with differing sizes" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try test3_1(test3_foo);
|
||||
try test3_2(test3_bar);
|
||||
@ -979,7 +981,6 @@ fn test3_2(f: Test3Foo) !void {
|
||||
}
|
||||
|
||||
test "@tagName" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -995,7 +996,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 {
|
||||
const BareNumber = enum { One, Two, Three };
|
||||
|
||||
test "@tagName non-exhaustive enum" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1006,7 +1006,6 @@ test "@tagName non-exhaustive enum" {
|
||||
const NonExhaustive = enum(u8) { A, B, _ };
|
||||
|
||||
test "@tagName is null-terminated" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1021,7 +1020,6 @@ test "@tagName is null-terminated" {
|
||||
}
|
||||
|
||||
test "tag name with assigned enum values" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1111,7 +1109,6 @@ test "enum literal in array literal" {
|
||||
|
||||
test "tag name functions are unique" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -535,6 +535,8 @@ test "static eval list init" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(static_vec3.data[2] == 1.0);
|
||||
try expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
|
||||
|
||||
@ -904,7 +904,8 @@ test "negation f16" {
|
||||
}
|
||||
|
||||
test "negation f32" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -924,7 +925,8 @@ test "negation f32" {
|
||||
}
|
||||
|
||||
test "negation f64" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1021,7 +1023,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
|
||||
|
||||
test "comptime fixed-width float non-zero divided by zero produces signed Inf" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1060,7 +1061,8 @@ test "nan negation f16" {
|
||||
}
|
||||
|
||||
test "nan negation f32" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1080,7 +1082,8 @@ test "nan negation f32" {
|
||||
|
||||
test "nan negation f64" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -338,6 +338,8 @@ test "function call with anon list literal" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -358,6 +360,8 @@ test "function call with anon list literal - 2D" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@ -59,6 +59,8 @@ test "fn with comptime args" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(gimmeTheBigOne(1234, 5678) == 5678);
|
||||
try expect(shouldCallSameInstance(34, 12) == 34);
|
||||
@ -69,6 +71,8 @@ test "anytype params" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(max_i32(12, 34) == 34);
|
||||
try expect(max_f64(1.2, 3.4) == 3.4);
|
||||
|
||||
@ -94,7 +94,6 @@ test "inline else error" {
|
||||
|
||||
test "inline else enum" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };
|
||||
|
||||
@ -203,6 +203,8 @@ test "float equality" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const x: f64 = 0.012;
|
||||
const y: f64 = x + 1.0;
|
||||
@ -377,7 +379,6 @@ fn testBinaryNot(x: u16) !void {
|
||||
|
||||
test "binary not 128-bit" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1533,7 +1534,6 @@ test "signed zeros are represented properly" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
|
||||
@ -8,6 +8,8 @@ test "@max" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -54,6 +56,8 @@ test "@min" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@ -114,7 +114,7 @@ test "memset with large array element, runtime known" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
|
||||
|
||||
const A = [128]u64;
|
||||
var buf: [5]A = undefined;
|
||||
@ -132,7 +132,7 @@ test "memset with large array element, comptime known" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
|
||||
|
||||
const A = [128]u64;
|
||||
var buf: [5]A = undefined;
|
||||
|
||||
@ -206,7 +206,8 @@ test "allowzero pointer and slice" {
|
||||
}
|
||||
|
||||
test "assign null directly to C pointer and test null equality" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -345,6 +346,8 @@ test "pointer sentinel with +inf" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@ -744,7 +744,8 @@ var g_foo: S0 = S0.init();
|
||||
|
||||
test "packed struct with fp fields" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -88,7 +88,6 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {
|
||||
const SwitchStatementFoo = enum { A, B, C, D };
|
||||
|
||||
test "switch with multiple expressions" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const x = switch (returnsFive()) {
|
||||
@ -231,6 +230,8 @@ test "switch prong with variable" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
|
||||
try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
|
||||
@ -273,7 +274,6 @@ fn testSwitchEnumPtrCapture() !void {
|
||||
}
|
||||
|
||||
test "switch handles all cases of number" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchHandleAllCases();
|
||||
@ -453,7 +453,6 @@ test "else prong of switch on error set excludes other cases" {
|
||||
}
|
||||
|
||||
test "switch prongs with error set cases make a new error set type for capture value" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -530,7 +529,6 @@ test "switch with null and T peer types and inferred result location type" {
|
||||
test "switch prongs with cases with identical payload types" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const Union = union(enum) {
|
||||
|
||||
@ -258,7 +258,6 @@ test "Type.ErrorSet" {
|
||||
|
||||
test "Type.Struct" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -383,7 +382,6 @@ test "Type.Enum" {
|
||||
|
||||
test "Type.Union" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@ test "basic unions with floats" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
var foo = FooWithFloats{ .int = 1 };
|
||||
try expect(foo.int == 1);
|
||||
@ -29,6 +31,8 @@ test "init union with runtime value - floats" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
var foo: FooWithFloats = undefined;
|
||||
|
||||
@ -216,6 +220,8 @@ test "union with specified enum tag" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
try doTest();
|
||||
comptime try doTest();
|
||||
@ -225,6 +231,8 @@ test "packed union generates correctly aligned type" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = packed union {
|
||||
f1: *const fn () error{TestUnexpectedResult}!void,
|
||||
@ -903,6 +911,8 @@ test "anonymous union literal syntax" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Number = union {
|
||||
@ -1055,6 +1065,8 @@ test "containers with single-field enums" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const A = union(enum) { f1 };
|
||||
@ -1082,7 +1094,6 @@ test "containers with single-field enums" {
|
||||
test "@unionInit on union with tag but no fields" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -1277,7 +1288,6 @@ test "return an extern union from C calling convention" {
|
||||
test "noreturn field in union" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = union(enum) {
|
||||
@ -1515,6 +1525,8 @@ test "reinterpreting enum value inside packed union" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
comptime !std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sse, .sse2, .sse4_1 })) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = packed union {
|
||||
tag: enum { a, b },
|
||||
|
||||
@ -321,6 +321,7 @@ test "load vector elements via comptime index" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -342,6 +343,7 @@ test "store vector elements via comptime index" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -369,6 +371,7 @@ test "load vector elements via runtime index" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -390,6 +393,7 @@ test "store vector elements via runtime index" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@ -396,6 +396,12 @@ fn addFromDirInner(
|
||||
// Other backends don't support new liveness format
|
||||
continue;
|
||||
}
|
||||
if (backend == .stage2 and target.getOsTag() == .macos and
|
||||
target.getCpuArch() == .x86_64 and builtin.cpu.arch == .aarch64)
|
||||
{
|
||||
// Rosetta has issues with ZLD
|
||||
continue;
|
||||
}
|
||||
|
||||
const next = ctx.cases.items.len;
|
||||
try ctx.cases.append(.{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user