nir: add opcodes for *find_msb_rev and lowering
Some hardware supports a version of find_msb where the bits are counted starting at the high bit, and this needs some lowering to obtain the value that is expected by *find_msb Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Reviewed-by: Kristian H. Kristensen <hoegsberg@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9452>
This commit is contained in:
@@ -3160,6 +3160,8 @@ typedef struct nir_shader_compiler_options {
|
||||
bool lower_bit_count;
|
||||
/** Lowers ifind_msb to compare and ufind_msb */
|
||||
bool lower_ifind_msb;
|
||||
/** Lowers ifind_msb and ufind_msb to reverse variants */
|
||||
bool lower_find_msb_to_reverse;
|
||||
/** Lowers find_lsb to ufind_msb and logic ops */
|
||||
bool lower_find_lsb;
|
||||
bool lower_uadd_carry;
|
||||
|
@@ -454,6 +454,16 @@ for (int bit = bit_size - 1; bit >= 0; bit--) {
|
||||
}
|
||||
""")
|
||||
|
||||
unop_convert("ufind_msb_rev", tint32, tuint, """
|
||||
dst = -1;
|
||||
for (int bit = 0; bit < bit_size; bit++) {
|
||||
if ((src0 << bit) & 0x80000000) {
|
||||
dst = bit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
unop("uclz", tuint32, """
|
||||
int bit;
|
||||
for (bit = bit_size - 1; bit >= 0; bit--) {
|
||||
@@ -477,6 +487,22 @@ for (int bit = 31; bit >= 0; bit--) {
|
||||
}
|
||||
""")
|
||||
|
||||
unop_convert("ifind_msb_rev", tint32, tuint, """
|
||||
dst = -1;
|
||||
if (src0 != 0 || src0 != -1) {
|
||||
for (int bit = 0; bit < 31; bit++) {
|
||||
/* If src0 < 0, we're looking for the first 0 bit.
|
||||
* if src0 >= 0, we're looking for the first 1 bit.
|
||||
*/
|
||||
if ((((src0 << bit) & 0x40000000) && (src0 >= 0)) ||
|
||||
((!((src0 << bit) & 0x40000000)) && (src0 < 0))) {
|
||||
dst = bit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
unop_convert("find_lsb", tint32, tint, """
|
||||
dst = -1;
|
||||
for (unsigned bit = 0; bit < bit_size; bit++) {
|
||||
|
@@ -1523,6 +1523,18 @@ optimizations.extend([
|
||||
('ufind_msb', ('bcsel', ('ilt', 'value', 0), ('inot', 'value'), 'value')),
|
||||
'options->lower_ifind_msb'),
|
||||
|
||||
(('ifind_msb', 'value'),
|
||||
('bcsel', ('ige', ('ifind_msb_rev', 'value'), 0),
|
||||
('isub', 31, ('ifind_msb_rev', 'value')),
|
||||
('ifind_msb_rev', 'value')),
|
||||
'options->lower_find_msb_to_reverse'),
|
||||
|
||||
(('ufind_msb', 'value'),
|
||||
('bcsel', ('ige', ('ufind_msb_rev', 'value'), 0),
|
||||
('isub', 31, ('ufind_msb_rev', 'value')),
|
||||
('ufind_msb_rev', 'value')),
|
||||
'options->lower_find_msb_to_reverse'),
|
||||
|
||||
(('find_lsb', 'value'),
|
||||
('ufind_msb', ('iand', 'value', ('ineg', 'value'))),
|
||||
'options->lower_find_lsb'),
|
||||
|
Reference in New Issue
Block a user