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