Commit 25f73224f7
Changed files (7)
src
arch
aarch64
src/arch/aarch64/CodeGen.zig
@@ -2079,7 +2079,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
return if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(operand);
- const struct_ty = self.air.typeOf(operand).childType();
+ const ptr_ty = self.air.typeOf(operand);
+ const struct_ty = ptr_ty.childType();
const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
const struct_field_ty = struct_ty.structFieldType(index);
@@ -2088,7 +2089,28 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
.ptr_stack_offset => |off| {
break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size };
},
- else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}),
+ else => {
+ const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
+ .immediate = struct_field_offset,
+ });
+ self.register_manager.freezeRegs(&.{offset_reg});
+ defer self.register_manager.unfreezeRegs(&.{offset_reg});
+
+ const addr_reg = try self.copyToTmpRegister(ptr_ty, mcv);
+ self.register_manager.freezeRegs(&.{addr_reg});
+ defer self.register_manager.unfreezeRegs(&.{addr_reg});
+
+ const dest = try self.binOp(
+ .add,
+ null,
+ .{ .register = addr_reg },
+ .{ .register = offset_reg },
+ Type.usize,
+ Type.usize,
+ );
+
+ break :result dest;
+ },
}
};
}
@@ -3117,17 +3139,18 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
_ = sym_index;
return self.fail("TODO implement set stack variable from {}", .{mcv});
},
- .memory => |vaddr| {
- _ = vaddr;
- return self.fail("TODO implement set stack variable from memory vaddr", .{});
- },
- .stack_offset => |off| {
- if (stack_offset == off)
- return; // Copy stack variable to itself; nothing to do.
+ .memory,
+ .stack_offset,
+ => {
+ switch (mcv) {
+ .stack_offset => |off| {
+ if (stack_offset == off)
+ return; // Copy stack variable to itself; nothing to do.
+ },
+ else => {},
+ }
- const ptr_bits = self.target.cpu.arch.ptrBitWidth();
- const ptr_bytes: u64 = @divExact(ptr_bits, 8);
- if (abi_size <= ptr_bytes) {
+ if (abi_size <= 8) {
const reg = try self.copyToTmpRegister(ty, mcv);
return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
} else {
@@ -3142,17 +3165,23 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
const count_reg = regs[3];
const tmp_reg = regs[4];
- // sub src_reg, fp, #off
- const adj_src_offset = off + abi_size;
- const src_offset = math.cast(u12, adj_src_offset) catch return self.fail("TODO load: larger stack offsets", .{});
- _ = try self.addInst(.{
- .tag = .sub_immediate,
- .data = .{ .rr_imm12_sh = .{
- .rd = src_reg,
- .rn = .x29,
- .imm12 = src_offset,
- } },
- });
+ switch (mcv) {
+ .stack_offset => |off| {
+ // sub src_reg, fp, #off
+ const adj_src_offset = off + abi_size;
+ const src_offset = math.cast(u12, adj_src_offset) catch return self.fail("TODO load: larger stack offsets", .{});
+ _ = try self.addInst(.{
+ .tag = .sub_immediate,
+ .data = .{ .rr_imm12_sh = .{
+ .rd = src_reg,
+ .rn = .x29,
+ .imm12 = src_offset,
+ } },
+ });
+ },
+ .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }),
+ else => unreachable,
+ }
// sub dst_reg, fp, #stack_offset
const adj_dst_off = stack_offset + abi_size;
test/behavior/bugs/2006.zig
@@ -6,7 +6,7 @@ const S = struct {
p: *S,
};
test "bug 2006" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
var a: S = undefined;
a = S{ .p = undefined };
test/behavior/align.zig
@@ -311,7 +311,7 @@ fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void {
}
test "alignment of function with c calling convention" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
var runtime_nothing = ¬hing;
test/behavior/basic.zig
@@ -610,7 +610,7 @@ test "comptime cast fn to ptr" {
}
test "equality compare fn ptrs" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
var a = &emptyFn;
@@ -618,7 +618,7 @@ test "equality compare fn ptrs" {
}
test "self reference through fn ptr field" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
test/behavior/cast.zig
@@ -1013,7 +1013,7 @@ test "cast from array reference to fn: comptime fn ptr" {
try expect(@ptrToInt(f) == @ptrToInt(&global_array));
}
test "cast from array reference to fn: runtime fn ptr" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) 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
test/behavior/slice.zig
@@ -81,7 +81,7 @@ fn assertLenIsZero(msg: []const u8) !void {
}
test "access len index of sentinel-terminated slice" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
const S = struct {
test/behavior/struct.zig
@@ -43,7 +43,6 @@ const StructWithFields = struct {
};
test "non-packed struct has fields padded out to the required alignment" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
const foo = StructWithFields{ .a = 5, .b = 1, .c = 10, .d = 2 };
@@ -67,7 +66,7 @@ const SmallStruct = struct {
};
test "lower unnamed constants" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
var foo = SmallStruct{ .a = 1, .b = 255 };
try expect(foo.first() == 1);
try expect(foo.second() == 255);
@@ -186,7 +185,6 @@ test "store member function in variable" {
}
test "member functions" {
- if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const r = MemberFnRand{ .seed = 1234 };
try expect(r.getSeed() == 1234);
}