+typedef struct {
+ uint64_t data;
+} brw_compact_inst;
+
+/**
+ * Fetch a set of contiguous bits from the compacted instruction.
+ *
+ * Bits indices range from 0..63.
+ */
+static inline unsigned
+brw_compact_inst_bits(const brw_compact_inst *inst, unsigned high, unsigned low)
+{
+ const uint64_t mask = (1ull << (high - low + 1)) - 1;
+
+ return (inst->data >> low) & mask;
+}
+
+/**
+ * Set bits in the compacted instruction.
+ *
+ * Bits indices range from 0..63.
+ */
+static inline void
+brw_compact_inst_set_bits(brw_compact_inst *inst, unsigned high, unsigned low,
+ uint64_t value)
+{
+ const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low;
+
+ /* Make sure the supplied value actually fits in the given bitfield. */
+ assert((value & (mask >> low)) == value);
+
+ inst->data = (inst->data & ~mask) | (value << low);
+}
+
+#define FC(name, high, low, assertions) \
+static inline void \
+brw_compact_inst_set_##name(const struct gen_device_info *devinfo, \
+ brw_compact_inst *inst, unsigned v) \
+{ \
+ assert(assertions); \
+ (void) devinfo; \
+ brw_compact_inst_set_bits(inst, high, low, v); \
+} \
+static inline unsigned \
+brw_compact_inst_##name(const struct gen_device_info *devinfo, \
+ const brw_compact_inst *inst) \
+{ \
+ assert(assertions); \
+ (void) devinfo; \
+ return brw_compact_inst_bits(inst, high, low); \
+}
+
+/* A simple macro for fields which stay in the same place on all generations. */
+#define F(name, high, low) FC(name, high, low, true)
+
+F(src1_reg_nr, 63, 56)
+F(src0_reg_nr, 55, 48)
+F(dst_reg_nr, 47, 40)
+F(src1_index, 39, 35)
+F(src0_index, 34, 30)
+F(cmpt_control, 29, 29) /* Same location as brw_inst */
+FC(flag_subreg_nr, 28, 28, devinfo->gen <= 6)
+F(cond_modifier, 27, 24) /* Same location as brw_inst */
+FC(acc_wr_control, 23, 23, devinfo->gen >= 6)
+FC(mask_control_ex, 23, 23, devinfo->is_g4x || devinfo->gen == 5)
+F(subreg_index, 22, 18)
+F(datatype_index, 17, 13)
+F(control_index, 12, 8)
+F(debug_control, 7, 7)
+F(opcode, 6, 0) /* Same location as brw_inst */
+
+/**
+ * (Gen8+) Compacted three-source instructions:
+ * @{
+ */
+FC(3src_src2_reg_nr, 63, 57, devinfo->gen >= 8)
+FC(3src_src1_reg_nr, 56, 50, devinfo->gen >= 8)
+FC(3src_src0_reg_nr, 49, 43, devinfo->gen >= 8)
+FC(3src_src2_subreg_nr, 42, 40, devinfo->gen >= 8)
+FC(3src_src1_subreg_nr, 39, 37, devinfo->gen >= 8)
+FC(3src_src0_subreg_nr, 36, 34, devinfo->gen >= 8)
+FC(3src_src2_rep_ctrl, 33, 33, devinfo->gen >= 8)
+FC(3src_src1_rep_ctrl, 32, 32, devinfo->gen >= 8)
+FC(3src_saturate, 31, 31, devinfo->gen >= 8)
+FC(3src_debug_control, 30, 30, devinfo->gen >= 8)
+FC(3src_cmpt_control, 29, 29, devinfo->gen >= 8)
+FC(3src_src0_rep_ctrl, 28, 28, devinfo->gen >= 8)
+/* Reserved */
+FC(3src_dst_reg_nr, 18, 12, devinfo->gen >= 8)
+FC(3src_source_index, 11, 10, devinfo->gen >= 8)
+FC(3src_control_index, 9, 8, devinfo->gen >= 8)
+/* Bit 7 is Reserved (for future Opcode expansion) */
+FC(3src_opcode, 6, 0, devinfo->gen >= 8)
+/** @} */
+
+#undef F
+