authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-30 21:47:19-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 19:22:52-04:00
log47a34d038dd114533c3fcb130e03249ad846fe9c
tree6469bd38ce404ef80b0ad8258934c586cf0318e5
parent0489a63a432b31ce0fd9d6ec6c8e2fb72a920573

x86_64: implement tagName


9 files changed, 368 insertions(+), 71 deletions(-)

src/arch/x86_64/CodeGen.zig+266-26
...@@ -56,7 +56,10 @@ liveness: Liveness,...@@ -56,7 +56,10 @@ liveness: Liveness,
56bin_file: *link.File,56bin_file: *link.File,
57debug_output: DebugInfoOutput,57debug_output: DebugInfoOutput,
58target: *const std.Target,58target: *const std.Target,
59mod_fn: *const Module.Fn,59owner: union(enum) {
60 mod_fn: *const Module.Fn,
61 decl: Module.Decl.Index,
62},
60err_msg: ?*ErrorMsg,63err_msg: ?*ErrorMsg,
61args: []MCValue,64args: []MCValue,
62ret_mcv: InstTracking,65ret_mcv: InstTracking,
...@@ -617,7 +620,7 @@ pub fn generate(...@@ -617,7 +620,7 @@ pub fn generate(
617 .target = &bin_file.options.target,620 .target = &bin_file.options.target,
618 .bin_file = bin_file,621 .bin_file = bin_file,
619 .debug_output = debug_output,622 .debug_output = debug_output,
620 .mod_fn = module_fn,623 .owner = .{ .mod_fn = module_fn },
621 .err_msg = null,624 .err_msg = null,
622 .args = undefined, // populated after `resolveCallingConventionValues`625 .args = undefined, // populated after `resolveCallingConventionValues`
623 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`626 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -745,6 +748,92 @@ pub fn generate(...@@ -745,6 +748,92 @@ pub fn generate(
745 }748 }
746}749}
747750
751pub fn generateLazy(
752 bin_file: *link.File,
753 src_loc: Module.SrcLoc,
754 lazy_sym: link.File.LazySymbol,
755 code: *std.ArrayList(u8),
756 debug_output: DebugInfoOutput,
757) CodeGenError!Result {
758 const gpa = bin_file.allocator;
759 var function = Self{
760 .gpa = gpa,
761 .air = undefined,
762 .liveness = undefined,
763 .target = &bin_file.options.target,
764 .bin_file = bin_file,
765 .debug_output = debug_output,
766 .owner = .{ .decl = lazy_sym.ty.getOwnerDecl() },
767 .err_msg = null,
768 .args = undefined,
769 .ret_mcv = undefined,
770 .fn_type = undefined,
771 .arg_index = undefined,
772 .src_loc = src_loc,
773 .end_di_line = undefined, // no debug info yet
774 .end_di_column = undefined, // no debug info yet
775 };
776 defer {
777 function.mir_instructions.deinit(gpa);
778 function.mir_extra.deinit(gpa);
779 }
780
781 function.genLazy(lazy_sym) catch |err| switch (err) {
782 error.CodegenFail => return Result{ .fail = function.err_msg.? },
783 error.OutOfRegisters => return Result{
784 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
785 },
786 else => |e| return e,
787 };
788
789 var mir = Mir{
790 .instructions = function.mir_instructions.toOwnedSlice(),
791 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
792 .frame_locs = function.frame_locs.toOwnedSlice(),
793 };
794 defer mir.deinit(bin_file.allocator);
795
796 var emit = Emit{
797 .lower = .{
798 .allocator = bin_file.allocator,
799 .mir = mir,
800 .target = &bin_file.options.target,
801 .src_loc = src_loc,
802 },
803 .bin_file = bin_file,
804 .debug_output = debug_output,
805 .code = code,
806 .prev_di_pc = undefined, // no debug info yet
807 .prev_di_line = undefined, // no debug info yet
808 .prev_di_column = undefined, // no debug info yet
809 };
810 defer emit.deinit();
811 emit.emitMir() catch |err| switch (err) {
812 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
813 error.InvalidInstruction, error.CannotEncode => |e| {
814 const msg = switch (e) {
815 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
816 error.CannotEncode => "CodeGen failed to encode the instruction.",
817 };
818 return Result{
819 .fail = try ErrorMsg.create(
820 bin_file.allocator,
821 src_loc,
822 "{s} This is a bug in the Zig compiler.",
823 .{msg},
824 ),
825 };
826 },
827 else => |e| return e,
828 };
829
830 if (function.err_msg) |em| {
831 return Result{ .fail = em };
832 } else {
833 return Result.ok;
834 }
835}
836
748const FormatDeclData = struct {837const FormatDeclData = struct {
749 mod: *Module,838 mod: *Module,
750 decl_index: Module.Decl.Index,839 decl_index: Module.Decl.Index,
...@@ -1545,6 +1634,103 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1545,6 +1634,103 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1545 verbose_tracking_log.debug("{}", .{self.fmtTracking()});1634 verbose_tracking_log.debug("{}", .{self.fmtTracking()});
1546}1635}
15471636
1637fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
1638 switch (lazy_sym.ty.zigTypeTag()) {
1639 .Enum => {
1640 const enum_ty = lazy_sym.ty;
1641 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)});
1642
1643 const param_regs = abi.getCAbiIntParamRegs(self.target.*);
1644 const param_locks = self.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*);
1645 defer for (param_locks) |lock| self.register_manager.unlockReg(lock);
1646
1647 const ret_reg = param_regs[0];
1648 const enum_mcv = MCValue{ .register = param_regs[1] };
1649
1650 var exitlude_jump_relocs = try self.gpa.alloc(u32, enum_ty.enumFieldCount());
1651 defer self.gpa.free(exitlude_jump_relocs);
1652
1653 const data_reg = try self.register_manager.allocReg(null, gp);
1654 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);
1655 defer self.register_manager.unlockReg(data_lock);
1656
1657 const data_lazy_sym = link.File.LazySymbol{ .kind = .const_data, .ty = enum_ty };
1658 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1659 const atom_index = elf_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1660 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1661 const atom = elf_file.getAtom(atom_index);
1662 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
1663 const got_addr = atom.getOffsetTableAddress(elf_file);
1664 try self.asmRegisterMemory(
1665 .mov,
1666 data_reg.to64(),
1667 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
1668 );
1669 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
1670 const atom_index = coff_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1671 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1672 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
1673 try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index });
1674 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
1675 const atom_index = macho_file.getOrCreateAtomForLazySymbol(data_lazy_sym) catch |err|
1676 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1677 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
1678 try self.genSetReg(data_reg, Type.usize, .{ .lea_got = sym_index });
1679 } else {
1680 return self.fail("TODO implement {s} for {}", .{
1681 @tagName(lazy_sym.kind),
1682 lazy_sym.ty.fmt(self.bin_file.options.module.?),
1683 });
1684 }
1685
1686 var data_off: i32 = 0;
1687 for (
1688 exitlude_jump_relocs,
1689 enum_ty.enumFields().keys(),
1690 0..,
1691 ) |*exitlude_jump_reloc, tag_name, index| {
1692 var tag_pl = Value.Payload.U32{
1693 .base = .{ .tag = .enum_field_index },
1694 .data = @intCast(u32, index),
1695 };
1696 const tag_val = Value.initPayload(&tag_pl.base);
1697 const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
1698 try self.genBinOpMir(.cmp, enum_ty, enum_mcv, tag_mcv);
1699 const skip_reloc = try self.asmJccReloc(undefined, .ne);
1700
1701 try self.genSetMem(
1702 .{ .reg = ret_reg },
1703 0,
1704 Type.usize,
1705 .{ .register_offset = .{ .reg = data_reg, .off = data_off } },
1706 );
1707 try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len });
1708
1709 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
1710 try self.performReloc(skip_reloc);
1711
1712 data_off += @intCast(i32, tag_name.len + 1);
1713 }
1714
1715 try self.airTrap();
1716
1717 for (exitlude_jump_relocs) |reloc| try self.performReloc(reloc);
1718 try self.asmOpOnly(.ret);
1719 },
1720 else => return self.fail(
1721 "TODO implement {s} for {}",
1722 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(self.bin_file.options.module.?) },
1723 ),
1724 }
1725}
1726
1727fn getOwnerDecl(self: *const Self) Module.Decl.Index {
1728 return switch (self.owner) {
1729 .mod_fn => |mod_fn| mod_fn.owner_decl,
1730 .decl => |index| index,
1731 };
1732}
1733
1548fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void {1734fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void {
1549 const reg = value.getReg() orelse return;1735 const reg = value.getReg() orelse return;
1550 if (self.register_manager.isRegFree(reg)) {1736 if (self.register_manager.isRegFree(reg)) {
...@@ -6020,7 +6206,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -6020,7 +6206,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
60206206
6021 const ty = self.air.typeOfIndex(inst);6207 const ty = self.air.typeOfIndex(inst);
6022 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;6208 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
6023 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);6209 const name = self.owner.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
6024 try self.genArgDbgInfo(ty, name, dst_mcv);6210 try self.genArgDbgInfo(ty, name, dst_mcv);
60256211
6026 break :result dst_mcv;6212 break :result dst_mcv;
...@@ -6044,7 +6230,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {...@@ -6044,7 +6230,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
6044 //},6230 //},
6045 else => unreachable, // not a valid function parameter6231 else => unreachable, // not a valid function parameter
6046 };6232 };
6047 try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, loc);6233 try dw.genArgDbgInfo(name, ty, self.getOwnerDecl(), loc);
6048 },6234 },
6049 .plan9 => {},6235 .plan9 => {},
6050 .none => {},6236 .none => {},
...@@ -6085,7 +6271,7 @@ fn genVarDbgInfo(...@@ -6085,7 +6271,7 @@ fn genVarDbgInfo(
6085 break :blk .nop;6271 break :blk .nop;
6086 },6272 },
6087 };6273 };
6088 try dw.genVarDbgInfo(name, ty, self.mod_fn.owner_decl, is_ptr, loc);6274 try dw.genVarDbgInfo(name, ty, self.getOwnerDecl(), is_ptr, loc);
6089 },6275 },
6090 .plan9 => {},6276 .plan9 => {},
6091 .none => {},6277 .none => {},
...@@ -6243,7 +6429,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -6243,7 +6429,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
6243 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);6429 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);
6244 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);6430 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
6245 if (self.bin_file.cast(link.File.Coff)) |coff_file| {6431 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6246 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);6432 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
6247 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);6433 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
6248 _ = try self.addInst(.{6434 _ = try self.addInst(.{
6249 .tag = .mov_linker,6435 .tag = .mov_linker,
...@@ -6257,7 +6443,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -6257,7 +6443,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
6257 try self.asmRegister(.call, .rax);6443 try self.asmRegister(.call, .rax);
6258 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {6444 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
6259 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);6445 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
6260 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);6446 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
6261 _ = try self.addInst(.{6447 _ = try self.addInst(.{
6262 .tag = .call_extern,6448 .tag = .call_extern,
6263 .ops = undefined,6449 .ops = undefined,
...@@ -6416,7 +6602,8 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -6416,7 +6602,8 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
6416 const mod = self.bin_file.options.module.?;6602 const mod = self.bin_file.options.module.?;
6417 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod);6603 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod);
6418 if (self.bin_file.cast(link.File.Elf)) |elf_file| {6604 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
6419 const atom_index = try elf_file.getOrCreateAtomForLazySymbol(lazy_sym);6605 const atom_index = elf_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
6606 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
6420 const atom = elf_file.getAtom(atom_index);6607 const atom = elf_file.getAtom(atom_index);
6421 _ = try atom.getOrCreateOffsetTableEntry(elf_file);6608 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
6422 const got_addr = atom.getOffsetTableAddress(elf_file);6609 const got_addr = atom.getOffsetTableAddress(elf_file);
...@@ -6426,11 +6613,13 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -6426,11 +6613,13 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
6426 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),6613 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
6427 );6614 );
6428 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {6615 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
6429 const atom_index = try coff_file.getOrCreateAtomForLazySymbol(lazy_sym);6616 const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
6617 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
6430 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;6618 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
6431 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });6619 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });
6432 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {6620 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
6433 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(lazy_sym);6621 const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
6622 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
6434 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;6623 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
6435 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });6624 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });
6436 } else {6625 } else {
...@@ -7530,7 +7719,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7530,7 +7719,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7530 }),7719 }),
7531 ),7720 ),
7532 .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) {7721 .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) {
7533 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);7722 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
7534 _ = try self.addInst(.{7723 _ = try self.addInst(.{
7535 .tag = .mov_linker,7724 .tag = .mov_linker,
7536 .ops = .direct_reloc,7725 .ops = .direct_reloc,
...@@ -7557,7 +7746,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7557,7 +7746,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7557 );7746 );
7558 },7747 },
7559 .lea_direct, .lea_got => |sym_index| {7748 .lea_direct, .lea_got => |sym_index| {
7560 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);7749 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
7561 _ = try self.addInst(.{7750 _ = try self.addInst(.{
7562 .tag = switch (src_mcv) {7751 .tag = switch (src_mcv) {
7563 .lea_direct => .lea_linker,7752 .lea_direct => .lea_linker,
...@@ -7577,7 +7766,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -7577,7 +7766,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
7577 });7766 });
7578 },7767 },
7579 .lea_tlv => |sym_index| {7768 .lea_tlv => |sym_index| {
7580 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);7769 const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl());
7581 if (self.bin_file.cast(link.File.MachO)) |_| {7770 if (self.bin_file.cast(link.File.MachO)) |_| {
7582 _ = try self.addInst(.{7771 _ = try self.addInst(.{
7583 .tag = .lea_linker,7772 .tag = .lea_linker,
...@@ -8475,10 +8664,64 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -8475,10 +8664,64 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
84758664
8476fn airTagName(self: *Self, inst: Air.Inst.Index) !void {8665fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
8477 const un_op = self.air.instructions.items(.data)[inst].un_op;8666 const un_op = self.air.instructions.items(.data)[inst].un_op;
8667 const inst_ty = self.air.typeOfIndex(inst);
8668 const enum_ty = self.air.typeOf(un_op);
8669
8670 // We need a properly aligned and sized call frame to be able to call this function.
8671 {
8672 const needed_call_frame = FrameAlloc.init(.{
8673 .size = inst_ty.abiSize(self.target.*),
8674 .alignment = inst_ty.abiAlignment(self.target.*),
8675 });
8676 const frame_allocs_slice = self.frame_allocs.slice();
8677 const stack_frame_size =
8678 &frame_allocs_slice.items(.abi_size)[@enumToInt(FrameIndex.call_frame)];
8679 stack_frame_size.* = @max(stack_frame_size.*, needed_call_frame.abi_size);
8680 const stack_frame_align =
8681 &frame_allocs_slice.items(.abi_align)[@enumToInt(FrameIndex.call_frame)];
8682 stack_frame_align.* = @max(stack_frame_align.*, needed_call_frame.abi_align);
8683 }
8684
8685 try self.spillEflagsIfOccupied();
8686 try self.spillRegisters(abi.getCallerPreservedRegs(self.target.*));
8687
8688 const param_regs = abi.getCAbiIntParamRegs(self.target.*);
8689
8690 const dst_mcv = try self.allocRegOrMem(inst, false);
8691 try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address());
8692
8478 const operand = try self.resolveInst(un_op);8693 const operand = try self.resolveInst(un_op);
8479 _ = operand;8694 try self.genSetReg(param_regs[1], enum_ty, operand);
8480 return self.fail("TODO implement airTagName for x86_64", .{});8695
8481 //return self.finishAir(inst, result, .{ un_op, .none, .none });8696 const mod = self.bin_file.options.module.?;
8697 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(), mod);
8698 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8699 const atom_index = elf_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8700 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8701 const atom = elf_file.getAtom(atom_index);
8702 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
8703 const got_addr = atom.getOffsetTableAddress(elf_file);
8704 try self.asmMemory(
8705 .call,
8706 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
8707 );
8708 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8709 const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8710 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8711 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8712 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8713 try self.asmRegister(.call, .rax);
8714 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8715 const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8716 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8717 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8718 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
8719 try self.asmRegister(.call, .rax);
8720 } else {
8721 return self.fail("TODO implement airTagName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
8722 }
8723
8724 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
8482}8725}
84838726
8484fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {8727fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
...@@ -8497,7 +8740,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -8497,7 +8740,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
8497 const mod = self.bin_file.options.module.?;8740 const mod = self.bin_file.options.module.?;
8498 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod);8741 const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod);
8499 if (self.bin_file.cast(link.File.Elf)) |elf_file| {8742 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
8500 const atom_index = try elf_file.getOrCreateAtomForLazySymbol(lazy_sym);8743 const atom_index = elf_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8744 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8501 const atom = elf_file.getAtom(atom_index);8745 const atom = elf_file.getAtom(atom_index);
8502 _ = try atom.getOrCreateOffsetTableEntry(elf_file);8746 _ = try atom.getOrCreateOffsetTableEntry(elf_file);
8503 const got_addr = atom.getOffsetTableAddress(elf_file);8747 const got_addr = atom.getOffsetTableAddress(elf_file);
...@@ -8507,11 +8751,13 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -8507,11 +8751,13 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
8507 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),8751 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }),
8508 );8752 );
8509 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {8753 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8510 const atom_index = try coff_file.getOrCreateAtomForLazySymbol(lazy_sym);8754 const atom_index = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8755 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8511 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;8756 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8512 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });8757 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });
8513 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {8758 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8514 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(lazy_sym);8759 const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
8760 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
8515 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;8761 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8516 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });8762 try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index });
8517 } else {8763 } else {
...@@ -8833,12 +9079,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV...@@ -8833,12 +9079,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
8833}9079}
88349080
8835fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {9081fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
8836 const mcv: MCValue = switch (try codegen.genTypedValue(9082 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.getOwnerDecl())) {
8837 self.bin_file,
8838 self.src_loc,
8839 arg_tv,
8840 self.mod_fn.owner_decl,
8841 )) {
8842 .mcv => |mcv| switch (mcv) {9083 .mcv => |mcv| switch (mcv) {
8843 .none => .none,9084 .none => .none,
8844 .undef => .undef,9085 .undef => .undef,
...@@ -8853,7 +9094,6 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -8853,7 +9094,6 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
8853 return error.CodegenFail;9094 return error.CodegenFail;
8854 },9095 },
8855 };9096 };
8856 return mcv;
8857}9097}
88589098
8859const CallMCValues = struct {9099const CallMCValues = struct {
src/codegen.zig+34-6
...@@ -7,6 +7,7 @@ const link = @import("link.zig");...@@ -7,6 +7,7 @@ const link = @import("link.zig");
7const log = std.log.scoped(.codegen);7const log = std.log.scoped(.codegen);
8const mem = std.mem;8const mem = std.mem;
9const math = std.math;9const math = std.math;
10const target_util = @import("target.zig");
10const trace = @import("tracy.zig").trace;11const trace = @import("tracy.zig").trace;
1112
12const Air = @import("Air.zig");13const Air = @import("Air.zig");
...@@ -89,6 +90,19 @@ pub fn generateFunction(...@@ -89,6 +90,19 @@ pub fn generateFunction(
89 }90 }
90}91}
9192
93pub fn generateLazyFunction(
94 bin_file: *link.File,
95 src_loc: Module.SrcLoc,
96 lazy_sym: link.File.LazySymbol,
97 code: *std.ArrayList(u8),
98 debug_output: DebugInfoOutput,
99) CodeGenError!Result {
100 switch (bin_file.options.target.cpu.arch) {
101 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(bin_file, src_loc, lazy_sym, code, debug_output),
102 else => unreachable,
103 }
104}
105
92fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian, code: []u8) void {106fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian, code: []u8) void {
93 _ = target;107 _ = target;
94 const bits = @typeInfo(F).Float.bits;108 const bits = @typeInfo(F).Float.bits;
...@@ -101,11 +115,11 @@ pub fn generateLazySymbol(...@@ -101,11 +115,11 @@ pub fn generateLazySymbol(
101 bin_file: *link.File,115 bin_file: *link.File,
102 src_loc: Module.SrcLoc,116 src_loc: Module.SrcLoc,
103 lazy_sym: link.File.LazySymbol,117 lazy_sym: link.File.LazySymbol,
118 alignment: *u32,
104 code: *std.ArrayList(u8),119 code: *std.ArrayList(u8),
105 debug_output: DebugInfoOutput,120 debug_output: DebugInfoOutput,
106 reloc_info: RelocInfo,121 reloc_info: RelocInfo,
107) CodeGenError!struct { res: Result, alignment: u32 } {122) CodeGenError!Result {
108 _ = debug_output;
109 _ = reloc_info;123 _ = reloc_info;
110124
111 const tracy = trace(@src());125 const tracy = trace(@src());
...@@ -120,7 +134,13 @@ pub fn generateLazySymbol(...@@ -120,7 +134,13 @@ pub fn generateLazySymbol(
120 lazy_sym.ty.fmt(mod),134 lazy_sym.ty.fmt(mod),
121 });135 });
122136
123 if (lazy_sym.kind == .const_data and lazy_sym.ty.isAnyError()) {137 if (lazy_sym.kind == .code) {
138 alignment.* = target_util.defaultFunctionAlignment(target);
139 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);
140 }
141
142 if (lazy_sym.ty.isAnyError()) {
143 alignment.* = 4;
124 const err_names = mod.error_name_list.items;144 const err_names = mod.error_name_list.items;
125 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);145 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
126 var offset = code.items.len;146 var offset = code.items.len;
...@@ -133,13 +153,21 @@ pub fn generateLazySymbol(...@@ -133,13 +153,21 @@ pub fn generateLazySymbol(
133 code.appendAssumeCapacity(0);153 code.appendAssumeCapacity(0);
134 }154 }
135 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);155 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
136 return .{ .res = Result.ok, .alignment = 4 };156 return Result.ok;
137 } else return .{ .res = .{ .fail = try ErrorMsg.create(157 } else if (lazy_sym.ty.zigTypeTag() == .Enum) {
158 alignment.* = 1;
159 for (lazy_sym.ty.enumFields().keys()) |tag_name| {
160 try code.ensureUnusedCapacity(tag_name.len + 1);
161 code.appendSliceAssumeCapacity(tag_name);
162 code.appendAssumeCapacity(0);
163 }
164 return Result.ok;
165 } else return .{ .fail = try ErrorMsg.create(
138 bin_file.allocator,166 bin_file.allocator,
139 src_loc,167 src_loc,
140 "TODO implement generateLazySymbol for {s} {}",168 "TODO implement generateLazySymbol for {s} {}",
141 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) },169 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) },
142 ) }, .alignment = undefined };170 ) };
143}171}
144172
145pub fn generateSymbol(173pub fn generateSymbol(
src/link/Coff.zig+23-10
...@@ -1218,6 +1218,7 @@ fn updateLazySymbolAtom(...@@ -1218,6 +1218,7 @@ fn updateLazySymbolAtom(
1218 const gpa = self.base.allocator;1218 const gpa = self.base.allocator;
1219 const mod = self.base.options.module.?;1219 const mod = self.base.options.module.?;
12201220
1221 var required_alignment: u32 = undefined;
1221 var code_buffer = std.ArrayList(u8).init(gpa);1222 var code_buffer = std.ArrayList(u8).init(gpa);
1222 defer code_buffer.deinit();1223 defer code_buffer.deinit();
12231224
...@@ -1238,10 +1239,16 @@ fn updateLazySymbolAtom(...@@ -1238,10 +1239,16 @@ fn updateLazySymbolAtom(
1238 .parent_decl_node = undefined,1239 .parent_decl_node = undefined,
1239 .lazy = .unneeded,1240 .lazy = .unneeded,
1240 };1241 };
1241 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{1242 const res = try codegen.generateLazySymbol(
1242 .parent_atom_index = local_sym_index,1243 &self.base,
1243 });1244 src,
1244 const code = switch (res.res) {1245 sym,
1246 &required_alignment,
1247 &code_buffer,
1248 .none,
1249 .{ .parent_atom_index = local_sym_index },
1250 );
1251 const code = switch (res) {
1245 .ok => code_buffer.items,1252 .ok => code_buffer.items,
1246 .fail => |em| {1253 .fail => |em| {
1247 log.err("{s}", .{em.msg});1254 log.err("{s}", .{em.msg});
...@@ -1255,11 +1262,11 @@ fn updateLazySymbolAtom(...@@ -1255,11 +1262,11 @@ fn updateLazySymbolAtom(
1255 symbol.section_number = @intToEnum(coff.SectionNumber, section_index + 1);1262 symbol.section_number = @intToEnum(coff.SectionNumber, section_index + 1);
1256 symbol.type = .{ .complex_type = .NULL, .base_type = .NULL };1263 symbol.type = .{ .complex_type = .NULL, .base_type = .NULL };
12571264
1258 const vaddr = try self.allocateAtom(atom_index, code_len, res.alignment);1265 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
1259 errdefer self.freeAtom(atom_index);1266 errdefer self.freeAtom(atom_index);
12601267
1261 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });1268 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
1262 log.debug(" (required alignment 0x{x})", .{res.alignment});1269 log.debug(" (required alignment 0x{x})", .{required_alignment});
12631270
1264 atom.size = code_len;1271 atom.size = code_len;
1265 symbol.value = vaddr;1272 symbol.value = vaddr;
...@@ -1270,14 +1277,20 @@ fn updateLazySymbolAtom(...@@ -1270,14 +1277,20 @@ fn updateLazySymbolAtom(
12701277
1271pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {1278pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {
1272 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());1279 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
1273 errdefer _ = self.lazy_syms.pop();1280 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1274 if (!gop.found_existing) gop.value_ptr.* = .{};1281 if (!gop.found_existing) gop.value_ptr.* = .{};
1275 const atom = switch (sym.kind) {1282 const atom_ptr = switch (sym.kind) {
1276 .code => &gop.value_ptr.text_atom,1283 .code => &gop.value_ptr.text_atom,
1277 .const_data => &gop.value_ptr.rdata_atom,1284 .const_data => &gop.value_ptr.rdata_atom,
1278 };1285 };
1279 if (atom.* == null) atom.* = try self.createAtom();1286 if (atom_ptr.*) |atom| return atom;
1280 return atom.*.?;1287 const atom = try self.createAtom();
1288 atom_ptr.* = atom;
1289 try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
1290 .code => self.text_section_index.?,
1291 .const_data => self.rdata_section_index.?,
1292 });
1293 return atom;
1281}1294}
12821295
1283pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {1296pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {
src/link/Elf.zig+22-9
...@@ -2376,14 +2376,20 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {...@@ -2376,14 +2376,20 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
23762376
2377pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol) !Atom.Index {2377pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol) !Atom.Index {
2378 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());2378 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
2379 errdefer _ = self.lazy_syms.pop();2379 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
2380 if (!gop.found_existing) gop.value_ptr.* = .{};2380 if (!gop.found_existing) gop.value_ptr.* = .{};
2381 const atom = switch (sym.kind) {2381 const atom_ptr = switch (sym.kind) {
2382 .code => &gop.value_ptr.text_atom,2382 .code => &gop.value_ptr.text_atom,
2383 .const_data => &gop.value_ptr.rodata_atom,2383 .const_data => &gop.value_ptr.rodata_atom,
2384 };2384 };
2385 if (atom.* == null) atom.* = try self.createAtom();2385 if (atom_ptr.*) |atom| return atom;
2386 return atom.*.?;2386 const atom = try self.createAtom();
2387 atom_ptr.* = atom;
2388 try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
2389 .code => self.text_section_index.?,
2390 .const_data => self.rodata_section_index.?,
2391 });
2392 return atom;
2387}2393}
23882394
2389pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {2395pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {
...@@ -2684,6 +2690,7 @@ fn updateLazySymbolAtom(...@@ -2684,6 +2690,7 @@ fn updateLazySymbolAtom(
2684 const gpa = self.base.allocator;2690 const gpa = self.base.allocator;
2685 const mod = self.base.options.module.?;2691 const mod = self.base.options.module.?;
26862692
2693 var required_alignment: u32 = undefined;
2687 var code_buffer = std.ArrayList(u8).init(gpa);2694 var code_buffer = std.ArrayList(u8).init(gpa);
2688 defer code_buffer.deinit();2695 defer code_buffer.deinit();
26892696
...@@ -2708,10 +2715,16 @@ fn updateLazySymbolAtom(...@@ -2708,10 +2715,16 @@ fn updateLazySymbolAtom(
2708 .parent_decl_node = undefined,2715 .parent_decl_node = undefined,
2709 .lazy = .unneeded,2716 .lazy = .unneeded,
2710 };2717 };
2711 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{2718 const res = try codegen.generateLazySymbol(
2712 .parent_atom_index = local_sym_index,2719 &self.base,
2713 });2720 src,
2714 const code = switch (res.res) {2721 sym,
2722 &required_alignment,
2723 &code_buffer,
2724 .none,
2725 .{ .parent_atom_index = local_sym_index },
2726 );
2727 const code = switch (res) {
2715 .ok => code_buffer.items,2728 .ok => code_buffer.items,
2716 .fail => |em| {2729 .fail => |em| {
2717 log.err("{s}", .{em.msg});2730 log.err("{s}", .{em.msg});
...@@ -2729,7 +2742,7 @@ fn updateLazySymbolAtom(...@@ -2729,7 +2742,7 @@ fn updateLazySymbolAtom(
2729 .st_value = 0,2742 .st_value = 0,
2730 .st_size = 0,2743 .st_size = 0,
2731 };2744 };
2732 const vaddr = try self.allocateAtom(atom_index, code.len, res.alignment);2745 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
2733 errdefer self.freeAtom(atom_index);2746 errdefer self.freeAtom(atom_index);
2734 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });2747 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });
27352748
src/link/MachO.zig+23-10
...@@ -2060,6 +2060,7 @@ fn updateLazySymbolAtom(...@@ -2060,6 +2060,7 @@ fn updateLazySymbolAtom(
2060 const gpa = self.base.allocator;2060 const gpa = self.base.allocator;
2061 const mod = self.base.options.module.?;2061 const mod = self.base.options.module.?;
20622062
2063 var required_alignment: u32 = undefined;
2063 var code_buffer = std.ArrayList(u8).init(gpa);2064 var code_buffer = std.ArrayList(u8).init(gpa);
2064 defer code_buffer.deinit();2065 defer code_buffer.deinit();
20652066
...@@ -2084,10 +2085,16 @@ fn updateLazySymbolAtom(...@@ -2084,10 +2085,16 @@ fn updateLazySymbolAtom(
2084 .parent_decl_node = undefined,2085 .parent_decl_node = undefined,
2085 .lazy = .unneeded,2086 .lazy = .unneeded,
2086 };2087 };
2087 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{2088 const res = try codegen.generateLazySymbol(
2088 .parent_atom_index = local_sym_index,2089 &self.base,
2089 });2090 src,
2090 const code = switch (res.res) {2091 sym,
2092 &required_alignment,
2093 &code_buffer,
2094 .none,
2095 .{ .parent_atom_index = local_sym_index },
2096 );
2097 const code = switch (res) {
2091 .ok => code_buffer.items,2098 .ok => code_buffer.items,
2092 .fail => |em| {2099 .fail => |em| {
2093 log.err("{s}", .{em.msg});2100 log.err("{s}", .{em.msg});
...@@ -2101,11 +2108,11 @@ fn updateLazySymbolAtom(...@@ -2101,11 +2108,11 @@ fn updateLazySymbolAtom(
2101 symbol.n_sect = section_index + 1;2108 symbol.n_sect = section_index + 1;
2102 symbol.n_desc = 0;2109 symbol.n_desc = 0;
21032110
2104 const vaddr = try self.allocateAtom(atom_index, code.len, res.alignment);2111 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
2105 errdefer self.freeAtom(atom_index);2112 errdefer self.freeAtom(atom_index);
21062113
2107 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });2114 log.debug("allocated atom for {s} at 0x{x}", .{ name, vaddr });
2108 log.debug(" (required alignment 0x{x}", .{res.alignment});2115 log.debug(" (required alignment 0x{x}", .{required_alignment});
21092116
2110 atom.size = code.len;2117 atom.size = code.len;
2111 symbol.n_value = vaddr;2118 symbol.n_value = vaddr;
...@@ -2116,14 +2123,20 @@ fn updateLazySymbolAtom(...@@ -2116,14 +2123,20 @@ fn updateLazySymbolAtom(
21162123
2117pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.Index {2124pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.Index {
2118 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());2125 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
2119 errdefer _ = self.lazy_syms.pop();2126 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
2120 if (!gop.found_existing) gop.value_ptr.* = .{};2127 if (!gop.found_existing) gop.value_ptr.* = .{};
2121 const atom = switch (sym.kind) {2128 const atom_ptr = switch (sym.kind) {
2122 .code => &gop.value_ptr.text_atom,2129 .code => &gop.value_ptr.text_atom,
2123 .const_data => &gop.value_ptr.data_const_atom,2130 .const_data => &gop.value_ptr.data_const_atom,
2124 };2131 };
2125 if (atom.* == null) atom.* = try self.createAtom();2132 if (atom_ptr.*) |atom| return atom;
2126 return atom.*.?;2133 const atom = try self.createAtom();
2134 atom_ptr.* = atom;
2135 try self.updateLazySymbolAtom(sym, atom, switch (sym.kind) {
2136 .code => self.text_section_index.?,
2137 .const_data => self.data_const_section_index.?,
2138 });
2139 return atom;
2127}2140}
21282141
2129fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {2142fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
test/behavior/enum.zig-5
...@@ -981,7 +981,6 @@ fn test3_2(f: Test3Foo) !void {...@@ -981,7 +981,6 @@ fn test3_2(f: Test3Foo) !void {
981}981}
982982
983test "@tagName" {983test "@tagName" {
984 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
985 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;984 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
986 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;985 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
987 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO986 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -997,7 +996,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 {...@@ -997,7 +996,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 {
997const BareNumber = enum { One, Two, Three };996const BareNumber = enum { One, Two, Three };
998997
999test "@tagName non-exhaustive enum" {998test "@tagName non-exhaustive enum" {
1000 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1001 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;999 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1002 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1000 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1003 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1001 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1008,7 +1006,6 @@ test "@tagName non-exhaustive enum" {...@@ -1008,7 +1006,6 @@ test "@tagName non-exhaustive enum" {
1008const NonExhaustive = enum(u8) { A, B, _ };1006const NonExhaustive = enum(u8) { A, B, _ };
10091007
1010test "@tagName is null-terminated" {1008test "@tagName is null-terminated" {
1011 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1012 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1009 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1013 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1010 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1014 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1011 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1023,7 +1020,6 @@ test "@tagName is null-terminated" {...@@ -1023,7 +1020,6 @@ test "@tagName is null-terminated" {
1023}1020}
10241021
1025test "tag name with assigned enum values" {1022test "tag name with assigned enum values" {
1026 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1027 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1023 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1028 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1024 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1029 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1025 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1113,7 +1109,6 @@ test "enum literal in array literal" {...@@ -1113,7 +1109,6 @@ test "enum literal in array literal" {
11131109
1114test "tag name functions are unique" {1110test "tag name functions are unique" {
1115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1111 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1118 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1114 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/memset.zig-2
...@@ -114,7 +114,6 @@ test "memset with large array element, runtime known" {...@@ -114,7 +114,6 @@ test "memset with large array element, runtime known" {
114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
116 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;116 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
117 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
118117
119 const A = [128]u64;118 const A = [128]u64;
120 var buf: [5]A = undefined;119 var buf: [5]A = undefined;
...@@ -132,7 +131,6 @@ test "memset with large array element, comptime known" {...@@ -132,7 +131,6 @@ test "memset with large array element, comptime known" {
132 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
133 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;132 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
134 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;133 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
135 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
136134
137 const A = [128]u64;135 const A = [128]u64;
138 var buf: [5]A = undefined;136 var buf: [5]A = undefined;
test/behavior/type.zig-2
...@@ -258,7 +258,6 @@ test "Type.ErrorSet" {...@@ -258,7 +258,6 @@ test "Type.ErrorSet" {
258258
259test "Type.Struct" {259test "Type.Struct" {
260 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO260 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
261 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
262 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO261 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
263 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO262 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
264 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO263 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -383,7 +382,6 @@ test "Type.Enum" {...@@ -383,7 +382,6 @@ test "Type.Enum" {
383382
384test "Type.Union" {383test "Type.Union" {
385 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO384 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
386 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
387 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO385 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO386 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
389387
test/behavior/union.zig-1
...@@ -1094,7 +1094,6 @@ test "containers with single-field enums" {...@@ -1094,7 +1094,6 @@ test "containers with single-field enums" {
1094test "@unionInit on union with tag but no fields" {1094test "@unionInit on union with tag but no fields" {
1095 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1095 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1096 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1096 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1097 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1098 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1097 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1099 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1098 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11001099