- assert(src2.nr < 128);
- brw_inst_set_3src_a16_src2_swizzle(devinfo, inst, src2.swizzle);
- brw_inst_set_3src_a16_src2_subreg_nr(devinfo, inst, get_3src_subreg_nr(src2));
- brw_inst_set_3src_src2_reg_nr(devinfo, inst, src2.nr);
- brw_inst_set_3src_src2_abs(devinfo, inst, src2.abs);
- brw_inst_set_3src_src2_negate(devinfo, inst, src2.negate);
- brw_inst_set_3src_a16_src2_rep_ctrl(devinfo, inst,
- src2.vstride == BRW_VERTICAL_STRIDE_0);
-
- if (devinfo->gen >= 7) {
- /* Set both the source and destination types based on dest.type,
- * ignoring the source register types. The MAD and LRP emitters ensure
- * that all four types are float. The BFE and BFI2 emitters, however,
- * may send us mixed D and UD types and want us to ignore that and use
- * the destination type.
- */
- switch (dest.type) {
- case BRW_REGISTER_TYPE_F:
- brw_inst_set_3src_a16_src_hw_type(devinfo, inst, BRW_3SRC_TYPE_F);
- brw_inst_set_3src_a16_dst_hw_type(devinfo, inst, BRW_3SRC_TYPE_F);
- break;
- case BRW_REGISTER_TYPE_DF:
- brw_inst_set_3src_a16_src_hw_type(devinfo, inst, BRW_3SRC_TYPE_DF);
- brw_inst_set_3src_a16_dst_hw_type(devinfo, inst, BRW_3SRC_TYPE_DF);
- break;
- case BRW_REGISTER_TYPE_D:
- brw_inst_set_3src_a16_src_hw_type(devinfo, inst, BRW_3SRC_TYPE_D);
- brw_inst_set_3src_a16_dst_hw_type(devinfo, inst, BRW_3SRC_TYPE_D);
- break;
- case BRW_REGISTER_TYPE_UD:
- brw_inst_set_3src_a16_src_hw_type(devinfo, inst, BRW_3SRC_TYPE_UD);
- brw_inst_set_3src_a16_dst_hw_type(devinfo, inst, BRW_3SRC_TYPE_UD);
- break;
- default:
- unreachable("not reached");
+
+ if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
+ assert(dest.file == BRW_GENERAL_REGISTER_FILE ||
+ dest.file == BRW_ARCHITECTURE_REGISTER_FILE);
+
+ if (devinfo->gen >= 12) {
+ brw_inst_set_3src_a1_dst_reg_file(devinfo, inst, dest.file);
+ brw_inst_set_3src_dst_reg_nr(devinfo, inst, dest.nr);
+ } else {
+ if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE) {
+ brw_inst_set_3src_a1_dst_reg_file(devinfo, inst,
+ BRW_ALIGN1_3SRC_ACCUMULATOR);
+ brw_inst_set_3src_dst_reg_nr(devinfo, inst, BRW_ARF_ACCUMULATOR);
+ } else {
+ brw_inst_set_3src_a1_dst_reg_file(devinfo, inst,
+ BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE);
+ brw_inst_set_3src_dst_reg_nr(devinfo, inst, dest.nr);
+ }
+ }
+ brw_inst_set_3src_a1_dst_subreg_nr(devinfo, inst, dest.subnr / 8);
+
+ brw_inst_set_3src_a1_dst_hstride(devinfo, inst, BRW_ALIGN1_3SRC_DST_HORIZONTAL_STRIDE_1);
+
+ if (brw_reg_type_is_floating_point(dest.type)) {
+ brw_inst_set_3src_a1_exec_type(devinfo, inst,
+ BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT);
+ } else {
+ brw_inst_set_3src_a1_exec_type(devinfo, inst,
+ BRW_ALIGN1_3SRC_EXEC_TYPE_INT);
+ }
+
+ brw_inst_set_3src_a1_dst_type(devinfo, inst, dest.type);
+ brw_inst_set_3src_a1_src0_type(devinfo, inst, src0.type);
+ brw_inst_set_3src_a1_src1_type(devinfo, inst, src1.type);
+ brw_inst_set_3src_a1_src2_type(devinfo, inst, src2.type);
+
+ if (src0.file == BRW_IMMEDIATE_VALUE) {
+ brw_inst_set_3src_a1_src0_imm(devinfo, inst, src0.ud);
+ } else {
+ brw_inst_set_3src_a1_src0_vstride(
+ devinfo, inst, to_3src_align1_vstride(devinfo, src0.vstride));
+ brw_inst_set_3src_a1_src0_hstride(devinfo, inst,
+ to_3src_align1_hstride(src0.hstride));
+ brw_inst_set_3src_a1_src0_subreg_nr(devinfo, inst, src0.subnr);
+ if (src0.type == BRW_REGISTER_TYPE_NF) {
+ brw_inst_set_3src_src0_reg_nr(devinfo, inst, BRW_ARF_ACCUMULATOR);
+ } else {
+ brw_inst_set_3src_src0_reg_nr(devinfo, inst, src0.nr);
+ }
+ brw_inst_set_3src_src0_abs(devinfo, inst, src0.abs);
+ brw_inst_set_3src_src0_negate(devinfo, inst, src0.negate);
+ }
+ brw_inst_set_3src_a1_src1_vstride(
+ devinfo, inst, to_3src_align1_vstride(devinfo, src1.vstride));
+ brw_inst_set_3src_a1_src1_hstride(devinfo, inst,
+ to_3src_align1_hstride(src1.hstride));
+
+ brw_inst_set_3src_a1_src1_subreg_nr(devinfo, inst, src1.subnr);
+ if (src1.file == BRW_ARCHITECTURE_REGISTER_FILE) {
+ brw_inst_set_3src_src1_reg_nr(devinfo, inst, BRW_ARF_ACCUMULATOR);
+ } else {
+ brw_inst_set_3src_src1_reg_nr(devinfo, inst, src1.nr);
+ }
+ brw_inst_set_3src_src1_abs(devinfo, inst, src1.abs);
+ brw_inst_set_3src_src1_negate(devinfo, inst, src1.negate);
+
+ if (src2.file == BRW_IMMEDIATE_VALUE) {
+ brw_inst_set_3src_a1_src2_imm(devinfo, inst, src2.ud);
+ } else {
+ brw_inst_set_3src_a1_src2_hstride(devinfo, inst,
+ to_3src_align1_hstride(src2.hstride));
+ /* no vstride on src2 */
+ brw_inst_set_3src_a1_src2_subreg_nr(devinfo, inst, src2.subnr);
+ brw_inst_set_3src_src2_reg_nr(devinfo, inst, src2.nr);
+ brw_inst_set_3src_src2_abs(devinfo, inst, src2.abs);
+ brw_inst_set_3src_src2_negate(devinfo, inst, src2.negate);
+ }
+
+ assert(src0.file == BRW_GENERAL_REGISTER_FILE ||
+ src0.file == BRW_IMMEDIATE_VALUE ||
+ (src0.file == BRW_ARCHITECTURE_REGISTER_FILE &&
+ src0.type == BRW_REGISTER_TYPE_NF));
+ assert(src1.file == BRW_GENERAL_REGISTER_FILE ||
+ src1.file == BRW_ARCHITECTURE_REGISTER_FILE);
+ assert(src2.file == BRW_GENERAL_REGISTER_FILE ||
+ src2.file == BRW_IMMEDIATE_VALUE);
+
+ if (devinfo->gen >= 12) {
+ if (src0.file == BRW_IMMEDIATE_VALUE) {
+ brw_inst_set_3src_a1_src0_is_imm(devinfo, inst, 1);
+ } else {
+ brw_inst_set_3src_a1_src0_reg_file(devinfo, inst, src0.file);
+ }
+
+ brw_inst_set_3src_a1_src1_reg_file(devinfo, inst, src1.file);
+
+ if (src2.file == BRW_IMMEDIATE_VALUE) {
+ brw_inst_set_3src_a1_src2_is_imm(devinfo, inst, 1);
+ } else {
+ brw_inst_set_3src_a1_src2_reg_file(devinfo, inst, src2.file);
+ }
+ } else {
+ brw_inst_set_3src_a1_src0_reg_file(devinfo, inst,
+ src0.file == BRW_GENERAL_REGISTER_FILE ?
+ BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE :
+ BRW_ALIGN1_3SRC_IMMEDIATE_VALUE);
+ brw_inst_set_3src_a1_src1_reg_file(devinfo, inst,
+ src1.file == BRW_GENERAL_REGISTER_FILE ?
+ BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE :
+ BRW_ALIGN1_3SRC_ACCUMULATOR);
+ brw_inst_set_3src_a1_src2_reg_file(devinfo, inst,
+ src2.file == BRW_GENERAL_REGISTER_FILE ?
+ BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE :
+ BRW_ALIGN1_3SRC_IMMEDIATE_VALUE);
+ }
+
+ } else {
+ assert(dest.file == BRW_GENERAL_REGISTER_FILE ||
+ dest.file == BRW_MESSAGE_REGISTER_FILE);
+ assert(dest.type == BRW_REGISTER_TYPE_F ||
+ dest.type == BRW_REGISTER_TYPE_DF ||
+ dest.type == BRW_REGISTER_TYPE_D ||
+ dest.type == BRW_REGISTER_TYPE_UD ||
+ (dest.type == BRW_REGISTER_TYPE_HF && devinfo->gen >= 8));
+ if (devinfo->gen == 6) {
+ brw_inst_set_3src_a16_dst_reg_file(devinfo, inst,
+ dest.file == BRW_MESSAGE_REGISTER_FILE);
+ }
+ brw_inst_set_3src_dst_reg_nr(devinfo, inst, dest.nr);
+ brw_inst_set_3src_a16_dst_subreg_nr(devinfo, inst, dest.subnr / 4);
+ brw_inst_set_3src_a16_dst_writemask(devinfo, inst, dest.writemask);
+
+ assert(src0.file == BRW_GENERAL_REGISTER_FILE);
+ brw_inst_set_3src_a16_src0_swizzle(devinfo, inst, src0.swizzle);
+ brw_inst_set_3src_a16_src0_subreg_nr(devinfo, inst, get_3src_subreg_nr(src0));
+ brw_inst_set_3src_src0_reg_nr(devinfo, inst, src0.nr);
+ brw_inst_set_3src_src0_abs(devinfo, inst, src0.abs);
+ brw_inst_set_3src_src0_negate(devinfo, inst, src0.negate);
+ brw_inst_set_3src_a16_src0_rep_ctrl(devinfo, inst,
+ src0.vstride == BRW_VERTICAL_STRIDE_0);
+
+ assert(src1.file == BRW_GENERAL_REGISTER_FILE);
+ brw_inst_set_3src_a16_src1_swizzle(devinfo, inst, src1.swizzle);
+ brw_inst_set_3src_a16_src1_subreg_nr(devinfo, inst, get_3src_subreg_nr(src1));
+ brw_inst_set_3src_src1_reg_nr(devinfo, inst, src1.nr);
+ brw_inst_set_3src_src1_abs(devinfo, inst, src1.abs);
+ brw_inst_set_3src_src1_negate(devinfo, inst, src1.negate);
+ brw_inst_set_3src_a16_src1_rep_ctrl(devinfo, inst,
+ src1.vstride == BRW_VERTICAL_STRIDE_0);
+
+ assert(src2.file == BRW_GENERAL_REGISTER_FILE);
+ brw_inst_set_3src_a16_src2_swizzle(devinfo, inst, src2.swizzle);
+ brw_inst_set_3src_a16_src2_subreg_nr(devinfo, inst, get_3src_subreg_nr(src2));
+ brw_inst_set_3src_src2_reg_nr(devinfo, inst, src2.nr);
+ brw_inst_set_3src_src2_abs(devinfo, inst, src2.abs);
+ brw_inst_set_3src_src2_negate(devinfo, inst, src2.negate);
+ brw_inst_set_3src_a16_src2_rep_ctrl(devinfo, inst,
+ src2.vstride == BRW_VERTICAL_STRIDE_0);
+
+ if (devinfo->gen >= 7) {
+ /* Set both the source and destination types based on dest.type,
+ * ignoring the source register types. The MAD and LRP emitters ensure
+ * that all four types are float. The BFE and BFI2 emitters, however,
+ * may send us mixed D and UD types and want us to ignore that and use
+ * the destination type.
+ */
+ brw_inst_set_3src_a16_src_type(devinfo, inst, dest.type);
+ brw_inst_set_3src_a16_dst_type(devinfo, inst, dest.type);
+
+ /* From the Bspec, 3D Media GPGPU, Instruction fields, srcType:
+ *
+ * "Three source instructions can use operands with mixed-mode
+ * precision. When SrcType field is set to :f or :hf it defines
+ * precision for source 0 only, and fields Src1Type and Src2Type
+ * define precision for other source operands:
+ *
+ * 0b = :f. Single precision Float (32-bit).
+ * 1b = :hf. Half precision Float (16-bit)."
+ */
+ if (src1.type == BRW_REGISTER_TYPE_HF)
+ brw_inst_set_3src_a16_src1_type(devinfo, inst, 1);
+
+ if (src2.type == BRW_REGISTER_TYPE_HF)
+ brw_inst_set_3src_a16_src2_type(devinfo, inst, 1);