intel/fs: Refactor code generation for nir_op_fsign to its own function

v2: Call emit_fsign from inside the existing switch statement.
Suggested by Matt.

Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
Ian Romanick
2018-06-25 19:50:56 -07:00
parent 90430d0488
commit ad98fbc217
2 changed files with 65 additions and 65 deletions

View File

@@ -187,6 +187,8 @@ public:
void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
fs_reg resolve_source_modifiers(const fs_reg &src);
void emit_discard_jump();
void emit_fsign(const class brw::fs_builder &, const nir_alu_instr *instr,
fs_reg result, fs_reg *op);
bool opt_peephole_sel();
bool opt_peephole_csel();
bool opt_peephole_predicated_break();

View File

@@ -801,6 +801,67 @@ fs_visitor::try_emit_b2fi_of_inot(const fs_builder &bld,
return true;
}
/**
* Emit code for nir_op_fsign
*/
void
fs_visitor::emit_fsign(const fs_builder &bld, const nir_alu_instr *instr,
fs_reg result, fs_reg *op)
{
fs_inst *inst;
assert(instr->op == nir_op_fsign);
assert(!instr->dest.saturate);
if (op[0].abs) {
/* Straightforward since the source can be assumed to be either strictly
* >= 0 or strictly <= 0 depending on the setting of the negate flag.
*/
set_condmod(BRW_CONDITIONAL_NZ, bld.MOV(result, op[0]));
inst = (op[0].negate)
? bld.MOV(result, brw_imm_f(-1.0f))
: bld.MOV(result, brw_imm_f(1.0f));
set_predicate(BRW_PREDICATE_NORMAL, inst);
} else if (type_sz(op[0].type) < 8) {
/* AND(val, 0x80000000) gives the sign bit.
*
* Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
* zero.
*/
bld.CMP(bld.null_reg_f(), op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ);
fs_reg result_int = retype(result, BRW_REGISTER_TYPE_UD);
op[0].type = BRW_REGISTER_TYPE_UD;
result.type = BRW_REGISTER_TYPE_UD;
bld.AND(result_int, op[0], brw_imm_ud(0x80000000u));
inst = bld.OR(result_int, result_int, brw_imm_ud(0x3f800000u));
inst->predicate = BRW_PREDICATE_NORMAL;
} else {
/* For doubles we do the same but we need to consider:
*
* - 2-src instructions can't operate with 64-bit immediates
* - The sign is encoded in the high 32-bit of each DF
* - We need to produce a DF result.
*/
fs_reg zero = vgrf(glsl_type::double_type);
bld.MOV(zero, setup_imm_df(bld, 0.0));
bld.CMP(bld.null_reg_df(), op[0], zero, BRW_CONDITIONAL_NZ);
bld.MOV(result, zero);
fs_reg r = subscript(result, BRW_REGISTER_TYPE_UD, 1);
bld.AND(r, subscript(op[0], BRW_REGISTER_TYPE_UD, 1),
brw_imm_ud(0x80000000u));
set_predicate(BRW_PREDICATE_NORMAL,
bld.OR(r, r, brw_imm_ud(0x3ff00000u)));
}
}
void
fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
{
@@ -932,72 +993,9 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
inst->saturate = instr->dest.saturate;
break;
case nir_op_fsign: {
assert(!instr->dest.saturate);
if (op[0].abs) {
/* Straightforward since the source can be assumed to be either
* strictly >= 0 or strictly <= 0 depending on the setting of the
* negate flag.
*/
set_condmod(BRW_CONDITIONAL_NZ, bld.MOV(result, op[0]));
inst = (op[0].negate)
? bld.MOV(result, brw_imm_f(-1.0f))
: bld.MOV(result, brw_imm_f(1.0f));
set_predicate(BRW_PREDICATE_NORMAL, inst);
} else if (type_sz(op[0].type) == 2) {
/* AND(val, 0x8000) gives the sign bit.
*
* Predicated OR ORs 1.0 (0x3c00) with the sign bit if val is not zero.
*/
fs_reg zero = retype(brw_imm_uw(0), BRW_REGISTER_TYPE_HF);
bld.CMP(bld.null_reg_f(), op[0], zero, BRW_CONDITIONAL_NZ);
op[0].type = BRW_REGISTER_TYPE_UW;
result.type = BRW_REGISTER_TYPE_UW;
bld.AND(result, op[0], brw_imm_uw(0x8000u));
inst = bld.OR(result, result, brw_imm_uw(0x3c00u));
inst->predicate = BRW_PREDICATE_NORMAL;
} else if (type_sz(op[0].type) == 4) {
/* AND(val, 0x80000000) gives the sign bit.
*
* Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
* zero.
*/
bld.CMP(bld.null_reg_f(), op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ);
op[0].type = BRW_REGISTER_TYPE_UD;
result.type = BRW_REGISTER_TYPE_UD;
bld.AND(result, op[0], brw_imm_ud(0x80000000u));
inst = bld.OR(result, result, brw_imm_ud(0x3f800000u));
inst->predicate = BRW_PREDICATE_NORMAL;
} else {
/* For doubles we do the same but we need to consider:
*
* - 2-src instructions can't operate with 64-bit immediates
* - The sign is encoded in the high 32-bit of each DF
* - We need to produce a DF result.
*/
assert(type_sz(op[0].type) == 8);
fs_reg zero = vgrf(glsl_type::double_type);
bld.MOV(zero, setup_imm_df(bld, 0.0));
bld.CMP(bld.null_reg_df(), op[0], zero, BRW_CONDITIONAL_NZ);
bld.MOV(result, zero);
fs_reg r = subscript(result, BRW_REGISTER_TYPE_UD, 1);
bld.AND(r, subscript(op[0], BRW_REGISTER_TYPE_UD, 1),
brw_imm_ud(0x80000000u));
set_predicate(BRW_PREDICATE_NORMAL,
bld.OR(r, r, brw_imm_ud(0x3ff00000u)));
}
case nir_op_fsign:
emit_fsign(bld, instr, result, op);
break;
}
case nir_op_frcp:
inst = bld.emit(SHADER_OPCODE_RCP, result, op[0]);