diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index f887c6cb13..0c6da840eb 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -3364,8 +3364,38 @@ fn airOptionalPayloadPtr(func: *Func, inst: Air.Inst.Index) !void { } fn airOptionalPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { + const zcu = func.pt.zcu; + 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 .optional_payload_ptr_set for {}", .{func.target.cpu.arch}); + const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { + const dst_ty = func.typeOfIndex(inst); + const src_ty = func.typeOf(ty_op.operand); + const opt_ty = src_ty.childType(zcu); + const src_mcv = try func.resolveInst(ty_op.operand); + + if (opt_ty.optionalReprIsPayload(zcu)) { + break :result if (func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try func.copyToNewRegister(inst, src_mcv); + } + + const dst_mcv: MCValue = if (src_mcv.isRegister() and + func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try func.copyToNewRegister(inst, src_mcv); + + const pl_ty = dst_ty.childType(zcu); + const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); + try func.genSetMem( + .{ .reg = dst_mcv.getReg().? }, + pl_abi_size, + Type.bool, + .{ .immediate = 1 }, + ); + break :result dst_mcv; + }; return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index b414977ad6..7dca19d212 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1875,7 +1875,6 @@ test "peer type resolution: vector and optional vector" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var a: ?@Vector(3, u32) = .{ 0, 1, 2 }; var b: @Vector(3, u32) = .{ 3, 4, 5 }; diff --git a/test/behavior/decl_literals.zig b/test/behavior/decl_literals.zig index b5961c2c13..f2f7f8a81f 100644 --- a/test/behavior/decl_literals.zig +++ b/test/behavior/decl_literals.zig @@ -33,8 +33,7 @@ test "decl literal with pointer" { } test "call decl literal with optional" { - if (builtin.zig_backend == .stage2_riscv64 or - builtin.zig_backend == .stage2_sparc64 or + if (builtin.zig_backend == .stage2_sparc64 or builtin.zig_backend == .stage2_arm or builtin.zig_backend == .stage2_aarch64 or builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index 53738a107b..967bc8cf85 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -320,7 +320,6 @@ test "coerce an anon struct literal to optional struct" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const Struct = struct { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 4694758e19..989da34ae7 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1165,7 +1165,6 @@ test "anon init through error unions and optionals" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { a: u32, @@ -1193,7 +1192,6 @@ test "anon init through optional" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { a: u32, @@ -1503,7 +1501,6 @@ test "no dependency loop on pointer to optional struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const A = struct { b: B }; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 9938c3c045..b0209c124e 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -1268,7 +1268,6 @@ test "extern union most-aligned field is smaller" { if (builtin.zig_backend == .stage2_aarch64) 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_riscv64) return error.SkipZigTest; const U = extern union { in6: extern struct {