+ /* 8: */ gen8_high, gen8_low, \
+ /* 12: */ gen12_high, gen12_low);
+
+/* Macro for fields that gained extra discontiguous MSBs in Gen12 (specified
+ * by hi12ex-lo12ex).
+ */
+#define FFDC(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
+ hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12, assertions) \
+static inline void \
+brw_inst_set_##name(const struct gen_device_info *devinfo, \
+ brw_inst *inst, uint64_t value) \
+{ \
+ assert(assertions); \
+ if (devinfo->gen >= 12) { \
+ const unsigned k = hi12 - lo12 + 1; \
+ if (hi12ex != -1 && lo12ex != -1) \
+ brw_inst_set_bits(inst, hi12ex, lo12ex, value >> k); \
+ brw_inst_set_bits(inst, hi12, lo12, value & ((1ull << k) - 1)); \
+ } else { \
+ BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
+ hi7, lo7, hi8, lo8, -1, -1); \
+ brw_inst_set_bits(inst, high, low, value); \
+ } \
+} \
+static inline uint64_t \
+brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \
+{ \
+ assert(assertions); \
+ if (devinfo->gen >= 12) { \
+ const unsigned k = hi12 - lo12 + 1; \
+ return (hi12ex == -1 || lo12ex == -1 ? 0 : \
+ brw_inst_bits(inst, hi12ex, lo12ex) << k) | \
+ brw_inst_bits(inst, hi12, lo12); \
+ } else { \
+ BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
+ hi7, lo7, hi8, lo8, -1, -1); \
+ return brw_inst_bits(inst, high, low); \
+ } \
+}
+
+#define FD(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
+ hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12) \
+ FFDC(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
+ hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12, true)
+
+/* Macro for fields that didn't move across generations until Gen12, and then
+ * gained extra discontiguous bits.
+ */
+#define FDC(name, hi4, lo4, hi12ex, lo12ex, hi12, lo12, assertions) \
+ FFDC(name, hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \
+ hi4, lo4, hi4, lo4, hi12ex, lo12ex, hi12, lo12, assertions)
+
+
+/* Macro for the 2-bit register file field, which on Gen12+ is stored as the
+ * variable length combination of an IsImm (hi12) bit and an additional file
+ * (lo12) bit.
+ */
+#define FI(name, hi4, lo4, hi8, lo8, hi12, lo12) \
+static inline void \
+brw_inst_set_##name(const struct gen_device_info *devinfo, \
+ brw_inst *inst, uint64_t value) \
+{ \
+ if (devinfo->gen >= 12) { \
+ brw_inst_set_bits(inst, hi12, hi12, value >> 1); \
+ if ((value >> 1) == 0) \
+ brw_inst_set_bits(inst, lo12, lo12, value & 1); \
+ } else { \
+ BOUNDS(hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \
+ hi4, lo4, hi8, lo8, -1, -1); \
+ brw_inst_set_bits(inst, high, low, value); \
+ } \
+} \
+static inline uint64_t \
+brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \
+{ \
+ if (devinfo->gen >= 12) { \
+ return (brw_inst_bits(inst, hi12, hi12) << 1) | \
+ (brw_inst_bits(inst, hi12, hi12) == 0 ? \
+ brw_inst_bits(inst, lo12, lo12) : 1); \
+ } else { \
+ BOUNDS(hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \
+ hi4, lo4, hi8, lo8, -1, -1); \
+ return brw_inst_bits(inst, high, low); \
+ } \
+}
+
+/* Macro for fields that become a constant in Gen12+ not actually represented
+ * in the instruction.
+ */
+#define FK(name, hi4, lo4, const12) \
+static inline void \
+brw_inst_set_##name(const struct gen_device_info *devinfo, \
+ brw_inst *inst, uint64_t v) \
+{ \
+ if (devinfo->gen >= 12) \
+ assert(v == (const12)); \
+ else \
+ brw_inst_set_bits(inst, hi4, lo4, v); \
+} \
+static inline uint64_t \
+brw_inst_##name(const struct gen_device_info *devinfo, \
+ const brw_inst *inst) \
+{ \
+ if (devinfo->gen >= 12) \
+ return (const12); \
+ else \
+ return brw_inst_bits(inst, hi4, lo4); \
+}
+
+F(src1_vstride, /* 4+ */ 120, 117, /* 12+ */ 119, 116)
+F(src1_width, /* 4+ */ 116, 114, /* 12+ */ 115, 113)
+F(src1_da16_swiz_w, /* 4+ */ 115, 114, /* 12+ */ -1, -1)
+F(src1_da16_swiz_z, /* 4+ */ 113, 112, /* 12+ */ -1, -1)
+F(src1_hstride, /* 4+ */ 113, 112, /* 12+ */ 97, 96)
+F(src1_address_mode, /* 4+ */ 111, 111, /* 12+ */ 112, 112)