summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir/nir_search.c')
-rw-r--r--src/compiler/nir/nir_search.c90
1 files changed, 84 insertions, 6 deletions
diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c
index a41fca876d5..f5fc92ec33c 100644
--- a/src/compiler/nir/nir_search.c
+++ b/src/compiler/nir/nir_search.c
@@ -90,6 +90,82 @@ src_is_type(nir_src src, nir_alu_type type)
}
static bool
+nir_op_matches_search_op(nir_op nop, uint16_t sop)
+{
+ if (sop <= nir_last_opcode)
+ return nop == sop;
+
+#define MATCH_FCONV_CASE(op) \
+ case nir_search_op_##op: \
+ return nop == nir_op_##op##16 || \
+ nop == nir_op_##op##32 || \
+ nop == nir_op_##op##64;
+
+#define MATCH_ICONV_CASE(op) \
+ case nir_search_op_##op: \
+ return nop == nir_op_##op##8 || \
+ nop == nir_op_##op##16 || \
+ nop == nir_op_##op##32 || \
+ nop == nir_op_##op##64;
+
+ switch (sop) {
+ MATCH_FCONV_CASE(i2f)
+ MATCH_FCONV_CASE(u2f)
+ MATCH_FCONV_CASE(f2f)
+ MATCH_ICONV_CASE(f2u)
+ MATCH_ICONV_CASE(f2i)
+ MATCH_ICONV_CASE(u2u)
+ MATCH_ICONV_CASE(i2i)
+ default:
+ unreachable("Invalid nir_search_op");
+ }
+
+#undef MATCH_FCONV_CASE
+#undef MATCH_ICONV_CASE
+}
+
+static nir_op
+nir_op_for_search_op(uint16_t sop, unsigned bit_size)
+{
+ if (sop <= nir_last_opcode)
+ return sop;
+
+#define RET_FCONV_CASE(op) \
+ case nir_search_op_##op: \
+ switch (bit_size) { \
+ case 16: return nir_op_##op##16; \
+ case 32: return nir_op_##op##32; \
+ case 64: return nir_op_##op##64; \
+ default: unreachable("Invalid bit size"); \
+ }
+
+#define RET_ICONV_CASE(op) \
+ case nir_search_op_##op: \
+ switch (bit_size) { \
+ case 8: return nir_op_##op##8; \
+ case 16: return nir_op_##op##16; \
+ case 32: return nir_op_##op##32; \
+ case 64: return nir_op_##op##64; \
+ default: unreachable("Invalid bit size"); \
+ }
+
+ switch (sop) {
+ RET_FCONV_CASE(i2f)
+ RET_FCONV_CASE(u2f)
+ RET_FCONV_CASE(f2f)
+ RET_ICONV_CASE(f2u)
+ RET_ICONV_CASE(f2i)
+ RET_ICONV_CASE(u2u)
+ RET_ICONV_CASE(i2i)
+ default:
+ unreachable("Invalid nir_search_op");
+ }
+
+#undef RET_FCONV_CASE
+#undef RET_ICONV_CASE
+}
+
+static bool
match_value(const nir_search_value *value, nir_alu_instr *instr, unsigned src,
unsigned num_components, const uint8_t *swizzle,
struct match_state *state)
@@ -223,7 +299,7 @@ match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
if (expr->cond && !expr->cond(instr))
return false;
- if (instr->op != expr->opcode)
+ if (!nir_op_matches_search_op(instr->op, expr->opcode))
return false;
assert(instr->dest.dest.is_ssa);
@@ -311,13 +387,15 @@ construct_value(nir_builder *build,
switch (value->type) {
case nir_search_value_expression: {
const nir_search_expression *expr = nir_search_value_as_expression(value);
+ unsigned dst_bit_size = replace_bitsize(value, search_bitsize, state);
+ nir_op op = nir_op_for_search_op(expr->opcode, dst_bit_size);
- if (nir_op_infos[expr->opcode].output_size != 0)
- num_components = nir_op_infos[expr->opcode].output_size;
+ if (nir_op_infos[op].output_size != 0)
+ num_components = nir_op_infos[op].output_size;
- nir_alu_instr *alu = nir_alu_instr_create(build->shader, expr->opcode);
+ nir_alu_instr *alu = nir_alu_instr_create(build->shader, op);
nir_ssa_dest_init(&alu->instr, &alu->dest.dest, num_components,
- replace_bitsize(value, search_bitsize, state), NULL);
+ dst_bit_size, NULL);
alu->dest.write_mask = (1 << num_components) - 1;
alu->dest.saturate = false;
@@ -328,7 +406,7 @@ construct_value(nir_builder *build,
*/
alu->exact = state->has_exact_alu;
- for (unsigned i = 0; i < nir_op_infos[expr->opcode].num_inputs; i++) {
+ for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++) {
/* If the source is an explicitly sized source, then we need to reset
* the number of components to match.
*/