| ... | ... | @@ -535,6 +535,7 @@ const DeclGen = struct { |
| 535 | 535 | .composite_integer, |
| 536 | 536 | }; |
| 537 | 537 | }, |
| 538 | .Enum => return self.arithmeticTypeInfo(ty.intTagType(mod)), |
| 538 | 539 | // As of yet, there is no vector support in the self-hosted compiler. |
| 539 | 540 | .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), |
| 540 | 541 | // TODO: For which types is this the case? |
| ... | ... | @@ -2168,6 +2169,7 @@ const DeclGen = struct { |
| 2168 | 2169 | /// non-zeros. |
| 2169 | 2170 | /// For signed integers, the value is also sign extended. |
| 2170 | 2171 | fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef { |
| 2172 | assert(info.class != .composite_integer); // TODO |
| 2171 | 2173 | if (info.bits == info.backing_bits) { |
| 2172 | 2174 | return value_id; |
| 2173 | 2175 | } |
| ... | ... | @@ -2731,25 +2733,33 @@ const DeclGen = struct { |
| 2731 | 2733 | |
| 2732 | 2734 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2733 | 2735 | const operand_id = try self.resolve(ty_op.operand); |
| 2734 | | const dest_ty = self.typeOfIndex(inst); |
| 2735 | | const dest_ty_id = try self.resolveTypeId(dest_ty); |
| 2736 | const src_ty = self.typeOf(ty_op.operand); |
| 2737 | const dst_ty = self.typeOfIndex(inst); |
| 2738 | const src_ty_ref = try self.resolveType(src_ty, .direct); |
| 2739 | const dst_ty_ref = try self.resolveType(dst_ty, .direct); |
| 2736 | 2740 | |
| 2737 | | const mod = self.module; |
| 2738 | | const dest_info = dest_ty.intInfo(mod); |
| 2741 | const src_info = try self.arithmeticTypeInfo(src_ty); |
| 2742 | const dst_info = try self.arithmeticTypeInfo(dst_ty); |
| 2743 | |
| 2744 | // While intcast promises that the value already fits, the upper bits of a |
| 2745 | // strange integer may contain garbage. Therefore, mask/sign extend it before. |
| 2746 | const src_id = try self.normalizeInt(src_ty_ref, operand_id, src_info); |
| 2739 | 2747 | |
| 2740 | | // TODO: Masking? |
| 2748 | if (src_info.backing_bits == dst_info.backing_bits) { |
| 2749 | return src_id; |
| 2750 | } |
| 2741 | 2751 | |
| 2742 | 2752 | const result_id = self.spv.allocId(); |
| 2743 | | switch (dest_info.signedness) { |
| 2753 | switch (dst_info.signedness) { |
| 2744 | 2754 | .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{ |
| 2745 | | .id_result_type = dest_ty_id, |
| 2755 | .id_result_type = self.typeId(dst_ty_ref), |
| 2746 | 2756 | .id_result = result_id, |
| 2747 | | .signed_value = operand_id, |
| 2757 | .signed_value = src_id, |
| 2748 | 2758 | }), |
| 2749 | 2759 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ |
| 2750 | | .id_result_type = dest_ty_id, |
| 2760 | .id_result_type = self.typeId(dst_ty_ref), |
| 2751 | 2761 | .id_result = result_id, |
| 2752 | | .unsigned_value = operand_id, |
| 2762 | .unsigned_value = src_id, |
| 2753 | 2763 | }), |
| 2754 | 2764 | } |
| 2755 | 2765 | return result_id; |