| ... | ... | @@ -56,7 +56,10 @@ liveness: Liveness, |
| 56 | 56 | bin_file: *link.File, |
| 57 | 57 | debug_output: DebugInfoOutput, |
| 58 | 58 | target: *const std.Target, |
| 59 | | mod_fn: *const Module.Fn, |
| 59 | owner: union(enum) { |
| 60 | mod_fn: *const Module.Fn, |
| 61 | decl: Module.Decl.Index, |
| 62 | }, |
| 60 | 63 | err_msg: ?*ErrorMsg, |
| 61 | 64 | args: []MCValue, |
| 62 | 65 | ret_mcv: InstTracking, |
| ... | ... | @@ -617,7 +620,7 @@ pub fn generate( |
| 617 | 620 | .target = &bin_file.options.target, |
| 618 | 621 | .bin_file = bin_file, |
| 619 | 622 | .debug_output = debug_output, |
| 620 | | .mod_fn = module_fn, |
| 623 | .owner = .{ .mod_fn = module_fn }, |
| 621 | 624 | .err_msg = null, |
| 622 | 625 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 623 | 626 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| ... | ... | @@ -745,6 +748,92 @@ pub fn generate( |
| 745 | 748 | } |
| 746 | 749 | } |
| 747 | 750 | |
| 751 | pub 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 | |
| 748 | 837 | const FormatDeclData = struct { |
| 749 | 838 | mod: *Module, |
| 750 | 839 | decl_index: Module.Decl.Index, |
| ... | ... | @@ -1545,6 +1634,103 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1545 | 1634 | verbose_tracking_log.debug("{}", .{self.fmtTracking()}); |
| 1546 | 1635 | } |
| 1547 | 1636 | |
| 1637 | fn 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 | |
| 1727 | fn 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 | |
| 1548 | 1734 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |
| 1549 | 1735 | const reg = value.getReg() orelse return; |
| 1550 | 1736 | if (self.register_manager.isRegFree(reg)) { |
| ... | ... | @@ -6020,7 +6206,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 6020 | 6206 | |
| 6021 | 6207 | const ty = self.air.typeOfIndex(inst); |
| 6022 | 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 | 6210 | try self.genArgDbgInfo(ty, name, dst_mcv); |
| 6025 | 6211 | |
| 6026 | 6212 | break :result dst_mcv; |
| ... | ... | @@ -6044,7 +6230,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 6044 | 6230 | //}, |
| 6045 | 6231 | 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 | 6235 | .plan9 => {}, |
| 6050 | 6236 | .none => {}, |
| ... | ... | @@ -6085,7 +6271,7 @@ fn genVarDbgInfo( |
| 6085 | 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 | 6276 | .plan9 => {}, |
| 6091 | 6277 | .none => {}, |
| ... | ... | @@ -6243,7 +6429,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6243 | 6429 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 6244 | 6430 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 6245 | 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 | 6433 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 6248 | 6434 | _ = try self.addInst(.{ |
| 6249 | 6435 | .tag = .mov_linker, |
| ... | ... | @@ -6257,7 +6443,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6257 | 6443 | try self.asmRegister(.call, .rax); |
| 6258 | 6444 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 6259 | 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 | 6447 | _ = try self.addInst(.{ |
| 6262 | 6448 | .tag = .call_extern, |
| 6263 | 6449 | .ops = undefined, |
| ... | ... | @@ -6416,7 +6602,8 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 6416 | 6602 | const mod = self.bin_file.options.module.?; |
| 6417 | 6603 | const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod); |
| 6418 | 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 | 6607 | const atom = elf_file.getAtom(atom_index); |
| 6421 | 6608 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); |
| 6422 | 6609 | const got_addr = atom.getOffsetTableAddress(elf_file); |
| ... | ... | @@ -6426,11 +6613,13 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 6426 | 6613 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), |
| 6427 | 6614 | ); |
| 6428 | 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 | 6618 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 6431 | 6619 | try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index }); |
| 6432 | 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 | 6623 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 6435 | 6624 | try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index }); |
| 6436 | 6625 | } else { |
| ... | ... | @@ -7530,7 +7719,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7530 | 7719 | }), |
| 7531 | 7720 | ), |
| 7532 | 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 | 7723 | _ = try self.addInst(.{ |
| 7535 | 7724 | .tag = .mov_linker, |
| 7536 | 7725 | .ops = .direct_reloc, |
| ... | ... | @@ -7557,7 +7746,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7557 | 7746 | ); |
| 7558 | 7747 | }, |
| 7559 | 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 | 7750 | _ = try self.addInst(.{ |
| 7562 | 7751 | .tag = switch (src_mcv) { |
| 7563 | 7752 | .lea_direct => .lea_linker, |
| ... | ... | @@ -7577,7 +7766,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7577 | 7766 | }); |
| 7578 | 7767 | }, |
| 7579 | 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 | 7770 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| 7582 | 7771 | _ = try self.addInst(.{ |
| 7583 | 7772 | .tag = .lea_linker, |
| ... | ... | @@ -8475,10 +8664,64 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 8475 | 8664 | |
| 8476 | 8665 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 8477 | 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 | 8693 | const operand = try self.resolveInst(un_op); |
| 8479 | | _ = operand; |
| 8480 | | return self.fail("TODO implement airTagName for x86_64", .{}); |
| 8481 | | //return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 8694 | try self.genSetReg(param_regs[1], enum_ty, operand); |
| 8695 | |
| 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 | } |
| 8483 | 8726 | |
| 8484 | 8727 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -8497,7 +8740,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8497 | 8740 | const mod = self.bin_file.options.module.?; |
| 8498 | 8741 | const lazy_sym = link.File.LazySymbol.initDecl(.const_data, null, mod); |
| 8499 | 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 | 8745 | const atom = elf_file.getAtom(atom_index); |
| 8502 | 8746 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); |
| 8503 | 8747 | const got_addr = atom.getOffsetTableAddress(elf_file); |
| ... | ... | @@ -8507,11 +8751,13 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8507 | 8751 | Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(i32, got_addr) }), |
| 8508 | 8752 | ); |
| 8509 | 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 | 8756 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 8512 | 8757 | try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index }); |
| 8513 | 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 | 8761 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 8516 | 8762 | try self.genSetReg(addr_reg, Type.usize, .{ .lea_got = sym_index }); |
| 8517 | 8763 | } else { |
| ... | ... | @@ -8833,12 +9079,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 8833 | 9079 | } |
| 8834 | 9080 | |
| 8835 | 9081 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8836 | | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 8837 | | self.bin_file, |
| 8838 | | self.src_loc, |
| 8839 | | arg_tv, |
| 8840 | | self.mod_fn.owner_decl, |
| 8841 | | )) { |
| 9082 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.getOwnerDecl())) { |
| 8842 | 9083 | .mcv => |mcv| switch (mcv) { |
| 8843 | 9084 | .none => .none, |
| 8844 | 9085 | .undef => .undef, |
| ... | ... | @@ -8853,7 +9094,6 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8853 | 9094 | return error.CodegenFail; |
| 8854 | 9095 | }, |
| 8855 | 9096 | }; |
| 8856 | | return mcv; |
| 8857 | 9097 | } |
| 8858 | 9098 | |
| 8859 | 9099 | const CallMCValues = struct { |