| 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 | 2599 | defer value.unfreezeIfRegister(&self.register_manager); |
| 2600 | 2600 | |
| 2601 | 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 | 2605 | try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); |
| 2603 | 2606 | |
| 2604 | 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 | 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 | 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 | 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 | 419 | else => return Result{ |
| 396 | 420 | .fail = try ErrorMsg.create( |
| 397 | 421 | bin_file.allocator, |
test/behavior/array.zig-4| ... | ... | @@ -179,7 +179,6 @@ fn plusOne(x: u32) u32 { |
| 179 | 179 | |
| 180 | 180 | test "single-item pointer to array indexing and slicing" { |
| 181 | 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 182 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 183 | 182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 184 | 183 | |
| 185 | 184 | try testSingleItemPtrArrayIndexSlice(); |
| ... | ... | @@ -206,7 +205,6 @@ fn doSomeMangling(array: *[4]u8) void { |
| 206 | 205 | |
| 207 | 206 | test "implicit cast zero sized array ptr to slice" { |
| 208 | 207 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 210 | 208 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 211 | 209 | |
| 212 | 210 | { |
| ... | ... | @@ -244,7 +242,6 @@ const Str = struct { a: []Sub }; |
| 244 | 242 | test "set global var array via slice embedded in struct" { |
| 245 | 243 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 246 | 244 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 247 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 248 | 245 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 249 | 246 | |
| 250 | 247 | var s = Str{ .a = s_array[0..] }; |
| ... | ... | @@ -261,7 +258,6 @@ test "set global var array via slice embedded in struct" { |
| 261 | 258 | test "read/write through global variable array of struct fields initialized via array mult" { |
| 262 | 259 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 263 | 260 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 264 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 265 | 261 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 266 | 262 | |
| 267 | 263 | const S = struct { |