diff options
author | Antia Puentes <[email protected]> | 2015-06-17 09:47:41 +0200 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-08-03 09:40:49 -0700 |
commit | 798cb33a256f703ecaf56d4443e12055484d4bcc (patch) | |
tree | fa9bb137931a30bcb50f1ca3f70c65123eb5f870 | |
parent | 8e1e6facbf828258a9a8ca09da846d1baa21d984 (diff) |
i965/nir/vec4: Implement the "sign" operation
Follows the vec4_visitor IR implementation but
sets the saturate value in addition.
Adds NIR ALU operations:
* nir_op_fsign
* nir_op_isign
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index e2357307ed3..560797068fb 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1148,6 +1148,39 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr) unreachable("not reached: should be handled by " "lower_instructions::bitfield_insert_to_bfm_bfi"); + case nir_op_fsign: + /* AND(val, 0x80000000) gives the sign bit. + * + * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not + * zero. + */ + emit(CMP(dst_null_f(), op[0], src_reg(0.0f), BRW_CONDITIONAL_NZ)); + + op[0].type = BRW_REGISTER_TYPE_UD; + dst.type = BRW_REGISTER_TYPE_UD; + emit(AND(dst, op[0], src_reg(0x80000000u))); + + inst = emit(OR(dst, src_reg(dst), src_reg(0x3f800000u))); + inst->predicate = BRW_PREDICATE_NORMAL; + dst.type = BRW_REGISTER_TYPE_F; + + if (instr->dest.saturate) { + inst = emit(MOV(dst, src_reg(dst))); + inst->saturate = true; + } + break; + + case nir_op_isign: + /* ASR(val, 31) -> negative val generates 0xffffffff (signed -1). + * -> non-negative val generates 0x00000000. + * Predicated OR sets 1 if val is positive. + */ + emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_G)); + emit(ASR(dst, op[0], src_reg(31))); + inst = emit(OR(dst, src_reg(dst), src_reg(1))); + inst->predicate = BRW_PREDICATE_NORMAL; + break; + default: unreachable("Unimplemented ALU operation"); } |