i965/fs: Add infrastructure for generating CSEL instructions.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 23 Nov 2015 04:12:17 +0000 (20:12 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 8 Mar 2018 23:26:26 +0000 (15:26 -0800)
v2 (idr): Don't allow CSEL with a non-float src2.

v3 (idr): Add CSEL to fs_inst::flags_written.  Suggested by Matt.

v4 (idr): Only set BRW_ALIGN_16 on Gen < 10 (suggested by Matt).  Don't
reset the access mode afterwards (suggested by Samuel and Matt).  Add
support for CSEL not modifying the flags to more places (requested by
Matt).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> [v3]
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/intel/compiler/brw_disasm.c
src/intel/compiler/brw_eu.h
src/intel/compiler/brw_eu_emit.c
src/intel/compiler/brw_fs.cpp
src/intel/compiler/brw_fs_builder.h
src/intel/compiler/brw_fs_generator.cpp
src/intel/compiler/brw_ir_vec4.h
src/intel/compiler/brw_vec4.cpp

index a9a108f8acd1b9df569c4ee33c2f5f78ba0b261a..5f75c67942e20bfb666ecb2ce765afad7b88ca14 100644 (file)
@@ -1508,6 +1508,7 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
        */
       if (brw_inst_cond_modifier(devinfo, inst) &&
           (devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
+                                opcode != BRW_OPCODE_CSEL &&
                                 opcode != BRW_OPCODE_IF &&
                                 opcode != BRW_OPCODE_WHILE))) {
          format(file, ".f%"PRIu64,
index a5f28d8fc650f1b57c6e0986e68b81063401ceb9..ca72666a55a641aee100fe66de24a926668a5973 100644 (file)
@@ -171,6 +171,7 @@ ALU2(SHR)
 ALU2(SHL)
 ALU1(DIM)
 ALU2(ASR)
+ALU3(CSEL)
 ALU1(F32TO16)
 ALU1(F16TO32)
 ALU2(ADD)
index f8102e014e598fbb0871d53b6376f26ca3e17d13..f039af56d05d5716c5748c00b51aa59a996e2b3d 100644 (file)
@@ -959,6 +959,7 @@ ALU2(SHR)
 ALU2(SHL)
 ALU1(DIM)
 ALU2(ASR)
+ALU3(CSEL)
 ALU1(FRC)
 ALU1(RNDD)
 ALU2(MAC)
index 53ba94ccccbd3477e5d88feec840aab94cf611a6..02a8ea0fd9dada60ef5a5f3867e4f9d202b1e3e1 100644 (file)
@@ -945,6 +945,7 @@ unsigned
 fs_inst::flags_written() const
 {
    if ((conditional_mod && (opcode != BRW_OPCODE_SEL &&
+                            opcode != BRW_OPCODE_CSEL &&
                             opcode != BRW_OPCODE_IF &&
                             opcode != BRW_OPCODE_WHILE)) ||
        opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS ||
@@ -5578,6 +5579,7 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
       fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
       if (!inst->predicate &&
           (devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
+                                inst->opcode != BRW_OPCODE_CSEL &&
                                 inst->opcode != BRW_OPCODE_IF &&
                                 inst->opcode != BRW_OPCODE_WHILE))) {
          fprintf(file, ".f%d.%d", inst->flag_subreg / 2,
index cf603b0c86891b1feed371cf1c5c0c86172dad09..4203c8c27c3d34121d931aa418ac1ed53179f621 100644 (file)
@@ -567,7 +567,6 @@ namespace brw {
       ALU1(BFREV)
       ALU1(CBIT)
       ALU2(CMPN)
-      ALU3(CSEL)
       ALU1(DIM)
       ALU2(DP2)
       ALU2(DP3)
@@ -642,6 +641,27 @@ namespace brw {
          return set_predicate(predicate, emit(BRW_OPCODE_IF));
       }
 
+      /**
+       * CSEL: dst = src2 <op> 0.0f ? src0 : src1
+       */
+      instruction *
+      CSEL(const dst_reg &dst, const src_reg &src0, const src_reg &src1,
+           const src_reg &src2, brw_conditional_mod condition) const
+      {
+         /* CSEL only operates on floats, so we can't do integer </<=/>=/>
+          * comparisons.  Zero/non-zero (== and !=) comparisons almost work.
+          * 0x80000000 fails because it is -0.0, and -0.0 == 0.0.
+          */
+         assert(src2.type == BRW_REGISTER_TYPE_F);
+
+         return set_condmod(condition,
+                            emit(BRW_OPCODE_CSEL,
+                                 retype(dst, BRW_REGISTER_TYPE_F),
+                                 retype(src0, BRW_REGISTER_TYPE_F),
+                                 retype(src1, BRW_REGISTER_TYPE_F),
+                                 src2));
+      }
+
       /**
        * Emit a linear interpolation instruction.
        */
index 5371246fd24192079a1224125077314627b604f6..0c85eb8e1e0a461bad2dc0230d5575560df15015 100644 (file)
@@ -1975,6 +1975,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       case BRW_OPCODE_SEL:
         brw_SEL(p, dst, src[0], src[1]);
         break;
+      case BRW_OPCODE_CSEL:
+         assert(devinfo->gen >= 8);
+         if (devinfo->gen < 10)
+            brw_set_default_access_mode(p, BRW_ALIGN_16);
+         brw_CSEL(p, dst, src[0], src[1], src[2]);
+         break;
       case BRW_OPCODE_BFREV:
          assert(devinfo->gen >= 7);
          brw_BFREV(p, retype(dst, BRW_REGISTER_TYPE_UD),
index a0e6402b0a4e60c8807a47a05e1d59bef74a694b..cbaff2feff4f20a1881c88644808d2be3377de14 100644 (file)
@@ -329,6 +329,7 @@ public:
    bool writes_flag()
    {
       return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
+                                  opcode != BRW_OPCODE_CSEL &&
                                   opcode != BRW_OPCODE_IF &&
                                   opcode != BRW_OPCODE_WHILE));
    }
index ac6b997b668f190268ae536652a354b60250b914..e4838146ac15cb6638002a435e5a9b8135afd89a 100644 (file)
@@ -1557,6 +1557,7 @@ vec4_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
       fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
       if (!inst->predicate &&
           (devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
+                                inst->opcode != BRW_OPCODE_CSEL &&
                                 inst->opcode != BRW_OPCODE_IF &&
                                 inst->opcode != BRW_OPCODE_WHILE))) {
          fprintf(file, ".f%d.%d", inst->flag_subreg / 2, inst->flag_subreg % 2);