| author | |
| committer | |
| log | 3ec74a1cd8b868b7cebfd584dec3f20a9aa2bda6 |
| tree | c8406c16704cd4a47247618395257180cf7f3a0d |
| parent | 1c8a86f063b65e95c2e23ceaa40843069adfdc23 |
* x64: handle storing from-to non-stack memory3 files changed, 61 insertions(+), 4 deletions(-)
src/arch/x86_64/CodeGen.zig+37| ... | @@ -2599,6 +2599,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2599,6 +2599,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2599 | defer value.unfreezeIfRegister(&self.register_manager); | 2599 | defer value.unfreezeIfRegister(&self.register_manager); |
| 2600 | 2600 | ||
| 2601 | const addr_reg = try self.register_manager.allocReg(null); | 2601 | const addr_reg = try self.register_manager.allocReg(null); |
| 2602 | self.register_manager.freezeRegs(&.{addr_reg}); | ||
| 2603 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); | ||
| 2604 | |||
| 2602 | try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); | 2605 | try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); |
| 2603 | 2606 | ||
| 2604 | // to get the actual address of the value we want to modify we have to go through the GOT | 2607 | // to get the actual address of the value we want to modify we have to go through the GOT |
| ... | @@ -2662,6 +2665,40 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2662,6 +2665,40 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2662 | .data = .{ .imm = 0 }, | 2665 | .data = .{ .imm = 0 }, |
| 2663 | }); | 2666 | }); |
| 2664 | }, | 2667 | }, |
| 2668 | .got_load, | ||
| 2669 | .direct_load, | ||
| 2670 | .memory, | ||
| 2671 | => { | ||
| 2672 | if (abi_size <= 8) { | ||
| 2673 | const tmp_reg = try self.register_manager.allocReg(null); | ||
| 2674 | self.register_manager.freezeRegs(&.{tmp_reg}); | ||
| 2675 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); | ||
| 2676 | |||
| 2677 | try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); | ||
| 2678 | |||
| 2679 | _ = try self.addInst(.{ | ||
| 2680 | .tag = .mov, | ||
| 2681 | .ops = (Mir.Ops{ | ||
| 2682 | .reg1 = tmp_reg, | ||
| 2683 | .reg2 = tmp_reg, | ||
| 2684 | .flags = 0b01, | ||
| 2685 | }).encode(), | ||
| 2686 | .data = .{ .imm = 0 }, | ||
| 2687 | }); | ||
| 2688 | _ = try self.addInst(.{ | ||
| 2689 | .tag = .mov, | ||
| 2690 | .ops = (Mir.Ops{ | ||
| 2691 | .reg1 = addr_reg.to64(), | ||
| 2692 | .reg2 = tmp_reg, | ||
| 2693 | .flags = 0b10, | ||
| 2694 | }).encode(), | ||
| 2695 | .data = .{ .imm = 0 }, | ||
| 2696 | }); | ||
| 2697 | return; | ||
| 2698 | } | ||
| 2699 | |||
| 2700 | try self.genInlineMemcpy(.{ .register = addr_reg.to64() }, value, .{ .immediate = abi_size }, .{}); | ||
| 2701 | }, | ||
| 2665 | else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}), | 2702 | else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}), |
| 2666 | } | 2703 | } |
| 2667 | }, | 2704 | }, |
src/codegen.zig+24| ... | @@ -392,6 +392,30 @@ pub fn generateSymbol( | ... | @@ -392,6 +392,30 @@ pub fn generateSymbol( |
| 392 | }, | 392 | }, |
| 393 | } | 393 | } |
| 394 | }, | 394 | }, |
| 395 | .elem_ptr => { | ||
| 396 | const elem_ptr = typed_value.val.castTag(.elem_ptr).?.data; | ||
| 397 | const elem_size = typed_value.ty.childType().abiSize(target); | ||
| 398 | const addend = @intCast(u32, elem_ptr.index * elem_size); | ||
| 399 | const array_ptr = elem_ptr.array_ptr; | ||
| 400 | |||
| 401 | switch (array_ptr.tag()) { | ||
| 402 | .decl_ref => { | ||
| 403 | const decl = array_ptr.castTag(.decl_ref).?.data; | ||
| 404 | return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{ | ||
| 405 | .parent_atom_index = reloc_info.parent_atom_index, | ||
| 406 | .addend = (reloc_info.addend orelse 0) + addend, | ||
| 407 | }); | ||
| 408 | }, | ||
| 409 | else => return Result{ | ||
| 410 | .fail = try ErrorMsg.create( | ||
| 411 | bin_file.allocator, | ||
| 412 | src_loc, | ||
| 413 | "TODO implement generateSymbol for pointer type value: '{s}'", | ||
| 414 | .{@tagName(typed_value.val.tag())}, | ||
| 415 | ), | ||
| 416 | }, | ||
| 417 | } | ||
| 418 | }, | ||
| 395 | else => return Result{ | 419 | else => return Result{ |
| 396 | .fail = try ErrorMsg.create( | 420 | .fail = try ErrorMsg.create( |
| 397 | bin_file.allocator, | 421 | bin_file.allocator, |
test/behavior/array.zig-4| ... | @@ -179,7 +179,6 @@ fn plusOne(x: u32) u32 { | ... | @@ -179,7 +179,6 @@ fn plusOne(x: u32) u32 { |
| 179 | 179 | ||
| 180 | test "single-item pointer to array indexing and slicing" { | 180 | test "single-item pointer to array indexing and slicing" { |
| 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 182 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 183 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 184 | 183 | ||
| 185 | try testSingleItemPtrArrayIndexSlice(); | 184 | try testSingleItemPtrArrayIndexSlice(); |
| ... | @@ -206,7 +205,6 @@ fn doSomeMangling(array: *[4]u8) void { | ... | @@ -206,7 +205,6 @@ fn doSomeMangling(array: *[4]u8) void { |
| 206 | 205 | ||
| 207 | test "implicit cast zero sized array ptr to slice" { | 206 | test "implicit cast zero sized array ptr to slice" { |
| 208 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 207 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 210 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 208 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 211 | 209 | ||
| 212 | { | 210 | { |
| ... | @@ -244,7 +242,6 @@ const Str = struct { a: []Sub }; | ... | @@ -244,7 +242,6 @@ const Str = struct { a: []Sub }; |
| 244 | test "set global var array via slice embedded in struct" { | 242 | test "set global var array via slice embedded in struct" { |
| 245 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 243 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 246 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 244 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 247 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 248 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 245 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 249 | 246 | ||
| 250 | var s = Str{ .a = s_array[0..] }; | 247 | var s = Str{ .a = s_array[0..] }; |
| ... | @@ -261,7 +258,6 @@ test "set global var array via slice embedded in struct" { | ... | @@ -261,7 +258,6 @@ test "set global var array via slice embedded in struct" { |
| 261 | test "read/write through global variable array of struct fields initialized via array mult" { | 258 | test "read/write through global variable array of struct fields initialized via array mult" { |
| 262 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 259 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 263 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 260 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 264 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 265 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 261 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 266 | 262 | ||
| 267 | const S = struct { | 263 | const S = struct { |