diff options
Diffstat (limited to 'src/compiler/nir/nir_search.c')
-rw-r--r-- | src/compiler/nir/nir_search.c | 90 |
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. */ |