summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2018-05-29 13:45:57 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2018-06-04 14:03:03 -0700
commit2d20303e1874a862117f526ee87789b00b049078 (patch)
tree9b6df0fd25926b7f1d41be3c498e2c787993d601
parent381fac274054784e4cbd152168653aecb9f1e5dd (diff)
downloadmesa-2d20303e1874a862117f526ee87789b00b049078.tar.gz
mesa-2d20303e1874a862117f526ee87789b00b049078.tar.xz
intel/eu: Copy fields manually in brw_next_insn
Instead of doing a memcpy, this moves us to start with a blank instruction (memset to zero) and copy the fields over one at a time. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/intel/compiler/brw_eu_emit.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c
index 80eea9ecba..a660d9eaaa 100644
--- a/src/intel/compiler/brw_eu_emit.c
+++ b/src/intel/compiler/brw_eu_emit.c
@@ -621,6 +621,94 @@ gen7_set_dp_scratch_message(struct brw_codegen *p,
brw_inst_set_scratch_addr_offset(devinfo, inst, addr_offset);
}
+struct brw_insn_state {
+ /* One of BRW_EXECUTE_* */
+ unsigned exec_size:3;
+
+ /* Group in units of channels */
+ unsigned group:5;
+
+ /* Compression control on gen4-5 */
+ bool compressed:1;
+
+ /* One of BRW_MASK_* */
+ unsigned mask_control:1;
+
+ bool saturate:1;
+
+ /* One of BRW_ALIGN_* */
+ unsigned access_mode:1;
+
+ /* One of BRW_PREDICATE_* */
+ enum brw_predicate predicate:4;
+
+ bool pred_inv:1;
+
+ /* Flag subreg. Bottom bit is subreg, top bit is reg */
+ unsigned flag_subreg:2;
+
+ bool acc_wr_control:1;
+};
+
+static struct brw_insn_state
+brw_inst_get_state(const struct gen_device_info *devinfo,
+ const brw_inst *insn)
+{
+ struct brw_insn_state state = { };
+
+ state.exec_size = brw_inst_exec_size(devinfo, insn);
+ if (devinfo->gen >= 6) {
+ state.group = brw_inst_qtr_control(devinfo, insn) * 8;
+ if (devinfo->gen >= 7)
+ state.group += brw_inst_nib_control(devinfo, insn) * 4;
+ } else {
+ unsigned qtr_control = brw_inst_qtr_control(devinfo, insn);
+ if (qtr_control == BRW_COMPRESSION_COMPRESSED) {
+ state.group = 0;
+ state.compressed = true;
+ } else {
+ state.group = qtr_control * 8;
+ state.compressed = false;
+ }
+ }
+ state.access_mode = brw_inst_access_mode(devinfo, insn);
+ state.mask_control = brw_inst_mask_control(devinfo, insn);
+ state.saturate = brw_inst_saturate(devinfo, insn);
+ state.predicate = brw_inst_pred_control(devinfo, insn);
+ state.pred_inv = brw_inst_pred_inv(devinfo, insn);
+
+ state.flag_subreg = brw_inst_flag_subreg_nr(devinfo, insn);
+ if (devinfo->gen >= 7)
+ state.flag_subreg += brw_inst_flag_reg_nr(devinfo, insn) * 2;
+
+ if (devinfo->gen >= 6)
+ state.acc_wr_control = brw_inst_acc_wr_control(devinfo, insn);
+
+ return state;
+}
+
+static void
+brw_inst_set_state(const struct gen_device_info *devinfo,
+ brw_inst *insn,
+ const struct brw_insn_state *state)
+{
+ brw_inst_set_exec_size(devinfo, insn, state->exec_size);
+ brw_inst_set_group(devinfo, insn, state->group);
+ brw_inst_set_compression(devinfo, insn, state->compressed);
+ brw_inst_set_access_mode(devinfo, insn, state->access_mode);
+ brw_inst_set_mask_control(devinfo, insn, state->mask_control);
+ brw_inst_set_saturate(devinfo, insn, state->saturate);
+ brw_inst_set_pred_control(devinfo, insn, state->predicate);
+ brw_inst_set_pred_inv(devinfo, insn, state->pred_inv);
+
+ brw_inst_set_flag_subreg_nr(devinfo, insn, state->flag_subreg % 2);
+ if (devinfo->gen >= 7)
+ brw_inst_set_flag_reg_nr(devinfo, insn, state->flag_subreg / 2);
+
+ if (devinfo->gen >= 6)
+ brw_inst_set_acc_wr_control(devinfo, insn, state->acc_wr_control);
+}
+
#define next_insn brw_next_insn
brw_inst *
brw_next_insn(struct brw_codegen *p, unsigned opcode)
@@ -635,9 +723,14 @@ brw_next_insn(struct brw_codegen *p, unsigned opcode)
p->next_insn_offset += 16;
insn = &p->store[p->nr_insn++];
- memcpy(insn, p->current, sizeof(*insn));
+ memset(insn, 0, sizeof(*insn));
brw_inst_set_opcode(devinfo, insn, opcode);
+
+ /* Apply the default instruction state */
+ struct brw_insn_state current = brw_inst_get_state(devinfo, p->current);
+ brw_inst_set_state(devinfo, insn, &current);
+
return insn;
}