Commit 97c25fb8d0
Changed files (2)
src
arch
x86_64
test
behavior
src/arch/x86_64/CodeGen.zig
@@ -1604,6 +1604,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
.stack_offset => |off| {
break :inner off;
},
+ .memory,
+ .got_load,
+ .direct_load,
+ => {
+ break :blk try self.loadMemPtrIntoRegister(Type.usize, array);
+ },
else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
}
};
@@ -1845,6 +1851,42 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
+fn loadMemPtrIntoRegister(self: *Self, ptr_ty: Type, ptr: MCValue) InnerError!Register {
+ switch (ptr) {
+ .got_load,
+ .direct_load,
+ => |sym_index| {
+ const flags: u2 = switch (ptr) {
+ .got_load => 0b00,
+ .direct_load => 0b01,
+ else => unreachable,
+ };
+ const reg = try self.register_manager.allocReg(null);
+ _ = try self.addInst(.{
+ .tag = .lea_pie,
+ .ops = (Mir.Ops{
+ .reg1 = reg.to64(),
+ .flags = flags,
+ }).encode(),
+ .data = .{
+ .load_reloc = .{
+ .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,
+ .sym_index = sym_index,
+ },
+ },
+ });
+ return reg.to64();
+ },
+ .memory => |addr| {
+ // TODO: in case the address fits in an imm32 we can use [ds:imm32]
+ // instead of wasting an instruction copying the address to a register
+ const reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr });
+ return reg.to64();
+ },
+ else => unreachable,
+ }
+}
+
fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
_ = ptr_ty;
const abi_size = value_ty.abiSize(self.target.*);
@@ -1955,41 +1997,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
value.freezeIfRegister(&self.register_manager);
defer value.unfreezeIfRegister(&self.register_manager);
- const addr_reg: Register = blk: {
- switch (ptr) {
- .got_load,
- .direct_load,
- => |sym_index| {
- const flags: u2 = switch (ptr) {
- .got_load => 0b00,
- .direct_load => 0b01,
- else => unreachable,
- };
- const addr_reg = try self.register_manager.allocReg(null);
- _ = try self.addInst(.{
- .tag = .lea_pie,
- .ops = (Mir.Ops{
- .reg1 = addr_reg.to64(),
- .flags = flags,
- }).encode(),
- .data = .{
- .load_reloc = .{
- .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,
- .sym_index = sym_index,
- },
- },
- });
- break :blk addr_reg;
- },
- .memory => |addr| {
- // TODO: in case the address fits in an imm32 we can use [ds:imm32]
- // instead of wasting an instruction copying the address to a register
- const addr_reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr });
- break :blk addr_reg;
- },
- else => unreachable,
- }
- };
+ const addr_reg = try self.loadMemPtrIntoRegister(ptr_ty, ptr);
// to get the actual address of the value we want to modify we have to go through the GOT
// mov reg, [reg]
@@ -3831,33 +3839,11 @@ fn genInlineMemcpy(self: *Self, stack_offset: i32, stack_reg: Register, ty: Type
const addr_reg: Register = blk: {
switch (val) {
- .memory => |addr| {
- const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr });
- break :blk reg;
- },
+ .memory,
.direct_load,
.got_load,
- => |sym_index| {
- const flags: u2 = switch (val) {
- .got_load => 0b00,
- .direct_load => 0b01,
- else => unreachable,
- };
- const addr_reg = (try self.register_manager.allocReg(null)).to64();
- _ = try self.addInst(.{
- .tag = .lea_pie,
- .ops = (Mir.Ops{
- .reg1 = addr_reg,
- .flags = flags,
- }).encode(),
- .data = .{
- .load_reloc = .{
- .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,
- .sym_index = sym_index,
- },
- },
- });
- break :blk addr_reg;
+ => {
+ break :blk try self.loadMemPtrIntoRegister(Type.usize, val);
},
.stack_offset => |off| {
const addr_reg = (try self.register_manager.allocReg(null)).to64();
test/behavior/array.zig
@@ -153,7 +153,7 @@ test "void arrays" {
test "nested arrays" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
for (array_of_strings) |s, i| {
@@ -525,8 +525,8 @@ test "zero-sized array with recursive type definition" {
test "type coercion of anon struct literal to array" {
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
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
const S = struct {
const U = union {
@@ -543,8 +543,8 @@ test "type coercion of anon struct literal to array" {
try expect(arr1[1] == 56);
try expect(arr1[2] == 54);
- if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
var x2: U = .{ .a = 42 };
const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } };