*/
nir_alu_instr *cond = nir_src_as_alu_instr(if_stmt->condition);
if (cond != NULL && cond->op == nir_op_inot) {
- assert(!cond->src[0].negate);
- assert(!cond->src[0].abs);
-
invert = true;
cond_reg = get_nir_src(cond->src[0].src);
} else {
src0->op != nir_op_extract_i8 && src0->op != nir_op_extract_i16)
return false;
- /* If either opcode has source modifiers, bail.
- *
- * TODO: We can potentially handle source modifiers if both of the opcodes
- * we're combining are signed integers.
- */
- if (instr->src[0].abs || instr->src[0].negate ||
- src0->src[0].abs || src0->src[0].negate)
- return false;
-
unsigned element = nir_src_as_uint(src0->src[1].src);
/* Element type to extract.*/
nir_src_bit_size(src0->src[0].src)));
op0 = offset(op0, bld, src0->src[0].swizzle[0]);
- set_saturate(instr->dest.saturate,
- bld.MOV(result, subscript(op0, type, element)));
+ bld.MOV(result, subscript(op0, type, element));
return true;
}
(nir_alu_type)(nir_op_infos[instr->op].output_type |
nir_dest_bit_size(instr->dest.dest)));
+ assert(!instr->dest.saturate);
+
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
+ /* We don't lower to source modifiers so they should not exist. */
+ assert(!instr->src[i].abs);
+ assert(!instr->src[i].negate);
+
op[i] = get_nir_src(instr->src[i].src);
op[i].type = brw_type_for_nir_type(devinfo,
(nir_alu_type)(nir_op_infos[instr->op].input_types[i] |
nir_src_bit_size(instr->src[i].src)));
- op[i].abs = instr->src[i].abs;
- op[i].negate = instr->src[i].negate;
}
/* Move and vecN instrutions may still be vectored. Return the raw,
for (unsigned i = 0; i < 2; i++) {
nir_alu_instr *inot_instr = nir_src_as_alu_instr(instr->src[i].src);
- if (inot_instr != NULL && inot_instr->op == nir_op_inot &&
- !inot_instr->src[0].abs && !inot_instr->src[0].negate) {
+ if (inot_instr != NULL && inot_instr->op == nir_op_inot) {
/* The source of the inot is now the source of instr. */
prepare_alu_destination_and_sources(bld, inot_instr, &op[i], false);
const nir_alu_instr *const fsign_instr =
nir_src_as_alu_instr(instr->src[fsign_src].src);
- assert(!fsign_instr->dest.saturate);
-
/* op[fsign_src] has the nominal result of the fsign, and op[1 -
* fsign_src] has the other multiply source. This must be rearranged so
* that op[0] is the source of the fsign op[1] is the other multiply
nir_src_bit_size(fsign_instr->src[0].src));
op[0].type = brw_type_for_nir_type(devinfo, t);
- op[0].abs = fsign_instr->src[0].abs;
- op[0].negate = fsign_instr->src[0].negate;
unsigned channel = 0;
if (nir_op_infos[instr->op].output_size == 0) {
bld.MOV(tmp, op[1]);
op[1] = tmp;
}
- } else {
- assert(!instr->dest.saturate);
}
if (op[0].abs) {
* have already been taken (in nir_opt_algebraic) to ensure that.
*/
return fsign_instr != NULL && fsign_instr->op == nir_op_fsign &&
- is_used_once(fsign_instr) &&
- !instr->src[fsign_src].abs && !instr->src[fsign_src].negate;
+ is_used_once(fsign_instr);
}
void
inst = bld.MOV(offset(temp, bld, i),
offset(op[i], bld, instr->src[i].swizzle[0]));
}
- inst->saturate = instr->dest.saturate;
}
/* In this case the source and destination registers were the same,
if (optimize_extract_to_float(instr, result))
return;
inst = bld.MOV(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_f2f16_rtne:
*/
assert(type_sz(op[0].type) < 8); /* brw_nir_lower_conversions */
inst = bld.MOV(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
}
assert(type_sz(result.type) < 8); /* brw_nir_lower_conversions */
inst = bld.MOV(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fsat:
case nir_op_ineg:
op[0].negate = true;
inst = bld.MOV(result, op[0]);
- if (instr->op == nir_op_fneg)
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fabs:
op[0].negate = false;
op[0].abs = true;
inst = bld.MOV(result, op[0]);
- if (instr->op == nir_op_fabs)
- inst->saturate = instr->dest.saturate;
break;
case nir_op_f2f32:
assert(type_sz(result.type) < 8); /* brw_nir_lower_conversions */
inst = bld.MOV(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fsign:
case nir_op_frcp:
inst = bld.emit(SHADER_OPCODE_RCP, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fexp2:
inst = bld.emit(SHADER_OPCODE_EXP2, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_flog2:
inst = bld.emit(SHADER_OPCODE_LOG2, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fsin:
inst = bld.emit(SHADER_OPCODE_SIN, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fcos:
inst = bld.emit(SHADER_OPCODE_COS, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddx:
} else {
inst = bld.emit(FS_OPCODE_DDX_COARSE, result, op[0]);
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddx_fine:
inst = bld.emit(FS_OPCODE_DDX_FINE, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddx_coarse:
inst = bld.emit(FS_OPCODE_DDX_COARSE, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddy:
if (fs_key->high_quality_derivatives) {
} else {
inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0]);
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddy_fine:
inst = bld.emit(FS_OPCODE_DDY_FINE, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddy_coarse:
inst = bld.emit(FS_OPCODE_DDY_COARSE, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fadd:
/* fallthrough */
case nir_op_iadd:
inst = bld.ADD(result, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_iadd_sat:
case nir_op_uadd_sat:
inst = bld.ADD(result, op[0], op[1]);
- inst->saturate = true;
break;
case nir_op_isub_sat:
}
inst = bld.MUL(result, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_imul_2x32_64:
if (inot_src_instr != NULL &&
(inot_src_instr->op == nir_op_ior ||
inot_src_instr->op == nir_op_ixor ||
- inot_src_instr->op == nir_op_iand) &&
- !inot_src_instr->src[0].abs &&
- !inot_src_instr->src[0].negate &&
- !inot_src_instr->src[1].abs &&
- !inot_src_instr->src[1].negate) {
+ inot_src_instr->op == nir_op_iand)) {
/* The sources of the source logical instruction are now the
* sources of the instruction that will be generated.
*/
case nir_op_fsqrt:
inst = bld.emit(SHADER_OPCODE_SQRT, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_frsq:
inst = bld.emit(SHADER_OPCODE_RSQ, result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_i2b32:
bld.ADD(result, result, brw_imm_f(1.0f)));
inst = bld.MOV(result, result); /* for potential saturation */
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fceil: {
bld.RNDD(temp, op[0]);
temp.negate = true;
inst = bld.MOV(result, temp);
- inst->saturate = instr->dest.saturate;
break;
}
case nir_op_ffloor:
inst = bld.RNDD(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_ffract:
inst = bld.FRC(result, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fround_even:
inst = bld.RNDE(result, op[0]);
bld.ADD(result, result, brw_imm_f(1.0f)));
inst = bld.MOV(result, result); /* for potential saturation */
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fquantize2f16: {
/* Select that or zero based on normal status */
inst = bld.SEL(result, zero, tmp32);
inst->predicate = BRW_PREDICATE_NORMAL;
- inst->saturate = instr->dest.saturate;
break;
}
case nir_op_umin:
case nir_op_fmin:
inst = bld.emit_minmax(result, op[0], op[1], BRW_CONDITIONAL_L);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_imax:
case nir_op_umax:
case nir_op_fmax:
inst = bld.emit_minmax(result, op[0], op[1], BRW_CONDITIONAL_GE);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_pack_snorm_2x16:
case nir_op_unpack_half_2x16_split_x:
inst = bld.emit(BRW_OPCODE_F16TO32, result,
subscript(op[0], BRW_REGISTER_TYPE_UW, 0));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_unpack_half_2x16_split_y_flush_to_zero:
case nir_op_unpack_half_2x16_split_y:
inst = bld.emit(BRW_OPCODE_F16TO32, result,
subscript(op[0], BRW_REGISTER_TYPE_UW, 1));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_pack_64_2x32_split:
case nir_op_fpow:
inst = bld.emit(SHADER_OPCODE_POW, result, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_bitfield_reverse:
}
inst = bld.MAD(result, op[2], op[1], op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_flrp:
}
inst = bld.LRP(result, op[0], op[1], op[2]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_b32csel:
OPT(nir_opt_cse);
}
- OPT(nir_lower_to_source_mods, nir_lower_all_source_mods);
OPT(nir_copy_prop);
OPT(nir_opt_dce);
OPT(nir_opt_move, nir_move_comparisons);
bool optimize_predicate(nir_alu_instr *instr, enum brw_predicate *predicate);
- void emit_conversion_from_double(dst_reg dst, src_reg src, bool saturate);
- void emit_conversion_to_double(dst_reg dst, src_reg src, bool saturate);
+ void emit_conversion_from_double(dst_reg dst, src_reg src);
+ void emit_conversion_to_double(dst_reg dst, src_reg src);
vec4_instruction *shuffle_64bit_data(dst_reg dst, src_reg src,
bool for_write,
unsigned base_swizzle =
brw_swizzle_for_nir_swizzle(cmp_instr->src[i].swizzle);
op[i].swizzle = brw_compose_swizzle(size_swizzle, base_swizzle);
- op[i].abs = cmp_instr->src[i].abs;
- op[i].negate = cmp_instr->src[i].negate;
}
emit(CMP(dst_null_d(), op[0], op[1],
}
void
-vec4_visitor::emit_conversion_from_double(dst_reg dst, src_reg src,
- bool saturate)
+vec4_visitor::emit_conversion_from_double(dst_reg dst, src_reg src)
{
/* BDW PRM vol 15 - workarounds:
* DF->f format conversion for Align16 has wrong emask calculation when
*/
if (devinfo->gen == 8 && dst.type == BRW_REGISTER_TYPE_F &&
src.file == BRW_IMMEDIATE_VALUE) {
- vec4_instruction *inst = emit(MOV(dst, brw_imm_f(src.df)));
- inst->saturate = saturate;
+ emit(MOV(dst, brw_imm_f(src.df)));
return;
}
emit(op, temp2, src_reg(temp));
emit(VEC4_OPCODE_PICK_LOW_32BIT, retype(temp2, dst.type), src_reg(temp2));
- vec4_instruction *inst = emit(MOV(dst, src_reg(retype(temp2, dst.type))));
- inst->saturate = saturate;
+ emit(MOV(dst, src_reg(retype(temp2, dst.type))));
}
void
-vec4_visitor::emit_conversion_to_double(dst_reg dst, src_reg src,
- bool saturate)
+vec4_visitor::emit_conversion_to_double(dst_reg dst, src_reg src)
{
dst_reg tmp_dst = dst_reg(src_reg(this, glsl_type::dvec4_type));
src_reg tmp_src = retype(src_reg(this, glsl_type::vec4_type), src.type);
emit(MOV(dst_reg(tmp_src), src));
emit(VEC4_OPCODE_TO_DOUBLE, tmp_dst, tmp_src);
- vec4_instruction *inst = emit(MOV(dst, src_reg(tmp_dst)));
- inst->saturate = saturate;
+ emit(MOV(dst, src_reg(tmp_dst)));
}
/**
dst_reg dst = get_nir_dest(instr->dest.dest, dst_type);
dst.writemask = instr->dest.write_mask;
+ assert(!instr->dest.saturate);
+
src_reg op[4];
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
+ /* We don't lower to source modifiers, so they shouldn't exist. */
+ assert(!instr->src[i].abs);
+ assert(!instr->src[i].negate);
+
nir_alu_type src_type = (nir_alu_type)
(nir_op_infos[instr->op].input_types[i] |
nir_src_bit_size(instr->src[i].src));
op[i] = get_nir_src(instr->src[i].src, src_type, 4);
op[i].swizzle = brw_swizzle_for_nir_swizzle(instr->src[i].swizzle);
- op[i].abs = instr->src[i].abs;
- op[i].negate = instr->src[i].negate;
}
switch (instr->op) {
case nir_op_mov:
try_immediate_source(instr, &op[0], true, devinfo);
inst = emit(MOV(dst, op[0]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_vec2:
case nir_op_i2f32:
case nir_op_u2f32:
inst = emit(MOV(dst, op[0]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_f2f32:
case nir_op_f2i32:
case nir_op_f2u32:
if (nir_src_bit_size(instr->src[0].src) == 64)
- emit_conversion_from_double(dst, op[0], instr->dest.saturate);
+ emit_conversion_from_double(dst, op[0]);
else
inst = emit(MOV(dst, op[0]));
break;
case nir_op_f2f64:
case nir_op_i2f64:
case nir_op_u2f64:
- emit_conversion_to_double(dst, op[0], instr->dest.saturate);
+ emit_conversion_to_double(dst, op[0]);
break;
case nir_op_fsat:
case nir_op_ineg:
op[0].negate = true;
inst = emit(MOV(dst, op[0]));
- if (instr->op == nir_op_fneg)
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fabs:
op[0].negate = false;
op[0].abs = true;
inst = emit(MOV(dst, op[0]));
- if (instr->op == nir_op_fabs)
- inst->saturate = instr->dest.saturate;
break;
case nir_op_iadd:
case nir_op_fadd:
try_immediate_source(instr, op, true, devinfo);
inst = emit(ADD(dst, op[0], op[1]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_uadd_sat:
case nir_op_fmul:
try_immediate_source(instr, op, true, devinfo);
inst = emit(MUL(dst, op[0], op[1]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_imul: {
case nir_op_frcp:
inst = emit_math(SHADER_OPCODE_RCP, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fexp2:
inst = emit_math(SHADER_OPCODE_EXP2, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_flog2:
inst = emit_math(SHADER_OPCODE_LOG2, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fsin:
inst = emit_math(SHADER_OPCODE_SIN, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fcos:
inst = emit_math(SHADER_OPCODE_COS, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_idiv:
case nir_op_fsqrt:
inst = emit_math(SHADER_OPCODE_SQRT, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_frsq:
inst = emit_math(SHADER_OPCODE_RSQ, dst, op[0]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fpow:
inst = emit_math(SHADER_OPCODE_POW, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_uadd_carry: {
inst->predicate = BRW_PREDICATE_NORMAL;
inst = emit(MOV(dst, src_reg(dst))); /* for potential saturation */
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fceil: {
emit(RNDD(dst_reg(tmp), op[0]));
tmp.negate = true;
inst = emit(MOV(dst, tmp));
- inst->saturate = instr->dest.saturate;
break;
}
case nir_op_ffloor:
inst = emit(RNDD(dst, op[0]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_ffract:
inst = emit(FRC(dst, op[0]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fround_even:
inst->predicate = BRW_PREDICATE_NORMAL;
inst = emit(MOV(dst, src_reg(dst))); /* for potential saturation */
}
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fquantize2f16: {
/* Select that or zero based on normal status */
inst = emit(BRW_OPCODE_SEL, dst, zero, tmp32);
inst->predicate = BRW_PREDICATE_NORMAL;
- inst->saturate = instr->dest.saturate;
break;
}
case nir_op_fmin:
try_immediate_source(instr, op, true, devinfo);
inst = emit_minmax(BRW_CONDITIONAL_L, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_imax:
case nir_op_fmax:
try_immediate_source(instr, op, true, devinfo);
inst = emit_minmax(BRW_CONDITIONAL_GE, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fddx:
case nir_op_b2f64:
if (nir_dest_bit_size(instr->dest.dest) > 32) {
assert(dst.type == BRW_REGISTER_TYPE_DF);
- emit_conversion_to_double(dst, negate(op[0]), false);
+ emit_conversion_to_double(dst, negate(op[0]));
} else {
emit(MOV(dst, negate(op[0])));
}
unreachable("not reached: should have been lowered");
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
/* Now convert the result from float to double */
emit_conversion_to_double(dst, retype(src_reg(tmp),
- BRW_REGISTER_TYPE_F),
- false);
+ BRW_REGISTER_TYPE_F));
}
break;
dst_reg mul_dst = dst_reg(this, glsl_type::dvec4_type);
emit(MUL(mul_dst, op[1], op[0]));
inst = emit(ADD(dst, src_reg(mul_dst), op[2]));
- inst->saturate = instr->dest.saturate;
} else {
fix_float_operands(op, instr);
inst = emit(MAD(dst, op[2], op[1], op[0]));
- inst->saturate = instr->dest.saturate;
}
break;
case nir_op_flrp:
fix_float_operands(op, instr);
inst = emit(LRP(dst, op[2], op[1], op[0]));
- inst->saturate = instr->dest.saturate;
break;
case nir_op_b32csel:
case nir_op_fdot_replicated2:
try_immediate_source(instr, op, true, devinfo);
inst = emit(BRW_OPCODE_DP2, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fdot_replicated3:
try_immediate_source(instr, op, true, devinfo);
inst = emit(BRW_OPCODE_DP3, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fdot_replicated4:
try_immediate_source(instr, op, true, devinfo);
inst = emit(BRW_OPCODE_DP4, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fdph_replicated:
try_immediate_source(instr, op, false, devinfo);
inst = emit(BRW_OPCODE_DPH, dst, op[0], op[1]);
- inst->saturate = instr->dest.saturate;
break;
case nir_op_fdiv: