| ... | @@ -535,6 +535,7 @@ const DeclGen = struct { | ... | @@ -535,6 +535,7 @@ const DeclGen = struct { |
| 535 | .composite_integer, | 535 | .composite_integer, |
| 536 | }; | 536 | }; |
| 537 | }, | 537 | }, |
| | 538 | .Enum => return self.arithmeticTypeInfo(ty.intTagType(mod)), |
| 538 | // As of yet, there is no vector support in the self-hosted compiler. | 539 | // As of yet, there is no vector support in the self-hosted compiler. |
| 539 | .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), | 540 | .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}), |
| 540 | // TODO: For which types is this the case? | 541 | // TODO: For which types is this the case? |
| ... | @@ -2168,6 +2169,7 @@ const DeclGen = struct { | ... | @@ -2168,6 +2169,7 @@ const DeclGen = struct { |
| 2168 | /// non-zeros. | 2169 | /// non-zeros. |
| 2169 | /// For signed integers, the value is also sign extended. | 2170 | /// For signed integers, the value is also sign extended. |
| 2170 | fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef { | 2171 | fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef { |
| | 2172 | assert(info.class != .composite_integer); // TODO |
| 2171 | if (info.bits == info.backing_bits) { | 2173 | if (info.bits == info.backing_bits) { |
| 2172 | return value_id; | 2174 | return value_id; |
| 2173 | } | 2175 | } |
| ... | @@ -2731,25 +2733,33 @@ const DeclGen = struct { | ... | @@ -2731,25 +2733,33 @@ const DeclGen = struct { |
| 2731 | | 2733 | |
| 2732 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2734 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2733 | const operand_id = try self.resolve(ty_op.operand); | 2735 | const operand_id = try self.resolve(ty_op.operand); |
| 2734 | const dest_ty = self.typeOfIndex(inst); | 2736 | const src_ty = self.typeOf(ty_op.operand); |
| 2735 | const dest_ty_id = try self.resolveTypeId(dest_ty); | 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; | 2741 | const src_info = try self.arithmeticTypeInfo(src_ty); |
| 2738 | const dest_info = dest_ty.intInfo(mod); | 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 | const result_id = self.spv.allocId(); | 2752 | const result_id = self.spv.allocId(); |
| 2743 | switch (dest_info.signedness) { | 2753 | switch (dst_info.signedness) { |
| 2744 | .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{ | 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 | .id_result = result_id, | 2756 | .id_result = result_id, |
| 2747 | .signed_value = operand_id, | 2757 | .signed_value = src_id, |
| 2748 | }), | 2758 | }), |
| 2749 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ | 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 | .id_result = result_id, | 2761 | .id_result = result_id, |
| 2752 | .unsigned_value = operand_id, | 2762 | .unsigned_value = src_id, |
| 2753 | }), | 2763 | }), |
| 2754 | } | 2764 | } |
| 2755 | return result_id; | 2765 | return result_id; |