i965/fs: Add infrastructure for generating CSEL instructions.
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>
This commit is contained in:

committed by
Ian Romanick

parent
54e8d2268d
commit
70de61594d
@@ -1508,6 +1508,7 @@ brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
|
|||||||
*/
|
*/
|
||||||
if (brw_inst_cond_modifier(devinfo, inst) &&
|
if (brw_inst_cond_modifier(devinfo, inst) &&
|
||||||
(devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
|
(devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
|
||||||
|
opcode != BRW_OPCODE_CSEL &&
|
||||||
opcode != BRW_OPCODE_IF &&
|
opcode != BRW_OPCODE_IF &&
|
||||||
opcode != BRW_OPCODE_WHILE))) {
|
opcode != BRW_OPCODE_WHILE))) {
|
||||||
format(file, ".f%"PRIu64,
|
format(file, ".f%"PRIu64,
|
||||||
|
@@ -171,6 +171,7 @@ ALU2(SHR)
|
|||||||
ALU2(SHL)
|
ALU2(SHL)
|
||||||
ALU1(DIM)
|
ALU1(DIM)
|
||||||
ALU2(ASR)
|
ALU2(ASR)
|
||||||
|
ALU3(CSEL)
|
||||||
ALU1(F32TO16)
|
ALU1(F32TO16)
|
||||||
ALU1(F16TO32)
|
ALU1(F16TO32)
|
||||||
ALU2(ADD)
|
ALU2(ADD)
|
||||||
|
@@ -959,6 +959,7 @@ ALU2(SHR)
|
|||||||
ALU2(SHL)
|
ALU2(SHL)
|
||||||
ALU1(DIM)
|
ALU1(DIM)
|
||||||
ALU2(ASR)
|
ALU2(ASR)
|
||||||
|
ALU3(CSEL)
|
||||||
ALU1(FRC)
|
ALU1(FRC)
|
||||||
ALU1(RNDD)
|
ALU1(RNDD)
|
||||||
ALU2(MAC)
|
ALU2(MAC)
|
||||||
|
@@ -945,6 +945,7 @@ unsigned
|
|||||||
fs_inst::flags_written() const
|
fs_inst::flags_written() const
|
||||||
{
|
{
|
||||||
if ((conditional_mod && (opcode != BRW_OPCODE_SEL &&
|
if ((conditional_mod && (opcode != BRW_OPCODE_SEL &&
|
||||||
|
opcode != BRW_OPCODE_CSEL &&
|
||||||
opcode != BRW_OPCODE_IF &&
|
opcode != BRW_OPCODE_IF &&
|
||||||
opcode != BRW_OPCODE_WHILE)) ||
|
opcode != BRW_OPCODE_WHILE)) ||
|
||||||
opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS ||
|
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]);
|
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
|
||||||
if (!inst->predicate &&
|
if (!inst->predicate &&
|
||||||
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
|
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
|
||||||
|
inst->opcode != BRW_OPCODE_CSEL &&
|
||||||
inst->opcode != BRW_OPCODE_IF &&
|
inst->opcode != BRW_OPCODE_IF &&
|
||||||
inst->opcode != BRW_OPCODE_WHILE))) {
|
inst->opcode != BRW_OPCODE_WHILE))) {
|
||||||
fprintf(file, ".f%d.%d", inst->flag_subreg / 2,
|
fprintf(file, ".f%d.%d", inst->flag_subreg / 2,
|
||||||
|
@@ -567,7 +567,6 @@ namespace brw {
|
|||||||
ALU1(BFREV)
|
ALU1(BFREV)
|
||||||
ALU1(CBIT)
|
ALU1(CBIT)
|
||||||
ALU2(CMPN)
|
ALU2(CMPN)
|
||||||
ALU3(CSEL)
|
|
||||||
ALU1(DIM)
|
ALU1(DIM)
|
||||||
ALU2(DP2)
|
ALU2(DP2)
|
||||||
ALU2(DP3)
|
ALU2(DP3)
|
||||||
@@ -642,6 +641,27 @@ namespace brw {
|
|||||||
return set_predicate(predicate, emit(BRW_OPCODE_IF));
|
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.
|
* Emit a linear interpolation instruction.
|
||||||
*/
|
*/
|
||||||
|
@@ -1975,6 +1975,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
|
|||||||
case BRW_OPCODE_SEL:
|
case BRW_OPCODE_SEL:
|
||||||
brw_SEL(p, dst, src[0], src[1]);
|
brw_SEL(p, dst, src[0], src[1]);
|
||||||
break;
|
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:
|
case BRW_OPCODE_BFREV:
|
||||||
assert(devinfo->gen >= 7);
|
assert(devinfo->gen >= 7);
|
||||||
brw_BFREV(p, retype(dst, BRW_REGISTER_TYPE_UD),
|
brw_BFREV(p, retype(dst, BRW_REGISTER_TYPE_UD),
|
||||||
|
@@ -329,6 +329,7 @@ public:
|
|||||||
bool writes_flag()
|
bool writes_flag()
|
||||||
{
|
{
|
||||||
return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
|
return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
|
||||||
|
opcode != BRW_OPCODE_CSEL &&
|
||||||
opcode != BRW_OPCODE_IF &&
|
opcode != BRW_OPCODE_IF &&
|
||||||
opcode != BRW_OPCODE_WHILE));
|
opcode != BRW_OPCODE_WHILE));
|
||||||
}
|
}
|
||||||
|
@@ -1557,6 +1557,7 @@ vec4_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)
|
|||||||
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
|
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
|
||||||
if (!inst->predicate &&
|
if (!inst->predicate &&
|
||||||
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
|
(devinfo->gen < 5 || (inst->opcode != BRW_OPCODE_SEL &&
|
||||||
|
inst->opcode != BRW_OPCODE_CSEL &&
|
||||||
inst->opcode != BRW_OPCODE_IF &&
|
inst->opcode != BRW_OPCODE_IF &&
|
||||||
inst->opcode != BRW_OPCODE_WHILE))) {
|
inst->opcode != BRW_OPCODE_WHILE))) {
|
||||||
fprintf(file, ".f%d.%d", inst->flag_subreg / 2, inst->flag_subreg % 2);
|
fprintf(file, ".f%d.%d", inst->flag_subreg / 2, inst->flag_subreg % 2);
|
||||||
|
Reference in New Issue
Block a user