authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-14 00:33:31+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-24 21:19:27+07:00
log921f77622492bce8995ac61bdfcf4b46c44865a2
treec4fd22f8a48cca7a832bc64c21e58ae36688d819
parent40590c8bf976a44451e161b4a75d7f8bac15a7d4

stage2: sparc64: Implement airTry


1 files changed, 46 insertions(+), 1 deletions(-)

src/arch/sparc64/CodeGen.zig+46-1
......@@ -13,6 +13,7 @@ const link = @import("../../link.zig");
1313const Module = @import("../../Module.zig");
1414const TypedValue = @import("../../TypedValue.zig");
1515const ErrorMsg = Module.ErrorMsg;
16const codegen = @import("../../codegen.zig");
1617const Air = @import("../../Air.zig");
1718const Mir = @import("Mir.zig");
1819const Emit = @import("Emit.zig");
......@@ -26,6 +27,8 @@ const build_options = @import("build_options");
2627
2728const bits = @import("bits.zig");
2829const abi = @import("abi.zig");
30const errUnionPayloadOffset = codegen.errUnionPayloadOffset;
31const errUnionErrorOffset = codegen.errUnionErrorOffset;
2932const Instruction = bits.Instruction;
3033const ShiftWidth = Instruction.ShiftWidth;
3134const RegisterManager = abi.RegisterManager;
......@@ -627,7 +630,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
627630 .prefetch => @panic("TODO try self.airPrefetch(inst)"),
628631 .mul_add => @panic("TODO try self.airMulAdd(inst)"),
629632
630 .@"try" => @panic("TODO try self.airTry(inst)"),
633 .@"try" => try self.airTry(inst),
631634 .try_ptr => @panic("TODO try self.airTryPtr(inst)"),
632635
633636 .dbg_var_ptr,
......@@ -1796,6 +1799,24 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
17961799 return self.fail("TODO implement switch for {}", .{self.target.cpu.arch});
17971800}
17981801
1802fn airTry(self: *Self, inst: Air.Inst.Index) !void {
1803 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1804 const extra = self.air.extraData(Air.Try, pl_op.payload);
1805 const body = self.air.extra[extra.end..][0..extra.data.body_len];
1806 const result: MCValue = result: {
1807 const error_union_ty = self.air.typeOf(pl_op.operand);
1808 const error_union = try self.resolveInst(pl_op.operand);
1809 const is_err_result = try self.isErr(error_union_ty, error_union);
1810 const reloc = try self.condBr(is_err_result);
1811
1812 try self.genBody(body);
1813
1814 try self.performReloc(reloc);
1815 break :result try self.errUnionPayload(error_union, error_union_ty);
1816 };
1817 return self.finishAir(inst, result, .{ pl_op.operand, .none, .none });
1818}
1819
17991820fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
18001821 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
18011822 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
......@@ -2475,6 +2496,30 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
24752496 try table.ensureUnusedCapacity(self.gpa, additional_count);
24762497}
24772498
2499/// Given an error union, returns the payload
2500fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
2501 const err_ty = error_union_ty.errorUnionSet();
2502 const payload_ty = error_union_ty.errorUnionPayload();
2503 if (err_ty.errorSetIsEmpty()) {
2504 return error_union_mcv;
2505 }
2506 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2507 return MCValue.none;
2508 }
2509
2510 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));
2511 switch (error_union_mcv) {
2512 .register => return self.fail("TODO errUnionPayload for registers", .{}),
2513 .stack_offset => |off| {
2514 return MCValue{ .stack_offset = off - payload_offset };
2515 },
2516 .memory => |addr| {
2517 return MCValue{ .memory = addr + payload_offset };
2518 },
2519 else => unreachable, // invalid MCValue for an error union
2520 }
2521}
2522
24782523fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
24792524 @setCold(true);
24802525 assert(self.err_msg == null);