aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-10-08 20:26:15 +0200
committerRobin Voetter <robin@voetter.nl>2023-10-15 14:00:10 +0200
commite2e4e1f8b4fa5d8394cb571d00b4b62eacea97df (patch)
treef78cb2d4732bf0a59d791bd9d667e7ab6f6eb88e /src/codegen/spirv.zig
parentb1499df1b88b0fa25c4d7e4a16cb1715db452227 (diff)
downloadzig-e2e4e1f8b4fa5d8394cb571d00b4b62eacea97df.tar.gz
zig-e2e4e1f8b4fa5d8394cb571d00b4b62eacea97df.zip
spirv: intcast, trunc for strange ints
Diffstat (limited to 'src/codegen/spirv.zig')
-rw-r--r--src/codegen/spirv.zig30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index fab69da39b..6fff39f951 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -535,6 +535,7 @@ const DeclGen = struct {
.composite_integer,
};
},
+ .Enum => return self.arithmeticTypeInfo(ty.intTagType(mod)),
// As of yet, there is no vector support in the self-hosted compiler.
.Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
// TODO: For which types is this the case?
@@ -2168,6 +2169,7 @@ const DeclGen = struct {
/// non-zeros.
/// For signed integers, the value is also sign extended.
fn normalizeInt(self: *DeclGen, ty_ref: CacheRef, value_id: IdRef, info: ArithmeticTypeInfo) !IdRef {
+ assert(info.class != .composite_integer); // TODO
if (info.bits == info.backing_bits) {
return value_id;
}
@@ -2731,25 +2733,33 @@ const DeclGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand);
- const dest_ty = self.typeOfIndex(inst);
- const dest_ty_id = try self.resolveTypeId(dest_ty);
+ const src_ty = self.typeOf(ty_op.operand);
+ const dst_ty = self.typeOfIndex(inst);
+ const src_ty_ref = try self.resolveType(src_ty, .direct);
+ const dst_ty_ref = try self.resolveType(dst_ty, .direct);
- const mod = self.module;
- const dest_info = dest_ty.intInfo(mod);
+ const src_info = try self.arithmeticTypeInfo(src_ty);
+ const dst_info = try self.arithmeticTypeInfo(dst_ty);
+
+ // While intcast promises that the value already fits, the upper bits of a
+ // strange integer may contain garbage. Therefore, mask/sign extend it before.
+ const src_id = try self.normalizeInt(src_ty_ref, operand_id, src_info);
- // TODO: Masking?
+ if (src_info.backing_bits == dst_info.backing_bits) {
+ return src_id;
+ }
const result_id = self.spv.allocId();
- switch (dest_info.signedness) {
+ switch (dst_info.signedness) {
.signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{
- .id_result_type = dest_ty_id,
+ .id_result_type = self.typeId(dst_ty_ref),
.id_result = result_id,
- .signed_value = operand_id,
+ .signed_value = src_id,
}),
.unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{
- .id_result_type = dest_ty_id,
+ .id_result_type = self.typeId(dst_ty_ref),
.id_result = result_id,
- .unsigned_value = operand_id,
+ .unsigned_value = src_id,
}),
}
return result_id;