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;
|
bool lower_bit_count;
|
||||||
/** Lowers ifind_msb to compare and ufind_msb */
|
/** Lowers ifind_msb to compare and ufind_msb */
|
||||||
bool lower_ifind_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 */
|
/** Lowers find_lsb to ufind_msb and logic ops */
|
||||||
bool lower_find_lsb;
|
bool lower_find_lsb;
|
||||||
bool lower_uadd_carry;
|
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, """
|
unop("uclz", tuint32, """
|
||||||
int bit;
|
int bit;
|
||||||
for (bit = bit_size - 1; bit >= 0; 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, """
|
unop_convert("find_lsb", tint32, tint, """
|
||||||
dst = -1;
|
dst = -1;
|
||||||
for (unsigned bit = 0; bit < bit_size; bit++) {
|
for (unsigned bit = 0; bit < bit_size; bit++) {
|
||||||
|
@@ -1523,6 +1523,18 @@ optimizations.extend([
|
|||||||
('ufind_msb', ('bcsel', ('ilt', 'value', 0), ('inot', 'value'), 'value')),
|
('ufind_msb', ('bcsel', ('ilt', 'value', 0), ('inot', 'value'), 'value')),
|
||||||
'options->lower_ifind_msb'),
|
'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'),
|
(('find_lsb', 'value'),
|
||||||
('ufind_msb', ('iand', 'value', ('ineg', 'value'))),
|
('ufind_msb', ('iand', 'value', ('ineg', 'value'))),
|
||||||
'options->lower_find_lsb'),
|
'options->lower_find_lsb'),
|
||||||
|
Reference in New Issue
Block a user