riscv: implement errunion_payload_ptr_set

This commit is contained in:
David Rubin 2024-09-01 02:49:47 -07:00 committed by mlugg
parent 28383d4d98
commit fbac7afa0f
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
4 changed files with 40 additions and 7 deletions

View File

@ -3471,9 +3471,48 @@ fn airUnwrapErrPayloadPtr(func: *Func, inst: Air.Inst.Index) !void {
return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
} }
// *(E!T) => *T
fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .errunion_payload_ptr_set for {}", .{func.target.cpu.arch}); const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
const zcu = func.pt.zcu;
const src_ty = func.typeOf(ty_op.operand);
const src_mcv = try func.resolveInst(ty_op.operand);
// `src_reg` contains the pointer to the error union
const src_reg = switch (src_mcv) {
.register => |reg| reg,
else => try func.copyToTmpRegister(src_ty, src_mcv),
};
const src_lock = func.register_manager.lockRegAssumeUnused(src_reg);
defer func.register_manager.unlockReg(src_lock);
// we set the place of where the error would have been to 0
const eu_ty = src_ty.childType(zcu);
const pl_ty = eu_ty.errorUnionPayload(zcu);
const err_ty = eu_ty.errorUnionSet(zcu);
const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu));
try func.genSetMem(.{ .reg = src_reg }, err_off, err_ty, .{ .immediate = 0 });
const dst_reg, const dst_lock = if (func.reuseOperand(inst, ty_op.operand, 0, src_mcv))
.{ src_reg, null }
else
try func.allocReg(.int);
defer if (dst_lock) |lock| func.register_manager.unlockReg(lock);
// move the pointer to be at the payload
const pl_off = errUnionPayloadOffset(pl_ty, zcu);
try func.genBinOp(
.add,
.{ .register = src_reg },
Type.u64,
.{ .immediate = pl_off },
Type.u64,
dst_reg,
);
break :result .{ .register = dst_reg };
};
return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
} }

View File

@ -164,8 +164,6 @@ const Piece = packed struct {
}; };
test "load non byte-sized optional value" { test "load non byte-sized optional value" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// Originally reported at https://github.com/ziglang/zig/issues/14200 // Originally reported at https://github.com/ziglang/zig/issues/14200
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
@ -181,8 +179,6 @@ test "load non byte-sized optional value" {
} }
test "load non byte-sized value in struct" { test "load non byte-sized value in struct" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;

View File

@ -1214,7 +1214,6 @@ test "anon init through error union" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct { const S = struct {
a: u32, a: u32,

View File

@ -347,7 +347,6 @@ test "try terminating an infinite loop" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// Test coverage for https://github.com/ziglang/zig/issues/13546 // Test coverage for https://github.com/ziglang/zig/issues/13546
const Foo = struct { const Foo = struct {