intel/fs: Refactor code generation for nir_op_fsign to its own function
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 26 Jun 2018 02:50:56 +0000 (19:50 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 18 Apr 2019 19:37:48 +0000 (12:37 -0700)
v2: Call emit_fsign from inside the existing switch statement.
Suggested by Matt.

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/intel/compiler/brw_fs.h
src/intel/compiler/brw_fs_nir.cpp

index 391d46d5471c77d5b96e128ce3c90265554e0d03..b0147b39d3253b2221025d38b56c3519ac17cb28 100644 (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();
index 397d1f5980a15795de696203d2100cab5c27d8b5..1287035f54c1773b12e5db549aefe77d2ea0227c 100644 (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]);