From 205d928b24d46fd1fd5798c5d66e66ef25aa013f Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sun, 27 Nov 2022 15:04:16 +0100 Subject: [PATCH] spirv: left shift Implements the AIR left_shift operation for the SPIR-V backend. --- src/codegen/spirv.zig | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 47848d70c5..bfd2c2da30 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -850,6 +850,8 @@ pub const DeclGen = struct { .bool_and => try self.airBinOpSimple(inst, .OpLogicalAnd), .bool_or => try self.airBinOpSimple(inst, .OpLogicalOr), + .shl => try self.airShift(inst, .OpShiftLeftLogical), + .bitcast => try self.airBitcast(inst), .intcast => try self.airIntcast(inst), .not => try self.airNot(inst), @@ -928,6 +930,31 @@ pub const DeclGen = struct { return result_id.toRef(); } + fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const lhs_id = try self.resolve(bin_op.lhs); + const rhs_id = try self.resolve(bin_op.rhs); + const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst)); + + // the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int. + const shift_id = self.spv.allocId(); + try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ + .id_result_type = result_type_id, + .id_result = shift_id, + .unsigned_value = rhs_id, + }); + + const result_id = self.spv.allocId(); + try self.func.body.emit(self.spv.gpa, opcode, .{ + .id_result_type = result_type_id, + .id_result = result_id, + .base = lhs_id, + .shift = shift_id.toRef(), + }); + return result_id.toRef(); + } + fn maskStrangeInt(self: *DeclGen, ty_id: IdResultType, int_id: IdRef, bits: u16) !IdRef { const backing_bits = self.backingIntBits(bits).?; const mask_value = if (bits == 64) 0xFFFF_FFFF_FFFF_FFFF else (@as(u64, 1) << @intCast(u6, bits)) - 1;