| ... | @@ -1148,6 +1148,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1148,6 +1148,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1148 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), | 1148 | .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), |
| 1149 | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), | 1149 | .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), |
| 1150 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), | 1150 | .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), |
| | 1151 | .wrap_errunion_err => self.airWrapErrUnionErr(inst), |
| 1151 | | 1152 | |
| 1152 | .optional_payload => self.airOptionalPayload(inst), | 1153 | .optional_payload => self.airOptionalPayload(inst), |
| 1153 | .optional_payload_ptr => self.airOptionalPayload(inst), | 1154 | .optional_payload_ptr => self.airOptionalPayload(inst), |
| ... | @@ -1328,16 +1329,15 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro | ... | @@ -1328,16 +1329,15 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro |
| 1328 | return; | 1329 | return; |
| 1329 | }, | 1330 | }, |
| 1330 | .local => { | 1331 | .local => { |
| 1331 | // Load values from `rhs` stack position and store in `lhs` instead | 1332 | if (payload_ty.hasCodeGenBits()) { |
| 1332 | const tag_local = try self.load(rhs, tag_ty, 0); | 1333 | try self.store(lhs, rhs, payload_ty, payload_offset); |
| 1333 | const payload_local = try self.load(rhs, payload_ty, payload_offset); | 1334 | } |
| 1334 | | 1335 | return try self.store(lhs, rhs, tag_ty, 0); |
| 1335 | try self.store(lhs, tag_local, tag_ty, 0); | | |
| 1336 | return try self.store(lhs, payload_local, payload_ty, payload_offset); | | |
| 1337 | }, | 1336 | }, |
| 1338 | .local_with_offset => |with_offset| { | 1337 | .local_with_offset => |with_offset| { |
| 1339 | const tag_local = try self.allocLocal(tag_ty); | 1338 | const tag_local = try self.allocLocal(tag_ty); |
| 1340 | try self.addImm32(0); | 1339 | try self.addImm32(0); |
| | 1340 | try self.addLabel(.local_set, tag_local.local); |
| 1341 | try self.store(lhs, tag_local, tag_ty, 0); | 1341 | try self.store(lhs, tag_local, tag_ty, 0); |
| 1342 | | 1342 | |
| 1343 | return try self.store( | 1343 | return try self.store( |
| ... | @@ -1415,7 +1415,10 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { | ... | @@ -1415,7 +1415,10 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 1415 | // load local's value from memory by its stack position | 1415 | // load local's value from memory by its stack position |
| 1416 | try self.emitWValue(operand); | 1416 | try self.emitWValue(operand); |
| 1417 | // Build the opcode with the right bitsize | 1417 | // Build the opcode with the right bitsize |
| 1418 | const signedness: std.builtin.Signedness = if (ty.isUnsignedInt()) .unsigned else .signed; | 1418 | const signedness: std.builtin.Signedness = if (ty.isUnsignedInt() or ty.zigTypeTag() == .ErrorSet) |
| | 1419 | .unsigned |
| | 1420 | else |
| | 1421 | .signed; |
| 1419 | // check if we should pass by pointer or value based on ABI size | 1422 | // check if we should pass by pointer or value based on ABI size |
| 1420 | // TODO: Implement a way to get ABI values from a given type, | 1423 | // TODO: Implement a way to get ABI values from a given type, |
| 1421 | // that is portable across the backend, rather than copying logic. | 1424 | // that is portable across the backend, rather than copying logic. |
| ... | @@ -2081,9 +2084,25 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -2081,9 +2084,25 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2081 | } | 2084 | } |
| 2082 | | 2085 | |
| 2083 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 2086 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| | 2087 | if (self.liveness.isUnused(inst)) return WValue.none; |
| | 2088 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 2089 | const operand = self.resolveInst(ty_op.operand); |
| | 2090 | |
| | 2091 | const op_ty = self.air.typeOf(ty_op.operand); |
| | 2092 | if (!op_ty.hasCodeGenBits()) return WValue.none; |
| | 2093 | const err_ty = self.air.getRefType(ty_op.ty); |
| | 2094 | const offset = err_ty.errorUnionSet().abiSize(self.target); |
| | 2095 | |
| | 2096 | return WValue{ .local_with_offset = .{ |
| | 2097 | .local = operand.local, |
| | 2098 | .offset = @intCast(u32, offset), |
| | 2099 | } }; |
| | 2100 | } |
| | 2101 | |
| | 2102 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| | 2103 | if (self.liveness.isUnused(inst)) return WValue.none; |
| 2084 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2104 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2085 | _ = ty_op; | 2105 | return self.resolveInst(ty_op.operand); |
| 2086 | return self.fail("TODO: wasm airWrapErrUnionPayload", .{}); | | |
| 2087 | } | 2106 | } |
| 2088 | | 2107 | |
| 2089 | fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 2108 | fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |