diff options
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 37 | ||||
| -rw-r--r-- | src/codegen.zig | 24 | ||||
| -rw-r--r-- | test/behavior/array.zig | 4 |
3 files changed, 61 insertions, 4 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 79e5c88050..33fd2c8321 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2599,6 +2599,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type defer value.unfreezeIfRegister(&self.register_manager); const addr_reg = try self.register_manager.allocReg(null); + self.register_manager.freezeRegs(&.{addr_reg}); + defer self.register_manager.unfreezeRegs(&.{addr_reg}); + try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); // 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 .data = .{ .imm = 0 }, }); }, + .got_load, + .direct_load, + .memory, + => { + if (abi_size <= 8) { + const tmp_reg = try self.register_manager.allocReg(null); + self.register_manager.freezeRegs(&.{tmp_reg}); + defer self.register_manager.unfreezeRegs(&.{tmp_reg}); + + try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); + + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .reg1 = tmp_reg, + .reg2 = tmp_reg, + .flags = 0b01, + }).encode(), + .data = .{ .imm = 0 }, + }); + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .reg1 = addr_reg.to64(), + .reg2 = tmp_reg, + .flags = 0b10, + }).encode(), + .data = .{ .imm = 0 }, + }); + return; + } + + try self.genInlineMemcpy(.{ .register = addr_reg.to64() }, value, .{ .immediate = abi_size }, .{}); + }, else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}), } }, diff --git a/src/codegen.zig b/src/codegen.zig index f0cf8da3b3..265c205f2f 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -392,6 +392,30 @@ pub fn generateSymbol( }, } }, + .elem_ptr => { + const elem_ptr = typed_value.val.castTag(.elem_ptr).?.data; + const elem_size = typed_value.ty.childType().abiSize(target); + const addend = @intCast(u32, elem_ptr.index * elem_size); + const array_ptr = elem_ptr.array_ptr; + + switch (array_ptr.tag()) { + .decl_ref => { + const decl = array_ptr.castTag(.decl_ref).?.data; + return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{ + .parent_atom_index = reloc_info.parent_atom_index, + .addend = (reloc_info.addend orelse 0) + addend, + }); + }, + else => return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for pointer type value: '{s}'", + .{@tagName(typed_value.val.tag())}, + ), + }, + } + }, else => return Result{ .fail = try ErrorMsg.create( bin_file.allocator, diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 634be7f5ad..cf9eaf660c 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -179,7 +179,6 @@ fn plusOne(x: u32) u32 { test "single-item pointer to array indexing and slicing" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); @@ -206,7 +205,6 @@ fn doSomeMangling(array: *[4]u8) void { test "implicit cast zero sized array ptr to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; { @@ -244,7 +242,6 @@ const Str = struct { a: []Sub }; test "set global var array via slice embedded in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var s = Str{ .a = s_array[0..] }; @@ -261,7 +258,6 @@ test "set global var array via slice embedded in struct" { test "read/write through global variable array of struct fields initialized via array mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { |
