authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-03 00:03:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-02 20:04:34-05:00
log3ec74a1cd8b868b7cebfd584dec3f20a9aa2bda6
treec8406c16704cd4a47247618395257180cf7f3a0d
parent1c8a86f063b65e95c2e23ceaa40843069adfdc23

codegen: handle elem_ptr when lowering to memory

* x64: handle storing from-to non-stack memory

3 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);
26002600
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);
26032606
2604 // to get the actual address of the value we want to modify we have to go through the GOT2607 // 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 {
179179
180test "single-item pointer to array indexing and slicing" {180test "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;
184183
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 {
206205
207test "implicit cast zero sized array ptr to slice" {206test "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;
211209
212 {210 {
...@@ -244,7 +242,6 @@ const Str = struct { a: []Sub };...@@ -244,7 +242,6 @@ const Str = struct { a: []Sub };
244test "set global var array via slice embedded in struct" {242test "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; // TODO244 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; // TODO245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
249246
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" {
261test "read/write through global variable array of struct fields initialized via array mult" {258test "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; // TODO260 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; // TODO261 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
266262
267 const S = struct {263 const S = struct {