| ... | @@ -1152,6 +1152,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1152,6 +1152,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1152 | .block => self.airBlock(inst), | 1152 | .block => self.airBlock(inst), |
| 1153 | .breakpoint => self.airBreakpoint(inst), | 1153 | .breakpoint => self.airBreakpoint(inst), |
| 1154 | .br => self.airBr(inst), | 1154 | .br => self.airBr(inst), |
| | 1155 | .bool_to_int => self.airBoolToInt(inst), |
| 1155 | .call => self.airCall(inst), | 1156 | .call => self.airCall(inst), |
| 1156 | .cond_br => self.airCondBr(inst), | 1157 | .cond_br => self.airCondBr(inst), |
| 1157 | .constant => unreachable, | 1158 | .constant => unreachable, |
| ... | @@ -1277,6 +1278,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -1277,6 +1278,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 1277 | const arg_val = self.resolveInst(arg_ref); | 1278 | const arg_val = self.resolveInst(arg_ref); |
| 1278 | | 1279 | |
| 1279 | const arg_ty = self.air.typeOf(arg_ref); | 1280 | const arg_ty = self.air.typeOf(arg_ref); |
| | 1281 | if (!arg_ty.hasCodeGenBits()) continue; |
| 1280 | switch (arg_ty.zigTypeTag()) { | 1282 | switch (arg_ty.zigTypeTag()) { |
| 1281 | .Struct, .Pointer, .Optional, .ErrorUnion => { | 1283 | .Struct, .Pointer, .Optional, .ErrorUnion => { |
| 1282 | // single pointer can be passed directly | 1284 | // single pointer can be passed directly |
| ... | @@ -1396,6 +1398,11 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro | ... | @@ -1396,6 +1398,11 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro |
| 1396 | return try self.store(lhs, tag_local, tag_ty, 0); | 1398 | return try self.store(lhs, tag_local, tag_ty, 0); |
| 1397 | }, | 1399 | }, |
| 1398 | .local_with_offset => |with_offset| { | 1400 | .local_with_offset => |with_offset| { |
| | 1401 | // check if we're storing the payload, or the error |
| | 1402 | if (with_offset.offset == 0) { |
| | 1403 | try self.store(lhs, .{ .local = with_offset.local }, tag_ty, 0); |
| | 1404 | return; |
| | 1405 | } |
| 1399 | const tag_local = try self.allocLocal(tag_ty); | 1406 | const tag_local = try self.allocLocal(tag_ty); |
| 1400 | try self.addImm32(0); | 1407 | try self.addImm32(0); |
| 1401 | try self.addLabel(.local_set, tag_local.local); | 1408 | try self.addLabel(.local_set, tag_local.local); |
| ... | @@ -1449,7 +1456,7 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro | ... | @@ -1449,7 +1456,7 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro |
| 1449 | // that is portable across the backend, rather than copying logic. | 1456 | // that is portable across the backend, rather than copying logic. |
| 1450 | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) | 1457 | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) |
| 1451 | @intCast(u8, ty.abiSize(self.target)) | 1458 | @intCast(u8, ty.abiSize(self.target)) |
| 1452 | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum) | 1459 | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum or ty.zigTypeTag() == .Bool) |
| 1453 | @intCast(u8, ty.abiSize(self.target)) | 1460 | @intCast(u8, ty.abiSize(self.target)) |
| 1454 | else | 1461 | else |
| 1455 | @as(u8, 4); | 1462 | @as(u8, 4); |
| ... | @@ -1499,7 +1506,7 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { | ... | @@ -1499,7 +1506,7 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { |
| 1499 | // that is portable across the backend, rather than copying logic. | 1506 | // that is portable across the backend, rather than copying logic. |
| 1500 | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) | 1507 | const abi_size = if ((ty.isInt() or ty.isAnyFloat()) and ty.abiSize(self.target) <= 8) |
| 1501 | @intCast(u8, ty.abiSize(self.target)) | 1508 | @intCast(u8, ty.abiSize(self.target)) |
| 1502 | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum) | 1509 | else if (ty.zigTypeTag() == .ErrorSet or ty.zigTypeTag() == .Enum or ty.zigTypeTag() == .Bool) |
| 1503 | @intCast(u8, ty.abiSize(self.target)) | 1510 | @intCast(u8, ty.abiSize(self.target)) |
| 1504 | else | 1511 | else |
| 1505 | @as(u8, 4); | 1512 | @as(u8, 4); |
| ... | @@ -2168,6 +2175,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W | ... | @@ -2168,6 +2175,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W |
| 2168 | } | 2175 | } |
| 2169 | | 2176 | |
| 2170 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 2177 | fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| | 2178 | if (self.liveness.isUnused(inst)) return WValue.none; |
| 2171 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2179 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2172 | const operand = self.resolveInst(ty_op.operand); | 2180 | const operand = self.resolveInst(ty_op.operand); |
| 2173 | const err_ty = self.air.typeOf(ty_op.operand); | 2181 | const err_ty = self.air.typeOf(ty_op.operand); |
| ... | @@ -2205,7 +2213,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -2205,7 +2213,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2205 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 2213 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2206 | if (self.liveness.isUnused(inst)) return WValue.none; | 2214 | if (self.liveness.isUnused(inst)) return WValue.none; |
| 2207 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2215 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2208 | return self.resolveInst(ty_op.operand); | 2216 | const operand = self.resolveInst(ty_op.operand); |
| | 2217 | return WValue{ .local_with_offset = .{ |
| | 2218 | .local = operand.local, |
| | 2219 | .offset = 0, |
| | 2220 | } }; |
| 2209 | } | 2221 | } |
| 2210 | | 2222 | |
| 2211 | fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | 2223 | fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| ... | @@ -2407,3 +2419,8 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -2407,3 +2419,8 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 2407 | try self.addLabel(.local_set, result.local); | 2419 | try self.addLabel(.local_set, result.local); |
| 2408 | return result; | 2420 | return result; |
| 2409 | } | 2421 | } |
| | 2422 | |
| | 2423 | fn airBoolToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| | 2424 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| | 2425 | return self.resolveInst(un_op); |
| | 2426 | } |