+ case SpvOpIsInf: {
+ nir_ssa_def *inf = nir_imm_floatN_t(&b->nb, INFINITY, src[0]->bit_size);
+ dest->def = nir_ieq(&b->nb, nir_fabs(&b->nb, src[0]), inf);
+ break;
+ }
+
+ case SpvOpFUnordEqual:
+ case SpvOpFUnordNotEqual:
+ case SpvOpFUnordLessThan:
+ case SpvOpFUnordGreaterThan:
+ case SpvOpFUnordLessThanEqual:
+ case SpvOpFUnordGreaterThanEqual: {
+ bool swap;
+ unsigned src_bit_size = glsl_get_bit_size(vtn_src[0]->type);
+ unsigned dst_bit_size = glsl_get_bit_size(dest_type);
+ nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap,
+ src_bit_size, dst_bit_size);
+
+ if (swap) {
+ nir_ssa_def *tmp = src[0];
+ src[0] = src[1];
+ src[1] = tmp;
+ }
+
+ dest->def =
+ nir_ior(&b->nb,
+ nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
+ nir_ior(&b->nb,
+ nir_fneu(&b->nb, src[0], src[0]),
+ nir_fneu(&b->nb, src[1], src[1])));
+ break;
+ }
+
+ case SpvOpLessOrGreater:
+ case SpvOpFOrdNotEqual: {
+ /* For all the SpvOpFOrd* comparisons apart from NotEqual, the value
+ * from the ALU will probably already be false if the operands are not
+ * ordered so we don’t need to handle it specially.
+ */
+ bool swap;
+ unsigned src_bit_size = glsl_get_bit_size(vtn_src[0]->type);
+ unsigned dst_bit_size = glsl_get_bit_size(dest_type);
+ nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap,
+ src_bit_size, dst_bit_size);
+
+ assert(!swap);
+
+ dest->def =
+ nir_iand(&b->nb,
+ nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
+ nir_iand(&b->nb,
+ nir_feq(&b->nb, src[0], src[0]),
+ nir_feq(&b->nb, src[1], src[1])));
+ break;
+ }
+
+ case SpvOpFConvert: {
+ nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
+ nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(dest_type);
+ nir_rounding_mode rounding_mode = nir_rounding_mode_undef;
+
+ vtn_foreach_decoration(b, dest_val, handle_rounding_mode, &rounding_mode);
+ nir_op op = nir_type_conversion_op(src_alu_type, dst_alu_type, rounding_mode);
+
+ dest->def = nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL);
+ break;
+ }
+
+ case SpvOpBitFieldInsert:
+ case SpvOpBitFieldSExtract:
+ case SpvOpBitFieldUExtract:
+ case SpvOpShiftLeftLogical:
+ case SpvOpShiftRightArithmetic:
+ case SpvOpShiftRightLogical: {
+ bool swap;
+ unsigned src0_bit_size = glsl_get_bit_size(vtn_src[0]->type);
+ unsigned dst_bit_size = glsl_get_bit_size(dest_type);
+ nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap,
+ src0_bit_size, dst_bit_size);
+
+ assert (op == nir_op_ushr || op == nir_op_ishr || op == nir_op_ishl ||
+ op == nir_op_bitfield_insert || op == nir_op_ubitfield_extract ||
+ op == nir_op_ibitfield_extract);
+
+ for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) {
+ unsigned src_bit_size =
+ nir_alu_type_get_type_size(nir_op_infos[op].input_types[i]);
+ if (src_bit_size == 0)
+ continue;
+ if (src_bit_size != src[i]->bit_size) {
+ assert(src_bit_size == 32);
+ /* Convert the Shift, Offset and Count operands to 32 bits, which is the bitsize
+ * supported by the NIR instructions. See discussion here:
+ *
+ * https://lists.freedesktop.org/archives/mesa-dev/2018-April/193026.html
+ */
+ src[i] = nir_u2u32(&b->nb, src[i]);
+ }
+ }
+ dest->def = nir_build_alu(&b->nb, op, src[0], src[1], src[2], src[3]);
+ break;
+ }
+
+ case SpvOpSignBitSet:
+ dest->def = nir_i2b(&b->nb,
+ nir_ushr(&b->nb, src[0], nir_imm_int(&b->nb, src[0]->bit_size - 1)));
+ break;
+
+ case SpvOpUCountTrailingZerosINTEL:
+ dest->def = nir_umin(&b->nb,
+ nir_find_lsb(&b->nb, src[0]),
+ nir_imm_int(&b->nb, 32u));
+ break;
+
+ case SpvOpBitCount: {
+ /* bit_count always returns int32, but the SPIR-V opcode just says the return
+ * value needs to be big enough to store the number of bits.
+ */
+ dest->def = nir_u2u(&b->nb, nir_bit_count(&b->nb, src[0]), glsl_get_bit_size(dest_type));
+ break;
+ }
+