| ... | @@ -994,10 +994,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -994,10 +994,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 994 | .optional_payload => try self.airOptionalPayload(inst), | 994 | .optional_payload => try self.airOptionalPayload(inst), |
| 995 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), | 995 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), |
| 996 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), | 996 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), |
| 997 | .unwrap_errunion_err => try self.airUnwrapErrErr(inst), | 997 | .unwrap_errunion_err => try self.airUnwrapErrUnionErr(inst), |
| 998 | .unwrap_errunion_payload => try self.airUnwrapErrPayload(inst), | 998 | .unwrap_errunion_payload => try self.airUnwrapErrUnionPayload(inst), |
| 999 | .unwrap_errunion_err_ptr => try self.airUnwrapErrErrPtr(inst), | 999 | .unwrap_errunion_err_ptr => try self.airUnwrapErrUnionErrPtr(inst), |
| 1000 | .unwrap_errunion_payload_ptr=> try self.airUnwrapErrPayloadPtr(inst), | 1000 | .unwrap_errunion_payload_ptr=> try self.airUnwrapErrUnionPayloadPtr(inst), |
| 1001 | .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst), | 1001 | .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst), |
| 1002 | .err_return_trace => try self.airErrReturnTrace(inst), | 1002 | .err_return_trace => try self.airErrReturnTrace(inst), |
| 1003 | .set_err_return_trace => try self.airSetErrReturnTrace(inst), | 1003 | .set_err_return_trace => try self.airSetErrReturnTrace(inst), |
| ... | @@ -1923,7 +1923,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1923,7 +1923,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 1923 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1923 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1924 | } | 1924 | } |
| 1925 | | 1925 | |
| 1926 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | 1926 | fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1927 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1927 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1928 | if (self.liveness.isUnused(inst)) { | 1928 | if (self.liveness.isUnused(inst)) { |
| 1929 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); | 1929 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| ... | @@ -1967,7 +1967,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1967,7 +1967,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1967 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1967 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1968 | } | 1968 | } |
| 1969 | | 1969 | |
| 1970 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { | 1970 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 1971 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1971 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1972 | if (self.liveness.isUnused(inst)) { | 1972 | if (self.liveness.isUnused(inst)) { |
| 1973 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); | 1973 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| ... | @@ -2021,31 +2021,112 @@ fn genUnwrapErrorUnionPayloadMir( | ... | @@ -2021,31 +2021,112 @@ fn genUnwrapErrorUnionPayloadMir( |
| 2021 | } | 2021 | } |
| 2022 | | 2022 | |
| 2023 | // *(E!T) -> E | 2023 | // *(E!T) -> E |
| 2024 | fn airUnwrapErrErrPtr(self: *Self, inst: Air.Inst.Index) !void { | 2024 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2025 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2025 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2026 | const result: MCValue = if (self.liveness.isUnused(inst)) | 2026 | const result: MCValue = result: { |
| 2027 | .dead | 2027 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2028 | else | 2028 | |
| 2029 | return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch}); | 2029 | const src_ty = self.air.typeOf(ty_op.operand); |
| | 2030 | const src_mcv = try self.resolveInst(ty_op.operand); |
| | 2031 | const src_reg = switch (src_mcv) { |
| | 2032 | .register => |reg| reg, |
| | 2033 | else => try self.copyToTmpRegister(src_ty, src_mcv), |
| | 2034 | }; |
| | 2035 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| | 2036 | defer self.register_manager.unlockReg(src_lock); |
| | 2037 | |
| | 2038 | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| | 2039 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| | 2040 | defer self.register_manager.unlockReg(dst_lock); |
| | 2041 | |
| | 2042 | const eu_ty = src_ty.childType(); |
| | 2043 | const pl_ty = eu_ty.errorUnionPayload(); |
| | 2044 | const err_ty = eu_ty.errorUnionSet(); |
| | 2045 | const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); |
| | 2046 | const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*)); |
| | 2047 | try self.asmRegisterMemory( |
| | 2048 | .mov, |
| | 2049 | registerAlias(dst_reg, err_abi_size), |
| | 2050 | Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ .base = src_reg, .disp = err_off }), |
| | 2051 | ); |
| | 2052 | break :result .{ .register = dst_reg }; |
| | 2053 | }; |
| 2030 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2054 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2031 | } | 2055 | } |
| 2032 | | 2056 | |
| 2033 | // *(E!T) -> *T | 2057 | // *(E!T) -> *T |
| 2034 | fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { | 2058 | fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2035 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2059 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2036 | const result: MCValue = if (self.liveness.isUnused(inst)) | 2060 | const result: MCValue = result: { |
| 2037 | .dead | 2061 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2038 | else | 2062 | |
| 2039 | return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch}); | 2063 | const src_ty = self.air.typeOf(ty_op.operand); |
| | 2064 | const src_mcv = try self.resolveInst(ty_op.operand); |
| | 2065 | const src_reg = switch (src_mcv) { |
| | 2066 | .register => |reg| reg, |
| | 2067 | else => try self.copyToTmpRegister(src_ty, src_mcv), |
| | 2068 | }; |
| | 2069 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| | 2070 | defer self.register_manager.unlockReg(src_lock); |
| | 2071 | |
| | 2072 | const dst_ty = self.air.typeOfIndex(inst); |
| | 2073 | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| | 2074 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| | 2075 | defer self.register_manager.unlockReg(dst_lock); |
| | 2076 | |
| | 2077 | const eu_ty = src_ty.childType(); |
| | 2078 | const pl_ty = eu_ty.errorUnionPayload(); |
| | 2079 | const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*)); |
| | 2080 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| | 2081 | try self.asmRegisterMemory( |
| | 2082 | .lea, |
| | 2083 | registerAlias(dst_reg, dst_abi_size), |
| | 2084 | Memory.sib(.qword, .{ .base = src_reg, .disp = pl_off }), |
| | 2085 | ); |
| | 2086 | break :result .{ .register = dst_reg }; |
| | 2087 | }; |
| 2040 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2088 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2041 | } | 2089 | } |
| 2042 | | 2090 | |
| 2043 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | 2091 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 2044 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2092 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2045 | const result: MCValue = if (self.liveness.isUnused(inst)) | 2093 | const result: MCValue = result: { |
| 2046 | .dead | 2094 | const src_ty = self.air.typeOf(ty_op.operand); |
| 2047 | else | 2095 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 2048 | return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch}); | 2096 | const src_reg = switch (src_mcv) { |
| | 2097 | .register => |reg| reg, |
| | 2098 | else => try self.copyToTmpRegister(src_ty, src_mcv), |
| | 2099 | }; |
| | 2100 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| | 2101 | defer self.register_manager.unlockReg(src_lock); |
| | 2102 | |
| | 2103 | const eu_ty = src_ty.childType(); |
| | 2104 | const pl_ty = eu_ty.errorUnionPayload(); |
| | 2105 | const err_ty = eu_ty.errorUnionSet(); |
| | 2106 | const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); |
| | 2107 | const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*)); |
| | 2108 | try self.asmMemoryImmediate( |
| | 2109 | .mov, |
| | 2110 | Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{ .base = src_reg, .disp = err_off }), |
| | 2111 | Immediate.u(0), |
| | 2112 | ); |
| | 2113 | |
| | 2114 | if (self.liveness.isUnused(inst)) break :result .dead; |
| | 2115 | |
| | 2116 | const dst_ty = self.air.typeOfIndex(inst); |
| | 2117 | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| | 2118 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| | 2119 | defer self.register_manager.unlockReg(dst_lock); |
| | 2120 | |
| | 2121 | const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); |
| | 2122 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| | 2123 | try self.asmRegisterMemory( |
| | 2124 | .lea, |
| | 2125 | registerAlias(dst_reg, dst_abi_size), |
| | 2126 | Memory.sib(.qword, .{ .base = src_reg, .disp = pl_off }), |
| | 2127 | ); |
| | 2128 | break :result .{ .register = dst_reg }; |
| | 2129 | }; |
| 2049 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2130 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2050 | } | 2131 | } |
| 2051 | | 2132 | |