mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
codegen: handle elem_ptr when lowering to memory
* x64: handle storing from-to non-stack memory
This commit is contained in:
parent
1c8a86f063
commit
3ec74a1cd8
@ -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}),
|
||||
}
|
||||
},
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user