| ... | ... | @@ -591,7 +591,7 @@ pub const Context = struct { |
| 591 | 591 | .ErrorSet, |
| 592 | 592 | => wasm.Valtype.i32, |
| 593 | 593 | .Struct, .ErrorUnion => unreachable, // Multi typed, must be handled individually. |
| 594 | | else => self.fail("TODO - Wasm valtype for type '{s}'", .{ty.zigTypeTag()}), |
| 594 | else => |tag| self.fail("TODO - Wasm valtype for type '{s}'", .{tag}), |
| 595 | 595 | }; |
| 596 | 596 | } |
| 597 | 597 | |
| ... | ... | @@ -800,8 +800,11 @@ pub const Context = struct { |
| 800 | 800 | const air_tags = self.air.instructions.items(.tag); |
| 801 | 801 | return switch (air_tags[inst]) { |
| 802 | 802 | .add => self.airBinOp(inst, .add), |
| 803 | .addwrap => self.airBinOp(inst, .add), |
| 803 | 804 | .sub => self.airBinOp(inst, .sub), |
| 805 | .subwrap => self.airBinOp(inst, .sub), |
| 804 | 806 | .mul => self.airBinOp(inst, .mul), |
| 807 | .mulwrap => self.airBinOp(inst, .mul), |
| 805 | 808 | .div => self.airBinOp(inst, .div), |
| 806 | 809 | .bit_and => self.airBinOp(inst, .@"and"), |
| 807 | 810 | .bit_or => self.airBinOp(inst, .@"or"), |
| ... | ... | @@ -826,6 +829,7 @@ pub const Context = struct { |
| 826 | 829 | .cond_br => self.airCondBr(inst), |
| 827 | 830 | .constant => unreachable, |
| 828 | 831 | .dbg_stmt => WValue.none, |
| 832 | .intcast => self.airIntcast(inst), |
| 829 | 833 | .is_err => self.airIsErr(inst, .i32_ne), |
| 830 | 834 | .is_non_err => self.airIsErr(inst, .i32_eq), |
| 831 | 835 | .load => self.airLoad(inst), |
| ... | ... | @@ -1494,4 +1498,27 @@ pub const Context = struct { |
| 1494 | 1498 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1495 | 1499 | return self.resolveInst(ty_op.operand); |
| 1496 | 1500 | } |
| 1501 | |
| 1502 | fn airIntcast(self: *Context, inst: Air.Inst.Index) InnerError!WValue { |
| 1503 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1504 | const ty = self.air.getRefType(ty_op.ty); |
| 1505 | const operand = self.resolveInst(ty_op.operand); |
| 1506 | const ref_ty = self.air.typeOf(ty_op.operand); |
| 1507 | const ref_info = ref_ty.intInfo(self.target); |
| 1508 | const op_bits = ref_info.bits; |
| 1509 | const wanted_bits = ty.intInfo(self.target).bits; |
| 1510 | |
| 1511 | try self.emitWValue(operand); |
| 1512 | if (op_bits > 32 and wanted_bits <= 32) { |
| 1513 | try self.code.append(wasm.opcode(.i32_wrap_i64)); |
| 1514 | } else if (op_bits <= 32 and wanted_bits > 32) { |
| 1515 | try self.code.append(wasm.opcode(switch (ref_info.signedness) { |
| 1516 | .signed => .i64_extend_i32_s, |
| 1517 | .unsigned => .i64_extend_i32_u, |
| 1518 | })); |
| 1519 | } |
| 1520 | |
| 1521 | // other cases are no-op |
| 1522 | return .none; |
| 1523 | } |
| 1497 | 1524 | }; |