| ... | @@ -137,6 +137,7 @@ pub const MCValue = union(enum) { | ... | @@ -137,6 +137,7 @@ pub const MCValue = union(enum) { |
| 137 | /// If the type is a pointer, it means the pointer is referenced indirectly via GOT. | 137 | /// If the type is a pointer, it means the pointer is referenced indirectly via GOT. |
| 138 | /// When lowered, linker will emit a relocation of type X86_64_RELOC_GOT. | 138 | /// When lowered, linker will emit a relocation of type X86_64_RELOC_GOT. |
| 139 | got_load: u32, | 139 | got_load: u32, |
| | 140 | imports_load: u32, |
| 140 | /// The value is in memory referenced directly via symbol index. | 141 | /// The value is in memory referenced directly via symbol index. |
| 141 | /// If the type is a pointer, it means the pointer is referenced directly via symbol index. | 142 | /// If the type is a pointer, it means the pointer is referenced directly via symbol index. |
| 142 | /// When lowered, linker will emit a relocation of type X86_64_RELOC_SIGNED. | 143 | /// When lowered, linker will emit a relocation of type X86_64_RELOC_SIGNED. |
| ... | @@ -156,6 +157,7 @@ pub const MCValue = union(enum) { | ... | @@ -156,6 +157,7 @@ pub const MCValue = union(enum) { |
| 156 | .ptr_stack_offset, | 157 | .ptr_stack_offset, |
| 157 | .direct_load, | 158 | .direct_load, |
| 158 | .got_load, | 159 | .got_load, |
| | 160 | .imports_load, |
| 159 | => true, | 161 | => true, |
| 160 | else => false, | 162 | else => false, |
| 161 | }; | 163 | }; |
| ... | @@ -2274,6 +2276,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2274,6 +2276,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2274 | .memory, | 2276 | .memory, |
| 2275 | .got_load, | 2277 | .got_load, |
| 2276 | .direct_load, | 2278 | .direct_load, |
| | 2279 | .imports_load, |
| 2277 | => { | 2280 | => { |
| 2278 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, array); | 2281 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, array); |
| 2279 | }, | 2282 | }, |
| ... | @@ -2618,6 +2621,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2618,6 +2621,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2618 | .memory, | 2621 | .memory, |
| 2619 | .got_load, | 2622 | .got_load, |
| 2620 | .direct_load, | 2623 | .direct_load, |
| | 2624 | .imports_load, |
| 2621 | => { | 2625 | => { |
| 2622 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); | 2626 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 2623 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); | 2627 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); |
| ... | @@ -2655,6 +2659,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue | ... | @@ -2655,6 +2659,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue |
| 2655 | switch (ptr) { | 2659 | switch (ptr) { |
| 2656 | .got_load, | 2660 | .got_load, |
| 2657 | .direct_load, | 2661 | .direct_load, |
| | 2662 | .imports_load, |
| 2658 | => |sym_index| { | 2663 | => |sym_index| { |
| 2659 | const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*)); | 2664 | const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*)); |
| 2660 | const mod = self.bin_file.options.module.?; | 2665 | const mod = self.bin_file.options.module.?; |
| ... | @@ -2666,6 +2671,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue | ... | @@ -2666,6 +2671,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue |
| 2666 | const flags: u2 = switch (ptr) { | 2671 | const flags: u2 = switch (ptr) { |
| 2667 | .got_load => 0b00, | 2672 | .got_load => 0b00, |
| 2668 | .direct_load => 0b01, | 2673 | .direct_load => 0b01, |
| | 2674 | .imports_load => 0b10, |
| 2669 | else => unreachable, | 2675 | else => unreachable, |
| 2670 | }; | 2676 | }; |
| 2671 | _ = try self.addInst(.{ | 2677 | _ = try self.addInst(.{ |
| ... | @@ -2763,6 +2769,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2763,6 +2769,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2763 | }, | 2769 | }, |
| 2764 | .got_load, | 2770 | .got_load, |
| 2765 | .direct_load, | 2771 | .direct_load, |
| | 2772 | .imports_load, |
| 2766 | .memory, | 2773 | .memory, |
| 2767 | .stack_offset, | 2774 | .stack_offset, |
| 2768 | => { | 2775 | => { |
| ... | @@ -2783,6 +2790,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2783,6 +2790,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2783 | }, | 2790 | }, |
| 2784 | .got_load, | 2791 | .got_load, |
| 2785 | .direct_load, | 2792 | .direct_load, |
| | 2793 | .imports_load, |
| 2786 | .memory, | 2794 | .memory, |
| 2787 | => { | 2795 | => { |
| 2788 | const value_lock: ?RegisterLock = switch (value) { | 2796 | const value_lock: ?RegisterLock = switch (value) { |
| ... | @@ -2854,6 +2862,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2854,6 +2862,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2854 | }, | 2862 | }, |
| 2855 | .got_load, | 2863 | .got_load, |
| 2856 | .direct_load, | 2864 | .direct_load, |
| | 2865 | .imports_load, |
| 2857 | .memory, | 2866 | .memory, |
| 2858 | => { | 2867 | => { |
| 2859 | if (abi_size <= 8) { | 2868 | if (abi_size <= 8) { |
| ... | @@ -3565,6 +3574,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3565,6 +3574,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3565 | .memory, | 3574 | .memory, |
| 3566 | .got_load, | 3575 | .got_load, |
| 3567 | .direct_load, | 3576 | .direct_load, |
| | 3577 | .imports_load, |
| 3568 | .eflags, | 3578 | .eflags, |
| 3569 | => { | 3579 | => { |
| 3570 | assert(abi_size <= 8); | 3580 | assert(abi_size <= 8); |
| ... | @@ -3650,7 +3660,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3650,7 +3660,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3650 | => { | 3660 | => { |
| 3651 | return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); | 3661 | return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); |
| 3652 | }, | 3662 | }, |
| 3653 | .got_load, .direct_load => { | 3663 | .got_load, |
| | 3664 | .direct_load, |
| | 3665 | .imports_load, |
| | 3666 | => { |
| 3654 | return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{}); | 3667 | return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{}); |
| 3655 | }, | 3668 | }, |
| 3656 | .eflags => { | 3669 | .eflags => { |
| ... | @@ -3661,7 +3674,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3661,7 +3674,10 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3661 | .memory => { | 3674 | .memory => { |
| 3662 | return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{}); | 3675 | return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{}); |
| 3663 | }, | 3676 | }, |
| 3664 | .got_load, .direct_load => { | 3677 | .got_load, |
| | 3678 | .direct_load, |
| | 3679 | .imports_load, |
| | 3680 | => { |
| 3665 | return self.fail("TODO implement x86 ADD/SUB/CMP destination symbol at index", .{}); | 3681 | return self.fail("TODO implement x86 ADD/SUB/CMP destination symbol at index", .{}); |
| 3666 | }, | 3682 | }, |
| 3667 | } | 3683 | } |
| ... | @@ -3729,7 +3745,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3729,7 +3745,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3729 | .memory => { | 3745 | .memory => { |
| 3730 | return self.fail("TODO implement x86 multiply source memory", .{}); | 3746 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 3731 | }, | 3747 | }, |
| 3732 | .got_load, .direct_load => { | 3748 | .got_load, |
| | 3749 | .direct_load, |
| | 3750 | .imports_load, |
| | 3751 | => { |
| 3733 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); | 3752 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); |
| 3734 | }, | 3753 | }, |
| 3735 | .eflags => { | 3754 | .eflags => { |
| ... | @@ -3773,7 +3792,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3773,7 +3792,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3773 | .memory, .stack_offset => { | 3792 | .memory, .stack_offset => { |
| 3774 | return self.fail("TODO implement x86 multiply source memory", .{}); | 3793 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 3775 | }, | 3794 | }, |
| 3776 | .got_load, .direct_load => { | 3795 | .got_load, |
| | 3796 | .direct_load, |
| | 3797 | .imports_load, |
| | 3798 | => { |
| 3777 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); | 3799 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); |
| 3778 | }, | 3800 | }, |
| 3779 | .eflags => { | 3801 | .eflags => { |
| ... | @@ -3784,7 +3806,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3784,7 +3806,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3784 | .memory => { | 3806 | .memory => { |
| 3785 | return self.fail("TODO implement x86 multiply destination memory", .{}); | 3807 | return self.fail("TODO implement x86 multiply destination memory", .{}); |
| 3786 | }, | 3808 | }, |
| 3787 | .got_load, .direct_load => { | 3809 | .got_load, |
| | 3810 | .direct_load, |
| | 3811 | .imports_load, |
| | 3812 | => { |
| 3788 | return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{}); | 3813 | return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{}); |
| 3789 | }, | 3814 | }, |
| 3790 | } | 3815 | } |
| ... | @@ -3948,6 +3973,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3948,6 +3973,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3948 | .memory => unreachable, | 3973 | .memory => unreachable, |
| 3949 | .got_load => unreachable, | 3974 | .got_load => unreachable, |
| 3950 | .direct_load => unreachable, | 3975 | .direct_load => unreachable, |
| | 3976 | .imports_load => unreachable, |
| 3951 | .eflags => unreachable, | 3977 | .eflags => unreachable, |
| 3952 | .register_overflow => unreachable, | 3978 | .register_overflow => unreachable, |
| 3953 | } | 3979 | } |
| ... | @@ -4025,15 +4051,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -4025,15 +4051,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 4025 | }); | 4051 | }); |
| 4026 | } | 4052 | } |
| 4027 | const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); | 4053 | const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); |
| | 4054 | try self.genSetReg(Type.initTag(.usize), .rax, .{ |
| | 4055 | .imports_load = sym_index, |
| | 4056 | }); |
| 4028 | _ = try self.addInst(.{ | 4057 | _ = try self.addInst(.{ |
| 4029 | .tag = .call_extern, | 4058 | .tag = .call, |
| 4030 | .ops = undefined, | 4059 | .ops = Mir.Inst.Ops.encode(.{ |
| 4031 | .data = .{ | 4060 | .reg1 = .rax, |
| 4032 | .relocation = .{ | 4061 | .flags = 0b01, |
| 4033 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.coff.sym_index, | 4062 | }), |
| 4034 | .sym_index = sym_index, | 4063 | .data = undefined, |
| 4035 | }, | | |
| 4036 | }, | | |
| 4037 | }); | 4064 | }); |
| 4038 | } else { | 4065 | } else { |
| 4039 | return self.fail("TODO implement calling bitcasted functions", .{}); | 4066 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| ... | @@ -4443,7 +4470,11 @@ fn genVarDbgInfo( | ... | @@ -4443,7 +4470,11 @@ fn genVarDbgInfo( |
| 4443 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; | 4470 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; |
| 4444 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | 4471 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 4445 | }, | 4472 | }, |
| 4446 | .memory, .got_load, .direct_load => { | 4473 | .memory, |
| | 4474 | .got_load, |
| | 4475 | .direct_load, |
| | 4476 | .imports_load, |
| | 4477 | => { |
| 4447 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); | 4478 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); |
| 4448 | const is_ptr = switch (tag) { | 4479 | const is_ptr = switch (tag) { |
| 4449 | .dbg_var_ptr => true, | 4480 | .dbg_var_ptr => true, |
| ... | @@ -4474,7 +4505,10 @@ fn genVarDbgInfo( | ... | @@ -4474,7 +4505,10 @@ fn genVarDbgInfo( |
| 4474 | try dbg_info.append(DW.OP.deref); | 4505 | try dbg_info.append(DW.OP.deref); |
| 4475 | } | 4506 | } |
| 4476 | switch (mcv) { | 4507 | switch (mcv) { |
| 4477 | .got_load, .direct_load => |index| try dw.addExprlocReloc(index, offset, is_ptr), | 4508 | .got_load, |
| | 4509 | .direct_load, |
| | 4510 | .imports_load, |
| | 4511 | => |index| try dw.addExprlocReloc(index, offset, is_ptr), |
| 4478 | else => {}, | 4512 | else => {}, |
| 4479 | } | 4513 | } |
| 4480 | }, | 4514 | }, |
| ... | @@ -5474,6 +5508,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -5474,6 +5508,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5474 | .memory, | 5508 | .memory, |
| 5475 | .direct_load, | 5509 | .direct_load, |
| 5476 | .got_load, | 5510 | .got_load, |
| | 5511 | .imports_load, |
| 5477 | => { | 5512 | => { |
| 5478 | if (abi_size <= 8) { | 5513 | if (abi_size <= 8) { |
| 5479 | const reg = try self.copyToTmpRegister(ty, mcv); | 5514 | const reg = try self.copyToTmpRegister(ty, mcv); |
| ... | @@ -5721,6 +5756,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5721,6 +5756,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5721 | .memory, | 5756 | .memory, |
| 5722 | .got_load, | 5757 | .got_load, |
| 5723 | .direct_load, | 5758 | .direct_load, |
| | 5759 | .imports_load, |
| 5724 | => { | 5760 | => { |
| 5725 | if (abi_size <= 8) { | 5761 | if (abi_size <= 8) { |
| 5726 | const reg = try self.copyToTmpRegister(ty, mcv); | 5762 | const reg = try self.copyToTmpRegister(ty, mcv); |
| ... | @@ -5848,6 +5884,7 @@ fn genInlineMemcpy( | ... | @@ -5848,6 +5884,7 @@ fn genInlineMemcpy( |
| 5848 | .memory, | 5884 | .memory, |
| 5849 | .got_load, | 5885 | .got_load, |
| 5850 | .direct_load, | 5886 | .direct_load, |
| | 5887 | .imports_load, |
| 5851 | => { | 5888 | => { |
| 5852 | try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_ptr); | 5889 | try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_ptr); |
| 5853 | }, | 5890 | }, |
| ... | @@ -5883,6 +5920,7 @@ fn genInlineMemcpy( | ... | @@ -5883,6 +5920,7 @@ fn genInlineMemcpy( |
| 5883 | .memory, | 5920 | .memory, |
| 5884 | .got_load, | 5921 | .got_load, |
| 5885 | .direct_load, | 5922 | .direct_load, |
| | 5923 | .imports_load, |
| 5886 | => { | 5924 | => { |
| 5887 | try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_ptr); | 5925 | try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_ptr); |
| 5888 | }, | 5926 | }, |
| ... | @@ -6021,6 +6059,7 @@ fn genInlineMemset( | ... | @@ -6021,6 +6059,7 @@ fn genInlineMemset( |
| 6021 | .memory, | 6059 | .memory, |
| 6022 | .got_load, | 6060 | .got_load, |
| 6023 | .direct_load, | 6061 | .direct_load, |
| | 6062 | .imports_load, |
| 6024 | => { | 6063 | => { |
| 6025 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_ptr); | 6064 | try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_ptr); |
| 6026 | }, | 6065 | }, |
| ... | @@ -6261,6 +6300,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6261,6 +6300,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6261 | }, | 6300 | }, |
| 6262 | .direct_load, | 6301 | .direct_load, |
| 6263 | .got_load, | 6302 | .got_load, |
| | 6303 | .imports_load, |
| 6264 | => { | 6304 | => { |
| 6265 | switch (ty.zigTypeTag()) { | 6305 | switch (ty.zigTypeTag()) { |
| 6266 | .Float => { | 6306 | .Float => { |
| ... | @@ -6655,7 +6695,11 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6655,7 +6695,11 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 6655 | // TODO Is this the only condition for pointer dereference for memcpy? | 6695 | // TODO Is this the only condition for pointer dereference for memcpy? |
| 6656 | const src: MCValue = blk: { | 6696 | const src: MCValue = blk: { |
| 6657 | switch (src_ptr) { | 6697 | switch (src_ptr) { |
| 6658 | .got_load, .direct_load, .memory => { | 6698 | .got_load, |
| | 6699 | .direct_load, |
| | 6700 | .imports_load, |
| | 6701 | .memory, |
| | 6702 | => { |
| 6659 | const reg = try self.register_manager.allocReg(null, gp); | 6703 | const reg = try self.register_manager.allocReg(null, gp); |
| 6660 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); | 6704 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); |
| 6661 | _ = try self.addInst(.{ | 6705 | _ = try self.addInst(.{ |