case SpvOpBitReverse: return nir_op_bitfield_reverse;
case SpvOpBitCount: return nir_op_bit_count;
+ case SpvOpUCountLeadingZerosINTEL: return nir_op_uclz;
+ /* SpvOpUCountTrailingZerosINTEL is handled elsewhere. */
+ case SpvOpAbsISubINTEL: return nir_op_uabs_isub;
+ case SpvOpAbsUSubINTEL: return nir_op_uabs_usub;
+ case SpvOpIAddSatINTEL: return nir_op_iadd_sat;
+ case SpvOpUAddSatINTEL: return nir_op_uadd_sat;
+ case SpvOpIAverageINTEL: return nir_op_ihadd;
+ case SpvOpUAverageINTEL: return nir_op_uhadd;
+ case SpvOpIAverageRoundedINTEL: return nir_op_irhadd;
+ case SpvOpUAverageRoundedINTEL: return nir_op_urhadd;
+ case SpvOpISubSatINTEL: return nir_op_isub_sat;
+ case SpvOpUSubSatINTEL: return nir_op_usub_sat;
+ case SpvOpIMul32x16INTEL: return nir_op_imul_32x16;
+ case SpvOpUMul32x16INTEL: return nir_op_umul_32x16;
+
/* The ordered / unordered operators need special implementation besides
* the logical operator to use since they also need to check if operands are
* ordered.
assert(dec->scope == VTN_DEC_DECORATION);
if (dec->decoration != SpvDecorationFPRoundingMode)
return;
- switch (dec->literals[0]) {
+ switch (dec->operands[0]) {
case SpvFPRoundingModeRTE:
*out_rounding_mode = nir_rounding_mode_rtne;
break;
}
}
+static void
+handle_no_wrap(struct vtn_builder *b, struct vtn_value *val, int member,
+ const struct vtn_decoration *dec, void *_alu)
+{
+ nir_alu_instr *alu = _alu;
+ switch (dec->decoration) {
+ case SpvDecorationNoSignedWrap:
+ alu->no_signed_wrap = true;
+ break;
+ case SpvDecorationNoUnsignedWrap:
+ alu->no_unsigned_wrap = true;
+ break;
+ default:
+ /* Do nothing. */
+ break;
+ }
+}
+
void
vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count)
switch (opcode) {
case SpvOpAny:
if (src[0]->num_components == 1) {
- val->ssa->def = nir_imov(&b->nb, src[0]);
+ val->ssa->def = nir_mov(&b->nb, src[0]);
} else {
nir_op op;
switch (src[0]->num_components) {
case SpvOpAll:
if (src[0]->num_components == 1) {
- val->ssa->def = nir_imov(&b->nb, src[0]);
+ val->ssa->def = nir_mov(&b->nb, src[0]);
} else {
nir_op op;
switch (src[0]->num_components) {
break;
}
- case SpvOpBitcast:
- /* From the definition of OpBitcast in the SPIR-V 1.2 spec:
- *
- * "If Result Type has the same number of components as Operand, they
- * must also have the same component width, and results are computed
- * per component.
- *
- * If Result Type has a different number of components than Operand,
- * the total number of bits in Result Type must equal the total
- * number of bits in Operand. Let L be the type, either Result Type
- * or Operand’s type, that has the larger number of components. Let S
- * be the other type, with the smaller number of components. The
- * number of components in L must be an integer multiple of the
- * number of components in S. The first component (that is, the only
- * or lowest-numbered component) of S maps to the first components of
- * L, and so on, up to the last component of S mapping to the last
- * components of L. Within this mapping, any single component of S
- * (mapping to multiple components of L) maps its lower-ordered bits
- * to the lower-numbered components of L."
- */
- vtn_fail_if(src[0]->num_components * src[0]->bit_size !=
- glsl_get_vector_elements(type) * glsl_get_bit_size(type),
- "Source and destination of OpBitcast must have the same "
- "total number of bits");
- val->ssa->def = nir_bitcast_vector(&b->nb, src[0],
- glsl_get_bit_size(type));
- 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(type);
val->ssa->def =
nir_ishr(&b->nb, src[0], nir_imm_int(&b->nb, src_bit_size - 1));
- if (src_bit_size != 32)
- val->ssa->def = nir_u2u32(&b->nb, val->ssa->def);
-
+ val->ssa->def = nir_i2b(&b->nb, val->ssa->def);
break;
}
+ case SpvOpUCountTrailingZerosINTEL:
+ val->ssa->def = nir_umin(&b->nb,
+ nir_find_lsb(&b->nb, src[0]),
+ nir_imm_int(&b->nb, 32u));
+ break;
+
default: {
bool swap;
unsigned src_bit_size = glsl_get_bit_size(vtn_src[0]->type);
} /* default */
}
+ switch (opcode) {
+ case SpvOpIAdd:
+ case SpvOpIMul:
+ case SpvOpISub:
+ case SpvOpShiftLeftLogical:
+ case SpvOpSNegate: {
+ nir_alu_instr *alu = nir_instr_as_alu(val->ssa->def->parent_instr);
+ vtn_foreach_decoration(b, val, handle_no_wrap, alu);
+ break;
+ }
+ default:
+ /* Do nothing. */
+ break;
+ }
+
b->nb.exact = b->exact;
}
+
+void
+vtn_handle_bitcast(struct vtn_builder *b, const uint32_t *w, unsigned count)
+{
+ vtn_assert(count == 4);
+ /* From the definition of OpBitcast in the SPIR-V 1.2 spec:
+ *
+ * "If Result Type has the same number of components as Operand, they
+ * must also have the same component width, and results are computed per
+ * component.
+ *
+ * If Result Type has a different number of components than Operand, the
+ * total number of bits in Result Type must equal the total number of
+ * bits in Operand. Let L be the type, either Result Type or Operand’s
+ * type, that has the larger number of components. Let S be the other
+ * type, with the smaller number of components. The number of components
+ * in L must be an integer multiple of the number of components in S.
+ * The first component (that is, the only or lowest-numbered component)
+ * of S maps to the first components of L, and so on, up to the last
+ * component of S mapping to the last components of L. Within this
+ * mapping, any single component of S (mapping to multiple components of
+ * L) maps its lower-ordered bits to the lower-numbered components of L."
+ */
+
+ struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
+ struct vtn_ssa_value *vtn_src = vtn_ssa_value(b, w[3]);
+ struct nir_ssa_def *src = vtn_src->def;
+ struct vtn_ssa_value *val = vtn_create_ssa_value(b, type->type);
+
+ vtn_assert(glsl_type_is_vector_or_scalar(vtn_src->type));
+
+ vtn_fail_if(src->num_components * src->bit_size !=
+ glsl_get_vector_elements(type->type) * glsl_get_bit_size(type->type),
+ "Source and destination of OpBitcast must have the same "
+ "total number of bits");
+ val->def = nir_bitcast_vector(&b->nb, src, glsl_get_bit_size(type->type));
+ vtn_push_ssa(b, w[2], type, val);
+}