authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-09-01 02:49:47-07:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-09-01 17:34:06+01:00
logfbac7afa0f280eb271e802046ae1f3f836a9f6b2
tree51c47833f3ec9c98f474cd61f0d4e2e3840d9df7
parent28383d4d985cd04c897f6b6a63bd2107d8e2a8e9
signaturelock-open Commit is signed but in an unrecognized format.

riscv: implement `errunion_payload_ptr_set`


4 files changed, 40 insertions(+), 7 deletions(-)

src/arch/riscv64/CodeGen.zig+40-1
...@@ -3471,9 +3471,48 @@ fn airUnwrapErrPayloadPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -3471,9 +3471,48 @@ fn airUnwrapErrPayloadPtr(func: *Func, inst: Air.Inst.Index) !void {
3471 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });3471 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3472}3472}
34733473
3474// *(E!T) => *T
3474fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {3475fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {
3475 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3476 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3476 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .errunion_payload_ptr_set for {}", .{func.target.cpu.arch});3477 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
3478 const zcu = func.pt.zcu;
3479 const src_ty = func.typeOf(ty_op.operand);
3480 const src_mcv = try func.resolveInst(ty_op.operand);
3481
3482 // `src_reg` contains the pointer to the error union
3483 const src_reg = switch (src_mcv) {
3484 .register => |reg| reg,
3485 else => try func.copyToTmpRegister(src_ty, src_mcv),
3486 };
3487 const src_lock = func.register_manager.lockRegAssumeUnused(src_reg);
3488 defer func.register_manager.unlockReg(src_lock);
3489
3490 // we set the place of where the error would have been to 0
3491 const eu_ty = src_ty.childType(zcu);
3492 const pl_ty = eu_ty.errorUnionPayload(zcu);
3493 const err_ty = eu_ty.errorUnionSet(zcu);
3494 const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, zcu));
3495 try func.genSetMem(.{ .reg = src_reg }, err_off, err_ty, .{ .immediate = 0 });
3496
3497 const dst_reg, const dst_lock = if (func.reuseOperand(inst, ty_op.operand, 0, src_mcv))
3498 .{ src_reg, null }
3499 else
3500 try func.allocReg(.int);
3501 defer if (dst_lock) |lock| func.register_manager.unlockReg(lock);
3502
3503 // move the pointer to be at the payload
3504 const pl_off = errUnionPayloadOffset(pl_ty, zcu);
3505 try func.genBinOp(
3506 .add,
3507 .{ .register = src_reg },
3508 Type.u64,
3509 .{ .immediate = pl_off },
3510 Type.u64,
3511 dst_reg,
3512 );
3513
3514 break :result .{ .register = dst_reg };
3515 };
3477 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });3516 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3478}3517}
34793518
test/behavior/cast_int.zig-4
...@@ -164,8 +164,6 @@ const Piece = packed struct {...@@ -164,8 +164,6 @@ const Piece = packed struct {
164};164};
165165
166test "load non byte-sized optional value" {166test "load non byte-sized optional value" {
167 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
168
169 // Originally reported at https://github.com/ziglang/zig/issues/14200167 // Originally reported at https://github.com/ziglang/zig/issues/14200
170 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;168 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
171169
...@@ -181,8 +179,6 @@ test "load non byte-sized optional value" {...@@ -181,8 +179,6 @@ test "load non byte-sized optional value" {
181}179}
182180
183test "load non byte-sized value in struct" {181test "load non byte-sized value in struct" {
184 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185
186 if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO182 if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO
187 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;183 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
188184
test/behavior/struct.zig-1
...@@ -1214,7 +1214,6 @@ test "anon init through error union" {...@@ -1214,7 +1214,6 @@ test "anon init through error union" {
1214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1215 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1215 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1216 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1216 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1217 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12181217
1219 const S = struct {1218 const S = struct {
1220 a: u32,1219 a: u32,
test/behavior/while.zig-1
...@@ -347,7 +347,6 @@ test "try terminating an infinite loop" {...@@ -347,7 +347,6 @@ test "try terminating an infinite loop" {
347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
349 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;349 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
351350
352 // Test coverage for https://github.com/ziglang/zig/issues/13546351 // Test coverage for https://github.com/ziglang/zig/issues/13546
353 const Foo = struct {352 const Foo = struct {