| author | |
| committer | |
| log | fbac7afa0f280eb271e802046ae1f3f836a9f6b2 |
| tree | 51c47833f3ec9c98f474cd61f0d4e2e3840d9df7 |
| parent | 28383d4d985cd04c897f6b6a63bd2107d8e2a8e9 |
| signature |
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 | } |
| 3473 | 3473 | ||
| 3474 | // *(E!T) => *T | ||
| 3474 | fn airErrUnionPayloadPtrSet(func: *Func, inst: Air.Inst.Index) !void { | 3475 | fn 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 | } |
| 3479 | 3518 |
test/behavior/cast_int.zig-4| ... | @@ -164,8 +164,6 @@ const Piece = packed struct { | ... | @@ -164,8 +164,6 @@ const Piece = packed struct { |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | test "load non byte-sized optional value" { | 166 | test "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/14200 | 167 | // 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; |
| 171 | 169 | ||
| ... | @@ -181,8 +179,6 @@ test "load non byte-sized optional value" { | ... | @@ -181,8 +179,6 @@ test "load non byte-sized optional value" { |
| 181 | } | 179 | } |
| 182 | 180 | ||
| 183 | test "load non byte-sized value in struct" { | 181 | test "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 TODO | 182 | 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; |
| 188 | 184 |
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; // TODO | 1214 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1215 | 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; | ||
| 1218 | 1217 | ||
| 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; // TODO | 347 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 348 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 348 | 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; | ||
| 351 | 350 | ||
| 352 | // Test coverage for https://github.com/ziglang/zig/issues/13546 | 351 | // Test coverage for https://github.com/ziglang/zig/issues/13546 |
| 353 | const Foo = struct { | 352 | const Foo = struct { |