From 70de61594dcf99f24eb31ebf98d62f13e1f44c2e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sun, 22 Nov 2015 20:12:17 -0800 Subject: [PATCH] i965/fs: Add infrastructure for generating CSEL instructions. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Ian Romanick Reviewed-by: Samuel Iglesias Gonsálvez [v3] Reviewed-by: Matt Turner --- src/intel/compiler/brw_disasm.c | 1 + src/intel/compiler/brw_eu.h | 1 + src/intel/compiler/brw_eu_emit.c | 1 + src/intel/compiler/brw_fs.cpp | 2 ++ src/intel/compiler/brw_fs_builder.h | 22 +++++++++++++++++++++- src/intel/compiler/brw_fs_generator.cpp | 6 ++++++ src/intel/compiler/brw_ir_vec4.h | 1 + src/intel/compiler/brw_vec4.cpp | 1 + 8 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/intel/compiler/brw_disasm.c b/src/intel/compiler/brw_disasm.c index a9a108f8acd..5f75c67942e 100644 --- a/src/intel/compiler/brw_disasm.c +++ b/src/intel/compiler/brw_disasm.c @@ -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, diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h index a5f28d8fc65..ca72666a55a 100644 --- a/src/intel/compiler/brw_eu.h +++ b/src/intel/compiler/brw_eu.h @@ -171,6 +171,7 @@ ALU2(SHR) ALU2(SHL) ALU1(DIM) ALU2(ASR) +ALU3(CSEL) ALU1(F32TO16) ALU1(F16TO32) ALU2(ADD) diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c index f8102e014e5..f039af56d05 100644 --- a/src/intel/compiler/brw_eu_emit.c +++ b/src/intel/compiler/brw_eu_emit.c @@ -959,6 +959,7 @@ ALU2(SHR) ALU2(SHL) ALU1(DIM) ALU2(ASR) +ALU3(CSEL) ALU1(FRC) ALU1(RNDD) ALU2(MAC) diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 53ba94ccccb..02a8ea0fd9d 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -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, diff --git a/src/intel/compiler/brw_fs_builder.h b/src/intel/compiler/brw_fs_builder.h index cf603b0c868..4203c8c27c3 100644 --- a/src/intel/compiler/brw_fs_builder.h +++ b/src/intel/compiler/brw_fs_builder.h @@ -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 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. */ diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index 5371246fd24..0c85eb8e1e0 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -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), diff --git a/src/intel/compiler/brw_ir_vec4.h b/src/intel/compiler/brw_ir_vec4.h index a0e6402b0a4..cbaff2feff4 100644 --- a/src/intel/compiler/brw_ir_vec4.h +++ b/src/intel/compiler/brw_ir_vec4.h @@ -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)); } diff --git a/src/intel/compiler/brw_vec4.cpp b/src/intel/compiler/brw_vec4.cpp index ac6b997b668..e4838146ac1 100644 --- a/src/intel/compiler/brw_vec4.cpp +++ b/src/intel/compiler/brw_vec4.cpp @@ -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); -- 2.30.2