| ... | ... | @@ -850,6 +850,8 @@ pub const DeclGen = struct { |
| 850 | 850 | .bool_and => try self.airBinOpSimple(inst, .OpLogicalAnd), |
| 851 | 851 | .bool_or => try self.airBinOpSimple(inst, .OpLogicalOr), |
| 852 | 852 | |
| 853 | .shl => try self.airShift(inst, .OpShiftLeftLogical), |
| 854 | |
| 853 | 855 | .bitcast => try self.airBitcast(inst), |
| 854 | 856 | .intcast => try self.airIntcast(inst), |
| 855 | 857 | .not => try self.airNot(inst), |
| ... | ... | @@ -928,6 +930,31 @@ pub const DeclGen = struct { |
| 928 | 930 | return result_id.toRef(); |
| 929 | 931 | } |
| 930 | 932 | |
| 933 | fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef { |
| 934 | if (self.liveness.isUnused(inst)) return null; |
| 935 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 936 | const lhs_id = try self.resolve(bin_op.lhs); |
| 937 | const rhs_id = try self.resolve(bin_op.rhs); |
| 938 | const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst)); |
| 939 | |
| 940 | // the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int. |
| 941 | const shift_id = self.spv.allocId(); |
| 942 | try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ |
| 943 | .id_result_type = result_type_id, |
| 944 | .id_result = shift_id, |
| 945 | .unsigned_value = rhs_id, |
| 946 | }); |
| 947 | |
| 948 | const result_id = self.spv.allocId(); |
| 949 | try self.func.body.emit(self.spv.gpa, opcode, .{ |
| 950 | .id_result_type = result_type_id, |
| 951 | .id_result = result_id, |
| 952 | .base = lhs_id, |
| 953 | .shift = shift_id.toRef(), |
| 954 | }); |
| 955 | return result_id.toRef(); |
| 956 | } |
| 957 | |
| 931 | 958 | fn maskStrangeInt(self: *DeclGen, ty_id: IdResultType, int_id: IdRef, bits: u16) !IdRef { |
| 932 | 959 | const backing_bits = self.backingIntBits(bits).?; |
| 933 | 960 | const mask_value = if (bits == 64) 0xFFFF_FFFF_FFFF_FFFF else (@as(u64, 1) << @intCast(u6, bits)) - 1; |