Skip to content

Commit fbac7af

Browse files
Rexicon226mlugg
authored andcommitted
riscv: implement errunion_payload_ptr_set
1 parent 28383d4 commit fbac7af

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

src/arch/riscv64/CodeGen.zig

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3471,9 +3471,48 @@ fn airUnwrapErrPayloadPtr(func: *Func, inst: Air.Inst.Index) !void {
34713471
return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
34723472
}
34733473

3474+
// *(E!T) => *T
34743475
fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void {
34753476
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+
};
34773516
return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
34783517
}
34793518

test/behavior/cast_int.zig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ const Piece = packed struct {
164164
};
165165

166166
test "load non byte-sized optional value" {
167-
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
168-
169167
// Originally reported at https://github.com/ziglang/zig/issues/14200
170168
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
171169

@@ -181,8 +179,6 @@ test "load non byte-sized optional value" {
181179
}
182180

183181
test "load non byte-sized value in struct" {
184-
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185-
186182
if (builtin.cpu.arch.endian() != .little) return error.SkipZigTest; // packed struct TODO
187183
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
188184

test/behavior/struct.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,6 @@ test "anon init through error union" {
12141214
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12151215
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12161216
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1217-
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12181217

12191218
const S = struct {
12201219
a: u32,

test/behavior/while.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ test "try terminating an infinite loop" {
347347
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
348348
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
349349
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
350-
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
351350

352351
// Test coverage for https://github.com/ziglang/zig/issues/13546
353352
const Foo = struct {

0 commit comments

Comments
 (0)