i965: Use LZD to implement nir_op_find_lsb on Gen < 7
v2: Rebase on changes to previous two patches. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -1387,7 +1387,27 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
|
||||
|
||||
case nir_op_find_lsb:
|
||||
assert(nir_dest_bit_size(instr->dest.dest) < 64);
|
||||
bld.FBL(result, op[0]);
|
||||
|
||||
if (devinfo->gen < 7) {
|
||||
fs_reg temp = vgrf(glsl_type::int_type);
|
||||
|
||||
/* (x & -x) generates a value that consists of only the LSB of x.
|
||||
* For all powers of 2, findMSB(y) == findLSB(y).
|
||||
*/
|
||||
fs_reg src = retype(op[0], BRW_REGISTER_TYPE_D);
|
||||
fs_reg negated_src = src;
|
||||
|
||||
/* One must be negated, and the other must be non-negated. It
|
||||
* doesn't matter which is which.
|
||||
*/
|
||||
negated_src.negate = true;
|
||||
src.negate = false;
|
||||
|
||||
bld.AND(temp, src, negated_src);
|
||||
emit_find_msb_using_lzd(bld, result, temp, false);
|
||||
} else {
|
||||
bld.FBL(result, op[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case nir_op_ubitfield_extract:
|
||||
|
@@ -1535,9 +1535,31 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_op_find_lsb:
|
||||
emit(FBL(dst, op[0]));
|
||||
case nir_op_find_lsb: {
|
||||
vec4_builder bld = vec4_builder(this).at_end();
|
||||
|
||||
if (devinfo->gen < 7) {
|
||||
dst_reg temp = bld.vgrf(BRW_REGISTER_TYPE_D);
|
||||
|
||||
/* (x & -x) generates a value that consists of only the LSB of x.
|
||||
* For all powers of 2, findMSB(y) == findLSB(y).
|
||||
*/
|
||||
src_reg src = src_reg(retype(op[0], BRW_REGISTER_TYPE_D));
|
||||
src_reg negated_src = src;
|
||||
|
||||
/* One must be negated, and the other must be non-negated. It
|
||||
* doesn't matter which is which.
|
||||
*/
|
||||
negated_src.negate = true;
|
||||
src.negate = false;
|
||||
|
||||
bld.AND(temp, src, negated_src);
|
||||
emit_find_msb_using_lzd(bld, dst, src_reg(temp), false);
|
||||
} else {
|
||||
bld.FBL(dst, op[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_op_ubitfield_extract:
|
||||
case nir_op_ibitfield_extract:
|
||||
|
Reference in New Issue
Block a user