| ... | @@ -591,7 +591,7 @@ pub const Context = struct { | ... | @@ -591,7 +591,7 @@ pub const Context = struct { |
| 591 | .ErrorSet, | 591 | .ErrorSet, |
| 592 | => wasm.Valtype.i32, | 592 | => wasm.Valtype.i32, |
| 593 | .Struct, .ErrorUnion => unreachable, // Multi typed, must be handled individually. | 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,8 +800,11 @@ pub const Context = struct { |
| 800 | const air_tags = self.air.instructions.items(.tag); | 800 | const air_tags = self.air.instructions.items(.tag); |
| 801 | return switch (air_tags[inst]) { | 801 | return switch (air_tags[inst]) { |
| 802 | .add => self.airBinOp(inst, .add), | 802 | .add => self.airBinOp(inst, .add), |
| | 803 | .addwrap => self.airBinOp(inst, .add), |
| 803 | .sub => self.airBinOp(inst, .sub), | 804 | .sub => self.airBinOp(inst, .sub), |
| | 805 | .subwrap => self.airBinOp(inst, .sub), |
| 804 | .mul => self.airBinOp(inst, .mul), | 806 | .mul => self.airBinOp(inst, .mul), |
| | 807 | .mulwrap => self.airBinOp(inst, .mul), |
| 805 | .div => self.airBinOp(inst, .div), | 808 | .div => self.airBinOp(inst, .div), |
| 806 | .bit_and => self.airBinOp(inst, .@"and"), | 809 | .bit_and => self.airBinOp(inst, .@"and"), |
| 807 | .bit_or => self.airBinOp(inst, .@"or"), | 810 | .bit_or => self.airBinOp(inst, .@"or"), |
| ... | @@ -826,6 +829,7 @@ pub const Context = struct { | ... | @@ -826,6 +829,7 @@ pub const Context = struct { |
| 826 | .cond_br => self.airCondBr(inst), | 829 | .cond_br => self.airCondBr(inst), |
| 827 | .constant => unreachable, | 830 | .constant => unreachable, |
| 828 | .dbg_stmt => WValue.none, | 831 | .dbg_stmt => WValue.none, |
| | 832 | .intcast => self.airIntcast(inst), |
| 829 | .is_err => self.airIsErr(inst, .i32_ne), | 833 | .is_err => self.airIsErr(inst, .i32_ne), |
| 830 | .is_non_err => self.airIsErr(inst, .i32_eq), | 834 | .is_non_err => self.airIsErr(inst, .i32_eq), |
| 831 | .load => self.airLoad(inst), | 835 | .load => self.airLoad(inst), |
| ... | @@ -1494,4 +1498,27 @@ pub const Context = struct { | ... | @@ -1494,4 +1498,27 @@ pub const Context = struct { |
| 1494 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1498 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1495 | return self.resolveInst(ty_op.operand); | 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 | }; |