• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /**
25  * @file
26  *
27  * A representation of i965 EU assembly instructions, with helper methods to
28  * get and set various fields.  This is the actual hardware format.
29  */
30 
31 #pragma once
32 
33 #include <assert.h>
34 #include <stdint.h>
35 
36 #include "brw_eu_defines.h"
37 #include "brw_isa_info.h"
38 #include "brw_reg_type.h"
39 #include "dev/intel_device_info.h"
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /* brw_context.h has a forward declaration of brw_eu_inst, so name the struct. */
46 typedef struct brw_eu_inst {
47    uint64_t data[2];
48 } brw_eu_inst;
49 
50 static inline uint64_t brw_eu_inst_bits(const brw_eu_inst *inst,
51                                         unsigned high, unsigned low);
52 static inline void brw_eu_inst_set_bits(brw_eu_inst *inst,
53                                         unsigned high, unsigned low,
54                                         uint64_t value);
55 
56 #define FC(name, hi9, lo9, hi12, lo12, assertions)            \
57 static inline void                                            \
58 brw_eu_inst_set_##name(const struct intel_device_info *devinfo,  \
59                        brw_eu_inst *inst, uint64_t v)         \
60 {                                                             \
61    assert(assertions);                                        \
62    if (devinfo->ver >= 12)                                    \
63       brw_eu_inst_set_bits(inst, hi12, lo12, v);              \
64    else                                                       \
65       brw_eu_inst_set_bits(inst, hi9, lo9, v);                \
66 }                                                             \
67 static inline uint64_t                                        \
68 brw_eu_inst_##name(const struct intel_device_info *devinfo,   \
69                    const brw_eu_inst *inst)                   \
70 {                                                             \
71    assert(assertions);                                        \
72    if (devinfo->ver >= 12)                                    \
73       return brw_eu_inst_bits(inst, hi12, lo12);              \
74    else                                                       \
75       return brw_eu_inst_bits(inst, hi9, lo9);                \
76 }
77 
78 /* A simple macro for fields which stay in the same place on all generations,
79  * except for Gfx12!
80  */
81 #define F(name, hi9, lo9, hi12, lo12) FC(name, hi9, lo9, hi12, lo12, true)
82 
83 /* A simple macro for fields which stay in the same place on all generations,
84  * except for Gfx12 and Gfx20.
85  */
86 #define F20(name, hi9, lo9, hi12, lo12, hi20, lo20)                \
87    static inline void                                              \
88    brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
89                           brw_eu_inst *inst, uint64_t v)           \
90    {                                                               \
91       if (devinfo->ver >= 20)                                      \
92          brw_eu_inst_set_bits(inst, hi20, lo20, v);                \
93       else if (devinfo->ver >= 12)                                 \
94          brw_eu_inst_set_bits(inst, hi12, lo12, v);                \
95       else                                                         \
96          brw_eu_inst_set_bits(inst, hi9, lo9, v);                  \
97    }                                                               \
98    static inline uint64_t                                          \
99    brw_eu_inst_##name(const struct intel_device_info *devinfo,     \
100                       const brw_eu_inst *inst)                     \
101    {                                                               \
102       if (devinfo->ver >= 20)                                      \
103          return brw_eu_inst_bits(inst, hi20, lo20);                \
104       else if (devinfo->ver >= 12)                                 \
105          return brw_eu_inst_bits(inst, hi12, lo12);                \
106       else                                                         \
107          return brw_eu_inst_bits(inst, hi9, lo9);                  \
108    }
109 
110 #define FV20(name, hi9, lo9, hi12, lo12, hi20, lo20)               \
111    static inline void                                              \
112    brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
113                           brw_eu_inst *inst, uint64_t v)           \
114    {                                                               \
115       if (devinfo->ver >= 20)                                      \
116          brw_eu_inst_set_bits(inst, hi20, lo20, v & 0x7);          \
117       else if (devinfo->ver >= 12)                                 \
118          brw_eu_inst_set_bits(inst, hi12, lo12, v);                \
119       else                                                         \
120          brw_eu_inst_set_bits(inst, hi9, lo9, v);                  \
121    }                                                               \
122    static inline uint64_t                                          \
123    brw_eu_inst_##name(const struct intel_device_info *devinfo,     \
124                       const brw_eu_inst *inst)                     \
125    {                                                               \
126       if (devinfo->ver >= 20)                                      \
127          return brw_eu_inst_bits(inst, hi20, lo20) == 0x7 ? 0xF :  \
128                 brw_eu_inst_bits(inst, hi20, lo20);                \
129       else if (devinfo->ver >= 12)                                 \
130          return brw_eu_inst_bits(inst, hi12, lo12);                \
131       else                                                         \
132          return brw_eu_inst_bits(inst, hi9, lo9);                  \
133    }
134 
135 #define FD20(name, hi9, lo9, hi12, lo12, hi20, lo20, zero20)       \
136    static inline void                                              \
137    brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
138                           brw_eu_inst *inst, uint64_t v)           \
139    {                                                               \
140       if (devinfo->ver >= 20) {                                    \
141          brw_eu_inst_set_bits(inst, hi20, lo20, v >> 1);           \
142          if (zero20 == -1)                                         \
143             assert((v & 1) == 0);                                  \
144          else                                                      \
145             brw_eu_inst_set_bits(inst, zero20, zero20, v & 1);     \
146       } else if (devinfo->ver >= 12)                               \
147          brw_eu_inst_set_bits(inst, hi12, lo12, v);                \
148       else                                                         \
149          brw_eu_inst_set_bits(inst, hi9, lo9, v);                  \
150    }                                                               \
151    static inline uint64_t                                          \
152    brw_eu_inst_##name(const struct intel_device_info *devinfo,     \
153                       const brw_eu_inst *inst)                     \
154    {                                                               \
155       if (devinfo->ver >= 20)                                      \
156          return (brw_eu_inst_bits(inst, hi20, lo20) << 1) |        \
157                 (zero20 == -1 ? 0 :                                \
158                  brw_eu_inst_bits(inst, zero20, zero20));          \
159       else if (devinfo->ver >= 12)                                 \
160          return brw_eu_inst_bits(inst, hi12, lo12);                \
161       else                                                         \
162          return brw_eu_inst_bits(inst, hi9, lo9);                  \
163    }
164 
165 /* Macro for fields that gained extra discontiguous MSBs in Gfx12 (specified
166  * by hi12ex-lo12ex).
167  */
168 #define FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions)          \
169 static inline void                                                            \
170 brw_eu_inst_set_##name(const struct intel_device_info *devinfo,               \
171                        brw_eu_inst *inst, uint64_t value)                     \
172 {                                                                             \
173    assert(assertions);                                                        \
174    if (devinfo->ver >= 12) {                                                  \
175       const unsigned k = hi12 - lo12 + 1;                                     \
176       if (hi12ex != -1 && lo12ex != -1)                                       \
177          brw_eu_inst_set_bits(inst, hi12ex, lo12ex, value >> k);              \
178       brw_eu_inst_set_bits(inst, hi12, lo12, value & ((1ull << k) - 1));      \
179    } else {                                                                   \
180       brw_eu_inst_set_bits(inst, hi9, lo9, value);                            \
181    }                                                                          \
182 }                                                                             \
183 static inline uint64_t                                                        \
184 brw_eu_inst_##name(const struct intel_device_info *devinfo,                   \
185                    const brw_eu_inst *inst)                                   \
186 {                                                                             \
187    assert(assertions);                                                        \
188    if (devinfo->ver >= 12) {                                                  \
189       const unsigned k = hi12 - lo12 + 1;                                     \
190       return (hi12ex == -1 || lo12ex == -1 ? 0 :                              \
191               brw_eu_inst_bits(inst, hi12ex, lo12ex) << k) |                  \
192              brw_eu_inst_bits(inst, hi12, lo12);                              \
193    } else {                                                                   \
194       return brw_eu_inst_bits(inst, hi9, lo9);                                \
195    }                                                                          \
196 }
197 
198 #define FD(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12)            \
199    FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, true)
200 
201 /* Macro for fields that didn't move across generations until Gfx12, and then
202  * gained extra discontiguous bits.
203  */
204 #define FDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions)     \
205    FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions)
206 
207 static inline uint64_t
brw_reg_file_to_hw_reg_file(enum brw_reg_file file)208 brw_reg_file_to_hw_reg_file(enum brw_reg_file file)
209 {
210    switch (file) {
211    case ARF:       return 0x0;
212    case FIXED_GRF: return 0x1;
213    default:        /* Fallthrough. */
214    case IMM:       return 0x3;
215    }
216 }
217 
218 static inline enum brw_reg_file
hw_reg_file_to_brw_reg_file(uint64_t v)219 hw_reg_file_to_brw_reg_file(uint64_t v)
220 {
221    switch (v) {
222    case 0x0: return ARF;
223    case 0x1: return FIXED_GRF;
224    default:  return IMM;
225    }
226 }
227 
228 /* Macro for storing register file field.  See variant FF below for no
229  * assertions.
230  *
231  * In Gfx12+, either a single bit is available (ARF or GRF) or two bits are
232  * available.  In that case the register file is stored as the variable length
233  * combination of an IsImm (hi12) bit and an additional file (lo12) bit.
234  *
235  * For some instructions in Gfx11, the encoding uses 0 for GRF, and 1 for
236  * either ARF (for accumulator) or IMM.
237  */
238 #define FFC(name, hi9, lo9, hi12, lo12, assertions, ...)                      \
239 static inline void                                                            \
240 brw_eu_inst_set_##name(const struct intel_device_info *devinfo,               \
241                        brw_eu_inst *inst, enum brw_reg_file file)             \
242 {                                                                             \
243    assert(assertions);                                                        \
244    const struct {                                                             \
245       bool _;  /* Exists to avoid empty initializer. */                       \
246       bool grf_or_imm;                                                        \
247       bool grf_or_acc;                                                        \
248    } args = { ._ = false, __VA_ARGS__ };                                      \
249    uint64_t value = brw_reg_file_to_hw_reg_file(file);                        \
250    if (devinfo->ver < 12) {                                                   \
251       if (devinfo->ver == 11 && args.grf_or_imm) {                            \
252          assert(file == FIXED_GRF || file == IMM);                            \
253          value = file == FIXED_GRF ? 0 : 1;                                   \
254       } else if (devinfo->ver == 11 && args.grf_or_acc) {                     \
255          assert(file == FIXED_GRF || file == ARF);                            \
256          value = file == FIXED_GRF ? 0 : 1;                                   \
257       }                                                                       \
258       brw_eu_inst_set_bits(inst, hi9, lo9, value);                            \
259    } else if (hi12 == lo12) {                                                 \
260       brw_eu_inst_set_bits(inst, hi12, lo12, value);                          \
261    } else {                                                                   \
262       brw_eu_inst_set_bits(inst, hi12, hi12, value >> 1);                     \
263       if ((value >> 1) == 0)                                                  \
264          brw_eu_inst_set_bits(inst, lo12, lo12, value & 1);                   \
265    }                                                                          \
266 }                                                                             \
267 static inline uint64_t                                                        \
268 brw_eu_inst_##name(const struct intel_device_info *devinfo,                   \
269                    const brw_eu_inst *inst)                                   \
270 {                                                                             \
271    assert(assertions);                                                        \
272    const struct {                                                             \
273       bool _;  /* Exists to avoid empty initializer. */                       \
274       bool grf_or_imm;                                                        \
275       bool grf_or_acc;                                                        \
276    } args = { ._ = false, __VA_ARGS__ };                                      \
277    uint64_t value;                                                            \
278    if (devinfo->ver < 12) {                                                   \
279       value = brw_eu_inst_bits(inst, hi9, lo9);                               \
280       if (devinfo->ver == 11 && args.grf_or_imm)                              \
281          return value ? IMM : FIXED_GRF;                                      \
282       else if (devinfo->ver == 11 && args.grf_or_acc)                         \
283          return value ? ARF : FIXED_GRF;                                      \
284    } else if (hi12 == lo12) {                                                 \
285       value = brw_eu_inst_bits(inst, hi12, lo12);                             \
286    } else {                                                                   \
287       value = (brw_eu_inst_bits(inst, hi12, hi12) << 1) |                     \
288               (brw_eu_inst_bits(inst, hi12, hi12) == 0 ?                      \
289                brw_eu_inst_bits(inst, lo12, lo12) : 1);                       \
290    }                                                                          \
291    return hw_reg_file_to_brw_reg_file(value);                                 \
292 }
293 
294 #define FF(name, hi9, lo9, hi12, lo12, ...) FFC(name, hi9, lo9, hi12, lo12, true, __VA_ARGS__)
295 
296 /* Macro for fields that become a constant in Gfx12+ not actually represented
297  * in the instruction.
298  */
299 #define FK(name, hi9, lo9, const12)                           \
300 static inline void                                            \
301 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
302                        brw_eu_inst *inst, uint64_t v)         \
303 {                                                             \
304    if (devinfo->ver >= 12)                                    \
305       assert(v == (const12));                                 \
306    else                                                       \
307       brw_eu_inst_set_bits(inst, hi9, lo9, v);                \
308 }                                                             \
309 static inline uint64_t                                        \
310 brw_eu_inst_##name(const struct intel_device_info *devinfo,   \
311                    const brw_eu_inst *inst)                   \
312 {                                                             \
313    if (devinfo->ver >= 12)                                    \
314       return (const12);                                       \
315    else                                                       \
316       return brw_eu_inst_bits(inst, hi9, lo9);                \
317 }
318 
319 FV20(src1_vstride,     /* 9+ */ 120, 117, /* 12+ */ 119, 116, /* 20+ */ 118, 116)
320 F(src1_width,          /* 9+ */ 116, 114, /* 12+ */ 115, 113)
321 F(src1_da16_swiz_w,    /* 9+ */ 115, 114, /* 12+ */ -1, -1)
322 F(src1_da16_swiz_z,    /* 9+ */ 113, 112, /* 12+ */ -1, -1)
323 F(src1_hstride,        /* 9+ */ 113, 112, /* 12+ */ 97, 96)
324 F(src1_address_mode,   /* 9+ */ 111, 111, /* 12+ */ 112, 112)
325 /** Src1.SrcMod @{ */
326 F(src1_negate,         /* 9+ */ 110, 110, /* 12+ */ 121, 121)
327 F(src1_abs,            /* 9+ */ 109, 109, /* 12+ */ 120, 120)
328 /** @} */
329 F(src1_ia_subreg_nr,   /* 9+ */ 108, 105, /* 12+ */ 111, 108)
330 F(src1_da_reg_nr,      /* 9+ */ 108, 101, /* 12+ */ 111, 104)
331 F(src1_da16_subreg_nr, /* 9+ */ 100, 100, /* 12+ */ -1, -1)
332 FD20(src1_da1_subreg_nr, /* 9+ */ 100, 96, /* 12+ */ 103, 99, /* 20+ */ 103, 99, -1)
333 F(src1_da16_swiz_y,    /* 9+ */ 99,  98,  /* 12+ */ -1, -1)
334 F(src1_da16_swiz_x,    /* 9+ */ 97,  96,  /* 12+ */ -1, -1)
335 F(src1_reg_hw_type,    /* 9+ */ 94,  91,  /* 12+ */ 91, 88)
336 FF(src1_reg_file,      /* 9+ */ 90,  89,  /* 12+ */ 47, 98)
337 F(src1_is_imm,         /* 9+ */ -1,  -1,  /* 12+ */ 47, 47)
338 FV20(src0_vstride,     /* 9+ */ 88,  85,  /* 12+ */ 87, 84,  /* 20+ */ 86, 84)
339 F(src0_width,          /* 9+ */ 84,  82,  /* 12+ */ 83, 81)
340 F(src0_da16_swiz_w,    /* 9+ */ 83,  82,  /* 12+ */ -1, -1)
341 F(src0_da16_swiz_z,    /* 9+ */ 81,  80,  /* 12+ */ -1, -1)
342 F(src0_hstride,        /* 9+ */ 81,  80,  /* 12+ */ 65, 64)
343 F(src0_address_mode,   /* 9+ */ 79,  79,  /* 12+ */ 80, 80)
344 /** Src0.SrcMod @{ */
345 F(src0_negate,         /* 9+ */ 78,  78,  /* 12+ */ 45, 45)
346 F(src0_abs,            /* 9+ */ 77,  77,  /* 12+ */ 44, 44)
347 /** @} */
348 F(src0_ia_subreg_nr,   /* 9+ */ 76,  73,  /* 12+ */ 79, 76)
349 F(src0_da_reg_nr,      /* 9+ */ 76,  69,  /* 12+ */ 79, 72)
350 F(src0_da16_subreg_nr, /* 9+ */ 68,  68,  /* 12+ */ -1, -1)
351 FD20(src0_da1_subreg_nr, /* 9+ */ 68, 64, /* 12+ */ 71,  67, /* 20+ */ 71, 67, 87)
352 F(src0_da16_swiz_y,    /* 9+ */ 67,  66,  /* 12+ */ -1, -1)
353 F(src0_da16_swiz_x,    /* 9+ */ 65,  64,  /* 12+ */ -1, -1)
354 F(dst_address_mode,    /* 9+ */ 63,  63,  /* 12+ */ 35, 35)
355 F(dst_hstride,         /* 9+ */ 62,  61,  /* 12+ */ 49, 48)
356 F(dst_ia_subreg_nr,    /* 9+ */ 60,  57,  /* 12+ */ 63, 60)
357 F(dst_da_reg_nr,       /* 9+ */ 60,  53,  /* 12+ */ 63, 56)
358 F(dst_da16_subreg_nr,  /* 9+ */ 52,  52,  /* 12+ */ -1, -1)
359 FD20(dst_da1_subreg_nr, /* 9+ */ 52, 48,  /* 12+ */ 55, 51, /* 20+ */ 55, 51, 33)
360 F(da16_writemask,      /* 9+ */ 51,  48,  /* 12+ */ -1, -1) /* Dst.ChanEn */
361 F(src0_reg_hw_type,    /* 9+ */ 46,  43,  /* 12+ */ 43, 40)
362 FF(src0_reg_file,      /* 9+ */ 42,  41,  /* 12+ */ 46, 66)
363 F(src0_is_imm,         /* 9+ */ -1,  -1,  /* 12+ */ 46, 46)
364 F(dst_reg_hw_type,     /* 9+ */ 40,  37,  /* 12+ */ 39, 36)
365 FF(dst_reg_file,       /* 9+ */ 36,  35,  /* 12+ */ 50, 50)
366 F(mask_control,        /* 9+ */ 34,  34,  /* 12+ */ 31, 31)
367 F20(flag_reg_nr,       /* 9+ */ 33,  33,  /* 12+ */ 23, 23,  /* 20+ */ 23, 22)
368 F20(flag_subreg_nr,    /* 9+ */ 32,  32,  /* 12+ */ 22, 22,  /* 20+ */ 21, 21)
369 F(saturate,            /* 9+ */ 31,  31,  /* 12+ */ 34, 34)
370 F(debug_control,       /* 9+ */ 30,  30,  /* 12+ */ 30, 30)
371 F(cmpt_control,        /* 9+ */ 29,  29,  /* 12+ */ 29, 29)
372 F(branch_control,      /* 9+ */ 28,  28,  /* 12+ */ 33, 33)
373 FC(acc_wr_control,     /* 9+ */ 28,  28,  /* 12+ */ 33, 33, devinfo->ver < 20)
374 F(cond_modifier,       /* 9+ */ 27,  24,  /* 12+ */ 95, 92)
375 F(math_function,       /* 9+ */ 27,  24,  /* 12+ */ 95, 92)
376 F20(exec_size,         /* 9+ */ 23,  21,  /* 12+ */ 18, 16,  /* 20+ */ 20, 18)
377 F(pred_inv,            /* 9+ */ 20,  20,  /* 12+ */ 28, 28)
378 F20(pred_control,      /* 9+ */ 19,  16,  /* 12+ */ 27, 24,  /* 20+ */ 27, 26)
379 F(thread_control,      /* 9+ */ 15,  14,  /* 12+ */ -1, -1)
380 F(atomic_control,      /* 9+ */ -1,  -1,  /* 12+ */ 32, 32)
381 F20(qtr_control,       /* 9+ */ 13,  12,  /* 12+ */ 21, 20,  /* 20+ */ 25, 24)
382 F20(nib_control,       /* 9+ */ 11,  11,  /* 12+ */ 19, 19,  /* 20+ */ -1, -1)
383 F(no_dd_check,         /* 9+ */ 10,  10,  /* 12+ */ -1, -1)
384 F(no_dd_clear,         /* 9+ */  9,   9,  /* 12+ */ -1, -1)
385 F20(swsb,              /* 9+ */  -1, -1,  /* 12+ */ 15,   8, /* 20+ */ 17, 8)
386 FK(access_mode,        /* 9+ */   8,  8,  /* 12+ */ BRW_ALIGN_1)
387 /* Bit 7 is Reserved (for future Opcode expansion) */
388 F(hw_opcode,           /* 9+ */   6,  0,  /* 12+ */ 6,  0)
389 
390 /**
391  * Three-source instructions:
392  *  @{
393  */
394 F(3src_src2_reg_nr,         /* 9+ */ 125, 118, /* 12+ */ 127, 120) /* same in align1 */
395 F(3src_a16_src2_swizzle,    /* 9+ */ 114, 107, /* 12+ */ -1, -1)
396 F(3src_a16_src2_rep_ctrl,   /* 9+ */ 106, 106, /* 12+ */ -1, -1)
397 F(3src_src1_reg_nr,         /* 9+ */ 104,  97, /* 12+ */ 111, 104) /* same in align1 */
398 F(3src_a16_src1_swizzle,    /* 9+ */ 93,  86,  /* 12+ */ -1, -1)
399 F(3src_a16_src1_rep_ctrl,   /* 9+ */ 85,  85,  /* 12+ */ -1, -1)
400 F(3src_src0_reg_nr,         /* 9+ */ 83,  76,  /* 12+ */ 79, 72) /* same in align1 */
401 F(3src_a16_src0_swizzle,    /* 9+ */ 72,  65,  /* 12+ */ -1, -1)
402 F(3src_a16_src0_rep_ctrl,   /* 9+ */ 64,  64,  /* 12+ */ -1, -1)
403 F(3src_dst_reg_nr,          /* 9+ */ 63,  56,  /* 12+ */ 63, 56) /* same in align1 */
404 F(3src_a16_dst_subreg_nr,   /* 9+ */ 55,  53,  /* 12+ */ -1, -1)
405 F(3src_a16_dst_writemask,   /* 9+ */ 52,  49,  /* 12+ */ -1, -1)
406 F(3src_a16_nib_ctrl,        /* 9+ */ 11,  11,  /* 12+ */ -1, -1) /* only exists on IVB+ */
407 F(3src_a16_dst_hw_type,     /* 9+ */ 48,  46,  /* 12+ */ -1, -1) /* only exists on IVB+ */
408 F(3src_a16_src_hw_type,     /* 9+ */ 45,  43,  /* 12+ */ -1, -1)
409 F(3src_src2_negate,         /* 9+ */ 42,  42,  /* 12+ */ 85, 85)
410 F(3src_src2_abs,            /* 9+ */ 41,  41,  /* 12+ */ 84, 84)
411 F(3src_src1_negate,         /* 9+ */ 40,  40,  /* 12+ */ 87, 87)
412 F(3src_src1_abs,            /* 9+ */ 39,  39,  /* 12+ */ 86, 86)
413 F(3src_src0_negate,         /* 9+ */ 38,  38,  /* 12+ */ 45, 45)
414 F(3src_src0_abs,            /* 9+ */ 37,  37,  /* 12+ */ 44, 44)
415 F(3src_a16_src1_type,       /* 9+ */ 36,  36,  /* 12+ */ -1, -1)
416 F(3src_a16_src2_type,       /* 9+ */ 35,  35,  /* 12+ */ -1, -1)
417 F(3src_a16_flag_reg_nr,     /* 9+ */ 33,  33,  /* 12+ */ -1, -1)
418 F(3src_a16_flag_subreg_nr,  /* 9+ */ 32,  32,  /* 12+ */ -1, -1)
419 F(3src_saturate,            /* 9+ */ 31, 31,   /* 12+ */ 34, 34)
420 F(3src_debug_control,       /* 9+ */ 30, 30,   /* 12+ */ 30, 30)
421 F(3src_cmpt_control,        /* 9+ */ 29, 29,   /* 12+ */ 29, 29)
422 FC(3src_acc_wr_control,     /* 9+ */ 28, 28,   /* 12+ */ 33, 33, devinfo->ver < 20)
423 F(3src_cond_modifier,       /* 9+ */ 27, 24,   /* 12+ */ 95, 92)
424 F(3src_exec_size,           /* 9+ */ 23, 21,   /* 12+ */ 18, 16)
425 F(3src_pred_inv,            /* 9+ */ 20, 20,   /* 12+ */ 28, 28)
426 F20(3src_pred_control,      /* 9+ */ 19, 16,   /* 12+ */ 27, 24, /* 20+ */ 27, 26)
427 F(3src_thread_control,      /* 9+ */ 15, 14,   /* 12+ */ -1, -1)
428 F(3src_atomic_control,      /* 9+ */ -1, -1,   /* 12+ */ 32, 32)
429 F20(3src_qtr_control,       /* 9+ */ 13, 12,   /* 12+ */ 21, 20, /* 20+ */ 25, 24)
430 F(3src_no_dd_check,         /* 9+ */ 10, 10,   /* 12+ */ -1, -1)
431 F(3src_no_dd_clear,         /* 9+ */  9,  9,   /* 12+ */ -1, -1)
432 F(3src_mask_control,        /* 9+ */ 34, 34,   /* 12+ */ 31, 31)
433 FK(3src_access_mode,        /* 9+ */  8,  8,   /* 12+ */ BRW_ALIGN_1)
434 F20(3src_swsb,              /* 9+ */ -1, -1,   /* 12+ */ 15,  8, /* 20+ */ 17, 8)
435 /* Bit 7 is Reserved (for future Opcode expansion) */
436 F(3src_hw_opcode,           /* 9+ */ 6,  0,    /* 12+ */ 6, 0)
437 /** @} */
438 
439 #define F_3SRC_A16_SUBREG_NR(srcN, src_base) \
440 static inline void                                                          \
441 brw_eu_inst_set_3src_a16_##srcN##_subreg_nr(const struct                    \
442                                             intel_device_info *devinfo,     \
443                                             brw_eu_inst *inst,              \
444                                             unsigned value)                 \
445 {                                                                           \
446    assert(devinfo->ver == 9);                                               \
447    assert((value & ~0b11110) == 0);                                         \
448    brw_eu_inst_set_bits(inst, src_base + 11, src_base + 9, value >> 2);        \
449    brw_eu_inst_set_bits(inst, src_base + 20, src_base + 20, (value >> 1) & 1); \
450 }                                                                           \
451 static inline unsigned                                                      \
452 brw_eu_inst_3src_a16_##srcN##_subreg_nr(const struct                        \
453                                      intel_device_info *devinfo,            \
454                                      const brw_eu_inst *inst)               \
455 {                                                                           \
456    assert(devinfo->ver == 9);                                               \
457    return brw_eu_inst_bits(inst, src_base + 11, src_base + 9) << 2 |        \
458           brw_eu_inst_bits(inst, src_base + 20, src_base + 20) << 1;        \
459 }
460 
461 F_3SRC_A16_SUBREG_NR(src0, 64)
462 F_3SRC_A16_SUBREG_NR(src1, 85)
463 F_3SRC_A16_SUBREG_NR(src2, 106)
464 #undef F_3SRC_A16_SUBREG_NR
465 
466 #define REG_TYPE(reg)                                                         \
467 static inline void                                                            \
468 brw_eu_inst_set_3src_a16_##reg##_type(const struct intel_device_info *devinfo,   \
469                                       brw_eu_inst *inst,                      \
470                                       enum brw_reg_type type)                 \
471 {                                                                             \
472    unsigned hw_type = brw_type_encode_for_3src(devinfo, type);                \
473    brw_eu_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type);          \
474 }                                                                             \
475                                                                               \
476 static inline enum brw_reg_type                                               \
477 brw_eu_inst_3src_a16_##reg##_type(const struct intel_device_info *devinfo,    \
478                                   const brw_eu_inst *inst)                    \
479 {                                                                             \
480    unsigned hw_type = brw_eu_inst_3src_a16_##reg##_hw_type(devinfo, inst);    \
481    return brw_type_decode_for_3src(devinfo, hw_type, 0);                      \
482 }
483 
REG_TYPE(dst)484 REG_TYPE(dst)
485 REG_TYPE(src)
486 #undef REG_TYPE
487 
488 /**
489  * Three-source align1 instructions:
490  *  @{
491  */
492 /* Reserved 127:126 */
493 /* src2_reg_nr same in align16 */
494 FD20(3src_a1_src2_subreg_nr,/* 9+ */   117, 113, /* 12+ */ 119, 115, /* 20+ */ 119, 115, -1)
495 FC(3src_a1_src2_hstride,    /* 9+ */   112, 111, /* 12+ */ 113, 112, devinfo->ver >= 10)
496 /* Reserved 110:109. src2 vstride is an implied parameter */
497 FC(3src_a1_src2_hw_type,    /* 9+ */   108, 106, /* 12+ */ 82, 80, devinfo->ver >= 10)
498 /* Reserved 105 */
499 /* src1_reg_nr same in align16 */
500 FD20(3src_a1_src1_subreg_nr, /* 9+ */   96,  92, /* 12+ */ 103, 99, /* 20+ */ 103, 99, -1)
501 FC(3src_a1_src1_hstride,    /* 9+ */   91,  90,  /* 12+ */ 97, 96, devinfo->ver >= 10)
502 FDC(3src_a1_src1_vstride,   /* 9+ */   89,  88,  /* 12+ */ 91, 91, 83, 83, devinfo->ver >= 10)
503 FC(3src_a1_src1_hw_type,    /* 9+ */   87,  85,  /* 12+ */ 90, 88, devinfo->ver >= 10)
504 /* Reserved 84 */
505 /* src0_reg_nr same in align16 */
506 FD20(3src_a1_src0_subreg_nr, /* 9+ */   75,  71, /* 12+ */ 71, 67, /* 20+ */ 71, 67, -1)
507 FC(3src_a1_src0_hstride,    /* 9+ */   70,  69,  /* 12+ */ 65, 64, devinfo->ver >= 10)
508 FDC(3src_a1_src0_vstride,   /* 9+ */   68,  67,  /* 12+ */ 43, 43, 35, 35, devinfo->ver >= 10)
509 FC(3src_a1_src0_hw_type,    /* 9+ */   66,  64,  /* 12+ */ 42, 40, devinfo->ver >= 10)
510 /* dst_reg_nr same in align16 */
511 FC(3src_a1_dst_subreg_nr,   /* 9+ */   55,  54,  /* 12+ */ 55, 54, devinfo->ver >= 10)
512 FC(3src_a1_special_acc,     /* 9+ */   55,  52,  /* 12+ */ 54, 51, devinfo->ver >= 10) /* aliases dst_subreg_nr */
513 /* Reserved 51:50 */
514 FC(3src_a1_dst_hstride,     /* 9+ */   49,  49,  /* 12+ */ 48, 48, devinfo->ver >= 10)
515 FC(3src_a1_dst_hw_type,     /* 9+ */   48,  46,  /* 12+ */ 38, 36, devinfo->ver >= 10)
516 FF(3src_a1_src2_reg_file,   /* 9+ */   45,  45,  /* 12+ */ 47, 114, .grf_or_imm = true)
517 FFC(3src_a1_src1_reg_file,  /* 9+ */   44,  44,  /* 12+ */ 98, 98, devinfo->ver >= 10, .grf_or_acc = true)
518 FF(3src_a1_src0_reg_file,   /* 9+ */   43,  43,  /* 12+ */ 46, 66, .grf_or_imm = true)
519 
520 F(3src_a1_src2_is_imm,      /* 9+ */   -1,  -1,  /* 12+ */ 47, 47)
521 F(3src_a1_src0_is_imm,      /* 9+ */   -1,  -1,  /* 12+ */ 46, 46)
522 
523 /* Source Modifier fields same in align16 */
524 FFC(3src_a1_dst_reg_file,   /* 9+ */    36,  36, /* 12+ */ 50, 50, devinfo->ver >= 10, .grf_or_acc = true)
525 FC(3src_a1_exec_type,       /* 9+ */    35,  35, /* 12+ */ 39, 39, devinfo->ver >= 10)
526 /* Fields below this same in align16 */
527 /** @} */
528 
529 #define REG_TYPE(reg)                                                         \
530 static inline void                                                            \
531 brw_eu_inst_set_3src_a1_##reg##_type(const struct intel_device_info *devinfo, \
532                                      brw_eu_inst *inst,                       \
533                                      enum brw_reg_type type)                  \
534 {                                                                             \
535    UNUSED enum gfx10_align1_3src_exec_type exec_type =                        \
536       (enum gfx10_align1_3src_exec_type)                                      \
537           brw_eu_inst_3src_a1_exec_type(devinfo, inst);                       \
538    if (brw_type_is_float(type)) {                                             \
539       assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT);                   \
540    } else {                                                                   \
541       assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT);                     \
542    }                                                                          \
543    unsigned hw_type = brw_type_encode_for_3src(devinfo, type);                \
544    brw_eu_inst_set_3src_a1_##reg##_hw_type(devinfo, inst, hw_type);           \
545 }                                                                             \
546                                                                               \
547 static inline enum brw_reg_type                                               \
548 brw_eu_inst_3src_a1_##reg##_type(const struct intel_device_info *devinfo,     \
549                                  const brw_eu_inst *inst)                     \
550 {                                                                             \
551    enum gfx10_align1_3src_exec_type exec_type =                               \
552       (enum gfx10_align1_3src_exec_type)                                      \
553          brw_eu_inst_3src_a1_exec_type(devinfo, inst);                        \
554    unsigned hw_type = brw_eu_inst_3src_a1_##reg##_hw_type(devinfo, inst);     \
555    return brw_type_decode_for_3src(devinfo, hw_type, exec_type);              \
556 }
557 
558 REG_TYPE(dst)
559 REG_TYPE(src0)
560 REG_TYPE(src1)
561 REG_TYPE(src2)
562 #undef REG_TYPE
563 
564 /**
565  * Three-source align1 instruction immediates:
566  *  @{
567  */
568 static inline uint16_t
569 brw_eu_inst_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo,
570                           const brw_eu_inst *insn)
571 {
572    assert(devinfo->ver >= 10);
573    if (devinfo->ver >= 12)
574       return brw_eu_inst_bits(insn, 79, 64);
575    else
576       return brw_eu_inst_bits(insn, 82, 67);
577 }
578 
579 static inline uint16_t
brw_eu_inst_3src_a1_src2_imm(ASSERTED const struct intel_device_info * devinfo,const brw_eu_inst * insn)580 brw_eu_inst_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo,
581                           const brw_eu_inst *insn)
582 {
583    assert(devinfo->ver >= 10);
584    if (devinfo->ver >= 12)
585       return brw_eu_inst_bits(insn, 127, 112);
586    else
587       return brw_eu_inst_bits(insn, 124, 109);
588 }
589 
590 static inline void
brw_eu_inst_set_3src_a1_src0_imm(ASSERTED const struct intel_device_info * devinfo,brw_eu_inst * insn,uint16_t value)591 brw_eu_inst_set_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo,
592                               brw_eu_inst *insn, uint16_t value)
593 {
594    assert(devinfo->ver >= 10);
595    if (devinfo->ver >= 12)
596       brw_eu_inst_set_bits(insn, 79, 64, value);
597    else
598       brw_eu_inst_set_bits(insn, 82, 67, value);
599 }
600 
601 static inline void
brw_eu_inst_set_3src_a1_src2_imm(ASSERTED const struct intel_device_info * devinfo,brw_eu_inst * insn,uint16_t value)602 brw_eu_inst_set_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo,
603                               brw_eu_inst *insn, uint16_t value)
604 {
605    assert(devinfo->ver >= 10);
606    if (devinfo->ver >= 12)
607       brw_eu_inst_set_bits(insn, 127, 112, value);
608    else
609       brw_eu_inst_set_bits(insn, 124, 109, value);
610 }
611 /** @} */
612 
613 /**
614  * Three-source systolic instructions:
615  *  @{
616  */
617 F(dpas_3src_src2_reg_nr,    /* 9+ */ -1, -1,   /* 12+ */ 127, 120)
618 F(dpas_3src_src2_subreg_nr, /* 9+ */ -1, -1,   /* 12+ */ 119, 115)
619 FF(dpas_3src_src2_reg_file, /* 9+ */ -1, -1,   /* 12+ */ 114, 114)
620 F(dpas_3src_src1_reg_nr,    /* 9+ */ -1, -1,   /* 12+ */ 111, 104)
621 F(dpas_3src_src1_subreg_nr, /* 9+ */ -1, -1,   /* 12+ */ 103, 99)
622 FF(dpas_3src_src1_reg_file, /* 9+ */ -1, -1,   /* 12+ */ 98,  98)
623 F(dpas_3src_src1_hw_type,   /* 9+ */ -1, -1,   /* 12+ */ 90,  88)
624 F(dpas_3src_src1_subbyte,   /* 9+ */ -1, -1,   /* 12+ */ 87,  86)
625 F(dpas_3src_src2_subbyte,   /* 9+ */ -1, -1,   /* 12+ */ 85,  84)
626 F(dpas_3src_src2_hw_type,   /* 9+ */ -1, -1,   /* 12+ */ 82,  80)
627 F(dpas_3src_src0_reg_nr,    /* 9+ */ -1, -1,   /* 12+ */ 79,  72)
628 F(dpas_3src_src0_subreg_nr, /* 9+ */ -1, -1,   /* 12+ */ 71,  67)
629 FF(dpas_3src_src0_reg_file, /* 9+ */ -1, -1,   /* 12+ */ 66,  66)
630 F(dpas_3src_dst_reg_nr,     /* 9+ */ -1, -1,   /* 12+ */ 63,  56)
631 F(dpas_3src_dst_subreg_nr,  /* 9+ */ -1, -1,   /* 12+ */ 55,  51)
632 FF(dpas_3src_dst_reg_file,  /* 9+ */ -1, -1,   /* 12+ */ 50,  50)
633 F(dpas_3src_sdepth,         /* 9+ */ -1, -1,   /* 12+ */ 49,  48)
634 F(dpas_3src_rcount,         /* 9+ */ -1, -1,   /* 12+ */ 45,  43)
635 F(dpas_3src_src0_hw_type,   /* 9+ */ -1, -1,   /* 12+ */ 42,  40)
636 F(dpas_3src_exec_type,      /* 9+ */ -1, -1,   /* 12+ */ 39,  39)
637 F(dpas_3src_dst_hw_type,    /* 9+ */ -1, -1,   /* 12+ */ 38,  36)
638 /** @} */
639 
640 #define REG_TYPE(reg)                                                         \
641 static inline void                                                            \
642 brw_eu_inst_set_dpas_3src_##reg##_type(const struct intel_device_info *devinfo,  \
643                                        brw_eu_inst *inst,                     \
644                                        enum brw_reg_type type)                \
645 {                                                                             \
646    UNUSED enum gfx10_align1_3src_exec_type exec_type =                        \
647       (enum gfx10_align1_3src_exec_type)                                      \
648          brw_eu_inst_dpas_3src_exec_type(devinfo, inst);                      \
649    if (brw_type_is_float(type)) {                                             \
650       assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT);                   \
651    } else {                                                                   \
652       assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT);                     \
653    }                                                                          \
654    unsigned hw_type = brw_type_encode_for_3src(devinfo, type);                \
655    brw_eu_inst_set_dpas_3src_##reg##_hw_type(devinfo, inst, hw_type);         \
656 }                                                                             \
657                                                                               \
658 static inline enum brw_reg_type                                               \
659 brw_eu_inst_dpas_3src_##reg##_type(const struct intel_device_info *devinfo,   \
660                                    const brw_eu_inst *inst)                   \
661 {                                                                             \
662    enum gfx10_align1_3src_exec_type exec_type =                               \
663       (enum gfx10_align1_3src_exec_type)                                      \
664          brw_eu_inst_dpas_3src_exec_type(devinfo, inst);                      \
665    unsigned hw_type = brw_eu_inst_dpas_3src_##reg##_hw_type(devinfo, inst);   \
666    return brw_type_decode_for_3src(devinfo, hw_type, exec_type);              \
667 }
668 
REG_TYPE(dst)669 REG_TYPE(dst)
670 REG_TYPE(src0)
671 REG_TYPE(src1)
672 REG_TYPE(src2)
673 #undef REG_TYPE
674 
675 /**
676  * Flow control instruction bits:
677  *  @{
678  */
679 static inline void
680 brw_eu_inst_set_uip(const struct intel_device_info *devinfo,
681                  brw_eu_inst *inst, int32_t value)
682 {
683    if (devinfo->ver >= 12)
684       brw_eu_inst_set_src1_is_imm(devinfo, inst, 1);
685 
686    brw_eu_inst_set_bits(inst, 95, 64, (uint32_t)value);
687 }
688 
689 static inline int32_t
brw_eu_inst_uip(const struct intel_device_info * devinfo,const brw_eu_inst * inst)690 brw_eu_inst_uip(const struct intel_device_info *devinfo, const brw_eu_inst *inst)
691 {
692    return brw_eu_inst_bits(inst, 95, 64);
693 }
694 
695 static inline void
brw_eu_inst_set_jip(const struct intel_device_info * devinfo,brw_eu_inst * inst,int32_t value)696 brw_eu_inst_set_jip(const struct intel_device_info *devinfo,
697                  brw_eu_inst *inst, int32_t value)
698 {
699    if (devinfo->ver >= 12)
700       brw_eu_inst_set_src0_is_imm(devinfo, inst, 1);
701 
702    brw_eu_inst_set_bits(inst, 127, 96, (uint32_t)value);
703 }
704 
705 static inline int32_t
brw_eu_inst_jip(const struct intel_device_info * devinfo,const brw_eu_inst * inst)706 brw_eu_inst_jip(const struct intel_device_info *devinfo, const brw_eu_inst *inst)
707 {
708    return brw_eu_inst_bits(inst, 127, 96);
709 }
710 /** @} */
711 
712 /**
713  * SEND instructions:
714  *  @{
715  */
716 F(send_ex_desc_ia_subreg_nr,  /* 9+ */ 82, 80, /* 12+ */  42,  40)
717 F(send_src0_address_mode,     /* 9+ */ 79, 79, /* 12+ */  -1,  -1)
718 F(send_sel_reg32_desc,        /* 9+ */ 77, 77, /* 12+ */  48,  48)
719 F(send_sel_reg32_ex_desc,     /* 9+ */ 61, 61, /* 12+ */  49,  49)
720 FF(send_src0_reg_file,        /* 9+ */ 42, 41, /* 12+ */   66, 66)
721 F(send_src1_reg_nr,           /* 9+ */ 51, 44, /* 12+ */ 111, 104)
722 FC(send_src1_len,             /* 9+ */ -1, -1, /* 12+ */ 103,  99, devinfo->verx10 >= 125)
723 FF(send_src1_reg_file,        /* 9+ */ 36, 36, /* 12+ */  98,  98)
724 FF(send_dst_reg_file,         /* 9+ */ 35, 35, /* 12+ */  50,  50)
725 FC(send_ex_bso,               /* 9+ */ -1, -1, /* 12+ */  39,  39, devinfo->verx10 >= 125)
726 
727 /* When using scalar register for src0, this replaces src1_len, which is
728  * always zero.
729  */
730 FC(send_src0_subreg_nr,       /* 9+ */ -1, -1, /* 12+ */ 103,  99, devinfo->verx10 >= 300)
731 /** @} */
732 
733 /* Message descriptor bits */
734 #define MD(x) ((x) + 96)
735 #define MD12(x) ((x) >= 30 ? (x) - 30 + 122 :        \
736                  (x) >= 25 ? (x) - 25 + 67 :         \
737                  (x) >= 20 ? (x) - 20 + 51 :         \
738                  (x) >= 11 ? (x) - 11 + 113 :        \
739                  (x) - 0 + 81)
740 
741 /**
742  * Set the SEND(C) message descriptor immediate.
743  *
744  * This doesn't include the SFID nor the EOT field that were considered to be
745  * part of the message descriptor by ancient versions of the BSpec, because
746  * they are present in the instruction even if the message descriptor is
747  * provided indirectly in the address register, so we want to specify them
748  * separately.
749  */
750 static inline void
brw_eu_inst_set_send_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value)751 brw_eu_inst_set_send_desc(const struct intel_device_info *devinfo,
752                        brw_eu_inst *inst, uint32_t value)
753 {
754    if (devinfo->ver >= 12) {
755       brw_eu_inst_set_bits(inst, 123, 122, GET_BITS(value, 31, 30));
756       brw_eu_inst_set_bits(inst, 71, 67, GET_BITS(value, 29, 25));
757       brw_eu_inst_set_bits(inst, 55, 51, GET_BITS(value, 24, 20));
758       brw_eu_inst_set_bits(inst, 121, 113, GET_BITS(value, 19, 11));
759       brw_eu_inst_set_bits(inst, 91, 81, GET_BITS(value, 10, 0));
760    } else {
761       brw_eu_inst_set_bits(inst, 126, 96, value);
762       assert(value >> 31 == 0);
763    }
764 }
765 
766 /**
767  * Get the SEND(C) message descriptor immediate.
768  *
769  * \sa brw_eu_inst_set_send_desc().
770  */
771 static inline uint32_t
brw_eu_inst_send_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst)772 brw_eu_inst_send_desc(const struct intel_device_info *devinfo,
773                    const brw_eu_inst *inst)
774 {
775    if (devinfo->ver >= 12) {
776       return (brw_eu_inst_bits(inst, 123, 122) << 30 |
777               brw_eu_inst_bits(inst, 71, 67) << 25 |
778               brw_eu_inst_bits(inst, 55, 51) << 20 |
779               brw_eu_inst_bits(inst, 121, 113) << 11 |
780               brw_eu_inst_bits(inst, 91, 81));
781    } else {
782       return brw_eu_inst_bits(inst, 126, 96);
783    }
784 }
785 
786 /**
787  * Set the SEND(C) message extended descriptor immediate.
788  *
789  * This doesn't include the SFID nor the EOT field that were considered to be
790  * part of the extended message descriptor by some versions of the BSpec,
791  * because they are present in the instruction even if the extended message
792  * descriptor is provided indirectly in a register, so we want to specify them
793  * separately.
794  */
795 static inline void
brw_eu_inst_set_send_ex_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value,bool gather)796 brw_eu_inst_set_send_ex_desc(const struct intel_device_info *devinfo,
797                              brw_eu_inst *inst, uint32_t value, bool gather)
798 {
799    assert(!gather || devinfo->ver >= 30);
800 
801    if (devinfo->ver >= 12) {
802        brw_eu_inst_set_bits(inst, 127, 124, GET_BITS(value, 31, 28));
803        brw_eu_inst_set_bits(inst, 97, 96, GET_BITS(value, 27, 26));
804        brw_eu_inst_set_bits(inst, 65, 64, GET_BITS(value, 25, 24));
805        brw_eu_inst_set_bits(inst, 47, 35, GET_BITS(value, 23, 11));
806 
807       /* SEND gather uses these bits for src0 subreg nr, so they
808        * are not part of the ex_desc.
809        */
810       if (gather) {
811          assert(devinfo->ver >= 30);
812          assert(GET_BITS(value, 10, 6) == 0);
813       } else {
814          brw_eu_inst_set_bits(inst, 103, 99, GET_BITS(value, 10, 6));
815       }
816 
817       assert(GET_BITS(value, 5, 0) == 0);
818    } else {
819       assert(devinfo->ver >= 9);
820       brw_eu_inst_set_bits(inst, 94, 91, GET_BITS(value, 31, 28));
821       brw_eu_inst_set_bits(inst, 88, 85, GET_BITS(value, 27, 24));
822       brw_eu_inst_set_bits(inst, 83, 80, GET_BITS(value, 23, 20));
823       brw_eu_inst_set_bits(inst, 67, 64, GET_BITS(value, 19, 16));
824       assert(GET_BITS(value, 15, 0) == 0);
825    }
826 }
827 
828 /**
829  * Set the SENDS(C) message extended descriptor immediate.
830  *
831  * This doesn't include the SFID nor the EOT field that were considered to be
832  * part of the extended message descriptor by some versions of the BSpec,
833  * because they are present in the instruction even if the extended message
834  * descriptor is provided indirectly in a register, so we want to specify them
835  * separately.
836  */
837 static inline void
brw_eu_inst_set_sends_ex_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value,bool gather)838 brw_eu_inst_set_sends_ex_desc(const struct intel_device_info *devinfo,
839                               brw_eu_inst *inst, uint32_t value, bool gather)
840 {
841    if (devinfo->ver >= 12) {
842       brw_eu_inst_set_send_ex_desc(devinfo, inst, value, gather);
843    } else {
844       brw_eu_inst_set_bits(inst, 95, 80, GET_BITS(value, 31, 16));
845       assert(GET_BITS(value, 15, 10) == 0);
846       brw_eu_inst_set_bits(inst, 67, 64, GET_BITS(value, 9, 6));
847       assert(GET_BITS(value, 5, 0) == 0);
848    }
849 }
850 
851 /**
852  * Get the SEND(C) message extended descriptor immediate.
853  *
854  * \sa brw_eu_inst_set_send_ex_desc().
855  */
856 static inline uint32_t
brw_eu_inst_send_ex_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst,bool gather)857 brw_eu_inst_send_ex_desc(const struct intel_device_info *devinfo,
858                          const brw_eu_inst *inst, bool gather)
859 {
860    assert(!gather || devinfo->ver >= 30);
861 
862    if (devinfo->ver >= 12) {
863       return (brw_eu_inst_bits(inst, 127, 124) << 28 |
864               brw_eu_inst_bits(inst, 97, 96) << 26 |
865               brw_eu_inst_bits(inst, 65, 64) << 24 |
866               brw_eu_inst_bits(inst, 47, 35) << 11 |
867               (!gather ? brw_eu_inst_bits(inst, 103, 99) << 6 : 0));
868    } else {
869       assert(devinfo->ver >= 9);
870       return (brw_eu_inst_bits(inst, 94, 91) << 28 |
871               brw_eu_inst_bits(inst, 88, 85) << 24 |
872               brw_eu_inst_bits(inst, 83, 80) << 20 |
873               brw_eu_inst_bits(inst, 67, 64) << 16);
874    }
875 }
876 
877 /**
878  * Get the SENDS(C) message extended descriptor immediate.
879  *
880  * \sa brw_eu_inst_set_send_ex_desc().
881  */
882 static inline uint32_t
brw_eu_inst_sends_ex_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst,bool gather)883 brw_eu_inst_sends_ex_desc(const struct intel_device_info *devinfo,
884                           const brw_eu_inst *inst, bool gather)
885 {
886    if (devinfo->ver >= 12) {
887       return brw_eu_inst_send_ex_desc(devinfo, inst, gather);
888    } else {
889       assert(!gather);
890       return (brw_eu_inst_bits(inst, 95, 80) << 16 |
891               brw_eu_inst_bits(inst, 67, 64) << 6);
892    }
893 }
894 
895 /**
896  * Fields for SEND messages:
897  *  @{
898  */
899 F(eot,                 /* 9+ */ 127, 127,       /* 12+ */ 34, 34)
900 F(mlen,                /* 9+ */ 124, 121,       /* 12+ */ MD12(28), MD12(25))
901 F(rlen,                /* 9+ */ 120, 116,       /* 12+ */ MD12(24), MD12(20))
902 F(header_present,      /* 9+ */ 115, 115,       /* 12+ */ MD12(19), MD12(19))
903 F(gateway_notify,      /* 9+ */ MD(16), MD(15), /* 12+ */ -1, -1)
904 FD(function_control,   /* 9+ */ 114,  96,       /* 12+ */ MD12(18), MD12(11), MD12(10), MD12(0))
905 F(gateway_subfuncid,   /* 9+ */ MD(2), MD(0),   /* 12+ */ MD12(2),  MD12(0))
906 F(sfid,                /* 9+ */  27,  24,       /* 12+ */ 95, 92)
907 F(null_rt,             /* 9+ */  80,  80,       /* 12+ */ 44, 44) /* actually only Gfx11+ */
908 F(send_rta_index,      /* 9+ */  -1,  -1,       /* 12+ */  38,  36)
909 /** @} */
910 
911 /**
912  * URB message function control bits:
913  *  @{
914  */
915 F(urb_per_slot_offset,      /* 9+ */ MD(17), MD(17), /* 12+ */ MD12(17), MD12(17))
916 F(urb_channel_mask_present, /* 9+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15))
917 F(urb_swizzle_control,      /* 9+ */ MD(15), MD(15), /* 12+ */ -1, -1)
918 FD(urb_global_offset,       /* 9+ */ MD(14), MD(4),  /* 12+ */ MD12(14), MD12(11), MD12(10), MD12(4))
919 F(urb_opcode,               /* 9+ */ MD( 3), MD(0),  /* 12+ */ MD12(3), MD12(0))
920 /** @} */
921 
922 /**
923  * Sampler message function control bits:
924  *  @{
925  */
926 F(sampler_simd_mode,      /* 9+ */ MD(18), MD(17), /* 12+ */ MD12(18), MD12(17))
927 F(sampler_msg_type,       /* 9+ */ MD(16), MD(12), /* 12+ */ MD12(16), MD12(12))
928 FD(sampler,               /* 9+ */ MD(11), MD(8),  /* 12+ */ MD12(11), MD12(11), MD12(10), MD12(8))
929 F(binding_table_index,    /* 9+ */ MD(7), MD(0),   /* 12+ */ MD12(7), MD12(0)) /* also used by other messages */
930 /** @} */
931 
932 /**
933  * Data port message function control bits:
934  *  @{
935  */
936 F(dp_category,            /* 9+ */ MD(18), MD(18), /* 12+ */ MD12(18), MD12(18))
937 
938 F(dp_read_msg_type,       /* 9+ */ MD(17), MD(14), /* 12+ */ MD12(17), MD12(14))
939 F(dp_write_msg_type,      /* 9+ */ MD(17), MD(14), /* 12+ */ MD12(17), MD12(14))
940 FD(dp_read_msg_control,   /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
941 FD(dp_write_msg_control,  /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
942 
943 F(dp_msg_type,            /* 9+ */ MD(18), MD(14), /* 12+ */ MD12(18), MD12(14))
944 FD(dp_msg_control,        /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
945 /** @} */
946 
947 /**
948  * Scratch message bits:
949  *  @{
950  */
951 F(scratch_read_write,  /* 9+ */ MD(17), MD(17), /* 12+ */ MD12(17), MD12(17)) /* 0 = read,  1 = write */
952 F(scratch_type,        /* 9+ */ MD(16), MD(16), /* 12+ */ -1, -1) /* 0 = OWord, 1 = DWord */
953 F(scratch_invalidate_after_read, /* 9+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15))
954 F(scratch_block_size,  /* 9+ */ MD(13), MD(12), /* 12+ */ MD12(13), MD12(12))
955 FD(scratch_addr_offset,
956    /* 9:   */ MD(11), MD(0),
957    /* 12:  */ MD12(11), MD12(11), MD12(10), MD12(0))
958 /** @} */
959 
960 /**
961  * Render Target message function control bits:
962  *  @{
963  */
964 F(rt_last,             /* 9+ */ MD(12), MD(12),  /* 12+ */ MD12(12), MD12(12))
965 F(rt_slot_group,       /* 9+ */ MD(11),  MD(11), /* 12+ */ MD12(11), MD12(11))
966 F(rt_message_type,     /* 9+ */ MD(10),  MD( 8), /* 12+ */ MD12(10), MD12(8))
967 /** @} */
968 
969 /**
970  * Pixel Interpolator message function control bits:
971  *  @{
972  */
973 F(pi_simd_mode,        /* 9+ */ MD(16),  MD(16), /* 12+ */ MD12(16), MD12(16))
974 F(pi_nopersp,          /* 9+ */ MD(14),  MD(14), /* 12+ */ MD12(14), MD12(14))
975 F(pi_message_type,     /* 9+ */ MD(13),  MD(12), /* 12+ */ MD12(13), MD12(12))
976 F(pi_slot_group,       /* 9+ */ MD(11),  MD(11), /* 12+ */ MD12(11), MD12(11))
977 F(pi_message_data,     /* 9+ */ MD(7),   MD(0),  /* 12+ */  MD12(7), MD12(0))
978 /** @} */
979 
980 /**
981  * Immediates:
982  *  @{
983  */
984 static inline int
brw_eu_inst_imm_d(const struct intel_device_info * devinfo,const brw_eu_inst * insn)985 brw_eu_inst_imm_d(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
986 {
987    (void) devinfo;
988    return brw_eu_inst_bits(insn, 127, 96);
989 }
990 
991 static inline unsigned
brw_eu_inst_imm_ud(const struct intel_device_info * devinfo,const brw_eu_inst * insn)992 brw_eu_inst_imm_ud(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
993 {
994    (void) devinfo;
995    return brw_eu_inst_bits(insn, 127, 96);
996 }
997 
998 static inline uint64_t
brw_eu_inst_imm_uq(const struct intel_device_info * devinfo,const brw_eu_inst * insn)999 brw_eu_inst_imm_uq(const struct intel_device_info *devinfo,
1000                 const brw_eu_inst *insn)
1001 {
1002    if (devinfo->ver >= 12) {
1003       return brw_eu_inst_bits(insn, 95, 64) << 32 |
1004              brw_eu_inst_bits(insn, 127, 96);
1005    } else {
1006       return brw_eu_inst_bits(insn, 127, 64);
1007    }
1008 }
1009 
1010 static inline float
brw_eu_inst_imm_f(const struct intel_device_info * devinfo,const brw_eu_inst * insn)1011 brw_eu_inst_imm_f(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
1012 {
1013    union {
1014       float f;
1015       uint32_t u;
1016    } ft;
1017    (void) devinfo;
1018    ft.u = brw_eu_inst_bits(insn, 127, 96);
1019    return ft.f;
1020 }
1021 
1022 static inline double
brw_eu_inst_imm_df(const struct intel_device_info * devinfo,const brw_eu_inst * insn)1023 brw_eu_inst_imm_df(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
1024 {
1025    union {
1026       double d;
1027       uint64_t u;
1028    } dt;
1029    dt.u = brw_eu_inst_imm_uq(devinfo, insn);
1030    return dt.d;
1031 }
1032 
1033 static inline void
brw_eu_inst_set_imm_d(const struct intel_device_info * devinfo,brw_eu_inst * insn,int value)1034 brw_eu_inst_set_imm_d(const struct intel_device_info *devinfo,
1035                    brw_eu_inst *insn, int value)
1036 {
1037    (void) devinfo;
1038    return brw_eu_inst_set_bits(insn, 127, 96, value);
1039 }
1040 
1041 static inline void
brw_eu_inst_set_imm_ud(const struct intel_device_info * devinfo,brw_eu_inst * insn,unsigned value)1042 brw_eu_inst_set_imm_ud(const struct intel_device_info *devinfo,
1043                     brw_eu_inst *insn, unsigned value)
1044 {
1045    (void) devinfo;
1046    return brw_eu_inst_set_bits(insn, 127, 96, value);
1047 }
1048 
1049 static inline void
brw_eu_inst_set_imm_f(const struct intel_device_info * devinfo,brw_eu_inst * insn,float value)1050 brw_eu_inst_set_imm_f(const struct intel_device_info *devinfo,
1051                    brw_eu_inst *insn, float value)
1052 {
1053    union {
1054       float f;
1055       uint32_t u;
1056    } ft;
1057    (void) devinfo;
1058    ft.f = value;
1059    brw_eu_inst_set_bits(insn, 127, 96, ft.u);
1060 }
1061 
1062 static inline void
brw_eu_inst_set_imm_df(const struct intel_device_info * devinfo,brw_eu_inst * insn,double value)1063 brw_eu_inst_set_imm_df(const struct intel_device_info *devinfo,
1064                     brw_eu_inst *insn, double value)
1065 {
1066    union {
1067       double d;
1068       uint64_t u;
1069    } dt;
1070    (void) devinfo;
1071    dt.d = value;
1072 
1073    if (devinfo->ver >= 12) {
1074       brw_eu_inst_set_bits(insn, 95, 64, dt.u >> 32);
1075       brw_eu_inst_set_bits(insn, 127, 96, dt.u & 0xFFFFFFFF);
1076    } else {
1077       brw_eu_inst_set_bits(insn, 127, 64, dt.u);
1078    }
1079 }
1080 
1081 static inline void
brw_eu_inst_set_imm_uq(const struct intel_device_info * devinfo,brw_eu_inst * insn,uint64_t value)1082 brw_eu_inst_set_imm_uq(const struct intel_device_info *devinfo,
1083                     brw_eu_inst *insn, uint64_t value)
1084 {
1085    (void) devinfo;
1086    if (devinfo->ver >= 12) {
1087       brw_eu_inst_set_bits(insn, 95, 64, value >> 32);
1088       brw_eu_inst_set_bits(insn, 127, 96, value & 0xFFFFFFFF);
1089    } else {
1090       brw_eu_inst_set_bits(insn, 127, 64, value);
1091    }
1092 }
1093 
1094 /** @} */
1095 
1096 #define REG_TYPE(reg)                                                         \
1097 static inline void                                                            \
1098 brw_eu_inst_set_##reg##_file_type(const struct intel_device_info *devinfo,    \
1099                                   brw_eu_inst *inst, enum brw_reg_file file,  \
1100                                   enum brw_reg_type type)                     \
1101 {                                                                             \
1102    assert(file <= IMM);                                                       \
1103    unsigned hw_type = brw_type_encode(devinfo, file, type);                   \
1104    brw_eu_inst_set_##reg##_reg_file(devinfo, inst, file);                     \
1105    brw_eu_inst_set_##reg##_reg_hw_type(devinfo, inst, hw_type);               \
1106 }                                                                             \
1107                                                                               \
1108 static inline enum brw_reg_type                                               \
1109 brw_eu_inst_##reg##_type(const struct intel_device_info *devinfo,             \
1110                          const brw_eu_inst *inst)                             \
1111 {                                                                             \
1112    unsigned file = __builtin_strcmp("dst", #reg) == 0 ?                       \
1113                    (unsigned) FIXED_GRF :                                     \
1114                    brw_eu_inst_##reg##_reg_file(devinfo, inst);               \
1115    unsigned hw_type = brw_eu_inst_##reg##_reg_hw_type(devinfo, inst);         \
1116    return brw_type_decode(devinfo, (enum brw_reg_file)file, hw_type);         \
1117 }
1118 
1119 REG_TYPE(dst)
REG_TYPE(src0)1120 REG_TYPE(src0)
1121 REG_TYPE(src1)
1122 #undef REG_TYPE
1123 
1124 
1125 /* The AddrImm fields are split into two discontiguous sections on Gfx9+ */
1126 #define BRW_IA1_ADDR_IMM(reg, g9_nine, g9_high, g9_low,                  \
1127                          g12_high, g12_low, g20_high, g20_low, g20_zero) \
1128 static inline void                                                       \
1129 brw_eu_inst_set_##reg##_ia1_addr_imm(const struct                        \
1130                                      intel_device_info *devinfo,         \
1131                                      brw_eu_inst *inst,                  \
1132                                      unsigned value)                     \
1133 {                                                                        \
1134    if (devinfo->ver >= 20) {                                             \
1135       assert((value & ~0x7ff) == 0);                                     \
1136       brw_eu_inst_set_bits(inst, g20_high, g20_low, value >> 1);         \
1137       if (g20_zero == -1)                                                \
1138          assert((value & 1) == 0);                                       \
1139       else                                                               \
1140          brw_eu_inst_set_bits(inst, g20_zero, g20_zero, value & 1);      \
1141    } else if (devinfo->ver >= 12) {                                      \
1142       assert((value & ~0x3ff) == 0);                                     \
1143       brw_eu_inst_set_bits(inst, g12_high, g12_low, value);              \
1144    } else {                                                              \
1145       assert((value & ~0x3ff) == 0);                                     \
1146       brw_eu_inst_set_bits(inst, g9_high, g9_low, value & 0x1ff);        \
1147       brw_eu_inst_set_bits(inst, g9_nine, g9_nine, value >> 9);          \
1148    }                                                                     \
1149 }                                                                        \
1150 static inline unsigned                                                   \
1151 brw_eu_inst_##reg##_ia1_addr_imm(const struct intel_device_info *devinfo,\
1152                                  const brw_eu_inst *inst)                \
1153 {                                                                        \
1154    if (devinfo->ver >= 20) {                                             \
1155       return brw_eu_inst_bits(inst, g20_high, g20_low) << 1 |            \
1156              (g20_zero == -1 ? 0 :                                       \
1157               brw_eu_inst_bits(inst, g20_zero, g20_zero));               \
1158    } else if (devinfo->ver >= 12) {                                      \
1159       return brw_eu_inst_bits(inst, g12_high, g12_low);                  \
1160    } else {                                                              \
1161       return brw_eu_inst_bits(inst, g9_high, g9_low) |                   \
1162              (brw_eu_inst_bits(inst, g9_nine, g9_nine) << 9);            \
1163    }                                                                     \
1164 }
1165 
1166 /* AddrImm for Align1 Indirect Addressing                 */
1167 /*                     ----Gfx9----  -Gfx12-  ---Gfx20--- */
1168 BRW_IA1_ADDR_IMM(src1, 121, 104, 96, 107, 98, 107, 98, -1)
1169 BRW_IA1_ADDR_IMM(src0,  95,  72, 64,  75, 66,  75, 66, 87)
1170 BRW_IA1_ADDR_IMM(dst,   47,  56, 48,  59, 50,  59, 50, 33)
1171 
1172 #define BRW_IA16_ADDR_IMM(reg, g9_nine, g9_high, g9_low)                  \
1173 static inline void                                                        \
1174 brw_eu_inst_set_##reg##_ia16_addr_imm(const struct                        \
1175                                       intel_device_info *devinfo,         \
1176                                       brw_eu_inst *inst, unsigned value)  \
1177 {                                                                         \
1178    assert(devinfo->ver < 12);                                             \
1179    assert((value & ~0x3ff) == 0);                                         \
1180    assert(GET_BITS(value, 3, 0) == 0);                                    \
1181    brw_eu_inst_set_bits(inst, g9_high, g9_low, GET_BITS(value, 8, 4));    \
1182    brw_eu_inst_set_bits(inst, g9_nine, g9_nine, GET_BITS(value, 9, 9));   \
1183 }                                                                         \
1184 static inline unsigned                                                    \
1185 brw_eu_inst_##reg##_ia16_addr_imm(const struct intel_device_info *devinfo,\
1186                                   const brw_eu_inst *inst)                \
1187 {                                                                         \
1188    assert(devinfo->ver < 12);                                             \
1189    return (brw_eu_inst_bits(inst, g9_high, g9_low) << 4) |                \
1190           (brw_eu_inst_bits(inst, g9_nine, g9_nine) << 9);                \
1191 }
1192 
1193 /* AddrImm[9:0] for Align16 Indirect Addressing:
1194  * Compared to Align1, these are missing the low 4 bits.
1195  *                             ----Gfx9----
1196  */
1197 BRW_IA16_ADDR_IMM(src1,        121, 104, 100)
1198 BRW_IA16_ADDR_IMM(src0,         95,  72,  68)
1199 BRW_IA16_ADDR_IMM(dst,          47,  56,  52)
1200 BRW_IA16_ADDR_IMM(send_src0,    78,  72,  68)
1201 BRW_IA16_ADDR_IMM(send_dst,     62,  56,  52)
1202 
1203 /**
1204  * Fetch a set of contiguous bits from the instruction.
1205  *
1206  * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
1207  */
1208 static inline uint64_t
1209 brw_eu_inst_bits(const brw_eu_inst *inst, unsigned high, unsigned low)
1210 {
1211    assume(high < 128);
1212    assume(high >= low);
1213    /* We assume the field doesn't cross 64-bit boundaries. */
1214    const unsigned word = high / 64;
1215    assert(word == low / 64);
1216 
1217    high %= 64;
1218    low %= 64;
1219 
1220    const uint64_t mask = (~0ull >> (64 - (high - low + 1)));
1221 
1222    return (inst->data[word] >> low) & mask;
1223 }
1224 
1225 /**
1226  * Set bits in the instruction, with proper shifting and masking.
1227  *
1228  * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
1229  */
1230 static inline void
brw_eu_inst_set_bits(brw_eu_inst * inst,unsigned high,unsigned low,uint64_t value)1231 brw_eu_inst_set_bits(brw_eu_inst *inst, unsigned high, unsigned low, uint64_t value)
1232 {
1233    assume(high < 128);
1234    assume(high >= low);
1235    const unsigned word = high / 64;
1236    assert(word == low / 64);
1237 
1238    high %= 64;
1239    low %= 64;
1240 
1241    const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low;
1242 
1243    /* Make sure the supplied value actually fits in the given bitfield. */
1244    assert((value & (mask >> low)) == value);
1245 
1246    inst->data[word] = (inst->data[word] & ~mask) | (value << low);
1247 }
1248 
1249 #undef BRW_IA16_ADDR_IMM
1250 #undef BRW_IA1_ADDR_IMM
1251 #undef MD
1252 #undef F
1253 #undef FC
1254 #undef F20
1255 #undef FD20
1256 
1257 typedef struct {
1258    uint64_t data;
1259 } brw_eu_compact_inst;
1260 
1261 /**
1262  * Fetch a set of contiguous bits from the compacted instruction.
1263  *
1264  * Bits indices range from 0..63.
1265  */
1266 static inline unsigned
brw_eu_compact_inst_bits(const brw_eu_compact_inst * inst,unsigned high,unsigned low)1267 brw_eu_compact_inst_bits(const brw_eu_compact_inst *inst, unsigned high, unsigned low)
1268 {
1269    assume(high < 64);
1270    assume(high >= low);
1271    const uint64_t mask = (1ull << (high - low + 1)) - 1;
1272 
1273    return (inst->data >> low) & mask;
1274 }
1275 
1276 /**
1277  * Set bits in the compacted instruction.
1278  *
1279  * Bits indices range from 0..63.
1280  */
1281 static inline void
brw_eu_compact_inst_set_bits(brw_eu_compact_inst * inst,unsigned high,unsigned low,uint64_t value)1282 brw_eu_compact_inst_set_bits(brw_eu_compact_inst *inst, unsigned high, unsigned low,
1283                              uint64_t value)
1284 {
1285    assume(high < 64);
1286    assume(high >= low);
1287    const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low;
1288 
1289    /* Make sure the supplied value actually fits in the given bitfield. */
1290    assert((value & (mask >> low)) == value);
1291 
1292    inst->data = (inst->data & ~mask) | (value << low);
1293 }
1294 
1295 #define FC(name, hi9, lo9, hi12, lo12, assertions)                 \
1296 static inline void                                                 \
1297 brw_eu_compact_inst_set_##name(const struct                        \
1298                                intel_device_info *devinfo,         \
1299                                brw_eu_compact_inst *inst,          \
1300                                unsigned v)                         \
1301 {                                                                  \
1302    assert(assertions);                                             \
1303    if (devinfo->ver >= 12)                                         \
1304       brw_eu_compact_inst_set_bits(inst, hi12, lo12, v);           \
1305    else                                                            \
1306       brw_eu_compact_inst_set_bits(inst, hi9, lo9, v);             \
1307 }                                                                  \
1308 static inline unsigned                                             \
1309 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo,\
1310                            const brw_eu_compact_inst *inst)        \
1311 {                                                                  \
1312    assert(assertions);                                             \
1313    if (devinfo->ver >= 12)                                         \
1314       return brw_eu_compact_inst_bits(inst, hi12, lo12);           \
1315    else                                                            \
1316       return brw_eu_compact_inst_bits(inst, hi9, lo9);             \
1317 }
1318 
1319 /* A simple macro for fields which stay in the same place on all generations
1320  * except for Gfx12.
1321  */
1322 #define F(name, hi9, lo9, hi12, lo12) FC(name, hi9, lo9, hi12, lo12, true)
1323 
1324 /* A macro for fields which moved to several different locations
1325  * across generations.
1326  */
1327 #define F20(name, hi9, lo9, hi12, lo12, hi20, lo20)                \
1328 static inline void                                                 \
1329 brw_eu_compact_inst_set_##name(const struct                        \
1330                                intel_device_info *devinfo,         \
1331                                brw_eu_compact_inst *inst,          \
1332                                unsigned v)                         \
1333 {                                                                  \
1334    if (devinfo->ver >= 20)                                         \
1335       brw_eu_compact_inst_set_bits(inst, hi20, lo20, v);           \
1336    else if (devinfo->ver >= 12)                                    \
1337       brw_eu_compact_inst_set_bits(inst, hi12, lo12, v);           \
1338    else                                                            \
1339       brw_eu_compact_inst_set_bits(inst, hi9, lo9, v);             \
1340 }                                                                  \
1341 static inline unsigned                                             \
1342 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo,\
1343                            const brw_eu_compact_inst *inst)        \
1344 {                                                                  \
1345    if (devinfo->ver >= 20)                                         \
1346       return brw_eu_compact_inst_bits(inst, hi20, lo20);           \
1347    else if (devinfo->ver >= 12)                                    \
1348       return brw_eu_compact_inst_bits(inst, hi12, lo12);           \
1349    else                                                            \
1350       return brw_eu_compact_inst_bits(inst, hi9, lo9);             \
1351 }
1352 
1353 /* A macro for fields which gained extra discontiguous bits in Gfx20
1354  * (specified by hi20ex-lo20ex).
1355  */
1356 #define FD20(name, hi9, lo9, hi12, lo12,                                \
1357              hi20, lo20, hi20ex, lo20ex)                                \
1358    static inline void                                                   \
1359 brw_eu_compact_inst_set_##name(const struct                             \
1360                                intel_device_info *devinfo,              \
1361                                brw_eu_compact_inst *inst, unsigned v)   \
1362 {                                                                       \
1363    if (devinfo->ver >= 20) {                                            \
1364       const unsigned k = hi20 - lo20 + 1;                               \
1365       brw_eu_compact_inst_set_bits(inst, hi20ex, lo20ex, v >> k);       \
1366       brw_eu_compact_inst_set_bits(inst, hi20, lo20, v & ((1u << k) - 1)); \
1367    } else if (devinfo->ver >= 12) {                                     \
1368       brw_eu_compact_inst_set_bits(inst, hi12, lo12, v);                \
1369    } else {                                                             \
1370       brw_eu_compact_inst_set_bits(inst, hi9, lo9, v);                  \
1371    }                                                                    \
1372 }                                                                       \
1373 static inline unsigned                                                  \
1374 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo,     \
1375                            const brw_eu_compact_inst *inst)             \
1376 {                                                                       \
1377    if (devinfo->ver >= 20) {                                            \
1378       const unsigned k = hi20 - lo20 + 1;                               \
1379       return (brw_eu_compact_inst_bits(inst, hi20ex, lo20ex) << k |     \
1380               brw_eu_compact_inst_bits(inst, hi20, lo20));              \
1381    } else if (devinfo->ver >= 12) {                                     \
1382       return brw_eu_compact_inst_bits(inst, hi12, lo12);                \
1383    } else {                                                             \
1384       return brw_eu_compact_inst_bits(inst, hi9, lo9);                  \
1385    }                                                                    \
1386 }
1387 
1388 F(src1_reg_nr,       /* 9+ */ 63, 56, /* 12+ */ 63, 56)
1389 F(src0_reg_nr,       /* 9+ */ 55, 48, /* 12+ */ 47, 40)
1390 F20(dst_reg_nr,      /* 9+ */ 47, 40, /* 12+ */ 23, 16, /* 20+ */ 39, 32)
1391 F(src1_index,        /* 9+ */ 39, 35, /* 12+ */ 55, 52)
1392 F20(src0_index,      /* 9+ */ 34, 30, /* 12+ */ 51, 48, /* 20+ */ 25, 23)
1393 F(cmpt_control,      /* 9+ */ 29, 29, /* 12+ */ 29, 29) /* Same location as brw_eu_inst */
1394 F(cond_modifier,     /* 9+ */ 27, 24, /* 12+ */ -1, -1) /* Same location as brw_eu_inst */
1395 F(acc_wr_control,    /* 9+ */ 23, 23, /* 12+ */ -1, -1)
1396 F20(subreg_index,    /* 9+ */ 22, 18, /* 12+ */ 39, 35, /* 20+ */ 51, 48)
1397 FD20(datatype_index, /* 9+ */ 17, 13, /* 12+ */ 34, 30, /* 20+ */ 28, 26, 31, 30)
1398 F20(control_index,   /* 9+ */ 12,  8, /* 12+ */ 28, 24, /* 20+ */ 22, 18)
1399 F20(swsb,            /* 9+ */ -1, -1, /* 12+ */ 15,  8, /* 20+ */ 17,  8)
1400 F(debug_control,     /* 9+ */  7,  7, /* 12+ */  7,  7)
1401 F(hw_opcode,         /* 9+ */  6,  0, /* 12+ */  6,  0) /* Same location as brw_eu_inst */
1402 
1403 static inline unsigned
brw_eu_compact_inst_imm(const struct intel_device_info * devinfo,const brw_eu_compact_inst * inst)1404 brw_eu_compact_inst_imm(const struct intel_device_info *devinfo,
1405                         const brw_eu_compact_inst *inst)
1406 {
1407    if (devinfo->ver >= 12) {
1408       return brw_eu_compact_inst_bits(inst, 63, 52);
1409    } else {
1410       return (brw_eu_compact_inst_bits(inst, 39, 35) << 8) |
1411              (brw_eu_compact_inst_bits(inst, 63, 56));
1412    }
1413 }
1414 
1415 /**
1416  * Compacted three-source instructions:
1417  *  @{
1418  */
1419 F(3src_src2_reg_nr,     /* 9+ */ 63, 57, /* 12+ */ 55, 48)
1420 F(3src_src1_reg_nr,     /* 9+ */ 56, 50, /* 12+ */ 63, 56)
1421 F(3src_src0_reg_nr,     /* 9+ */ 49, 43, /* 12+ */ 47, 40)
1422 F(3src_src2_subreg_nr,  /* 9+ */ 42, 40, /* 12+ */ -1, -1)
1423 F(3src_src1_subreg_nr,  /* 9+ */ 39, 37, /* 12+ */ -1, -1)
1424 F(3src_src0_subreg_nr,  /* 9+ */ 36, 34, /* 12+ */ -1, -1)
1425 F(3src_src2_rep_ctrl,   /* 9+ */ 33, 33, /* 12+ */ -1, -1)
1426 F(3src_src1_rep_ctrl,   /* 9+ */ 32, 32, /* 12+ */ -1, -1)
1427 F(3src_saturate,        /* 9+ */ 31, 31, /* 12+ */ -1, -1)
1428 F(3src_debug_control,   /* 9+ */ 30, 30, /* 12+ */  7,  7)
1429 F(3src_cmpt_control,    /* 9+ */ 29, 29, /* 12+ */ 29, 29)
1430 F(3src_src0_rep_ctrl,   /* 9+ */ 28, 28, /* 12+ */ -1, -1)
1431 /* Reserved */
1432 F20(3src_dst_reg_nr,    /* 9+ */ 18, 12, /* 12+ */ 23, 16, /* 20+ */ 39, 32)
1433 F20(3src_source_index,  /* 9+ */ 11, 10, /* 12+ */ 34, 30, /* 20+ */ 25, 22)
1434 FD20(3src_subreg_index, /* 9+ */ -1, -1, /* 12+ */ 39, 35, /* 20+ */ 28, 26, 31, 30)
1435 F20(3src_control_index, /* 9+ */  9,  8, /* 12+ */ 28, 24, /* 20+ */ 21, 18)
1436 F20(3src_swsb,          /* 9+ */ -1, -1, /* 12+ */ 15,  8, /* 20+ */ 17,  8)
1437 /* Bit 7 is Reserved (for future Opcode expansion) */
1438 F(3src_hw_opcode,       /* 9+ */  6,  0, /* 12+ */  6,  0)
1439 /** @} */
1440 
1441 #undef F
1442 
1443 static inline void
brw_eu_inst_set_opcode(const struct brw_isa_info * isa,struct brw_eu_inst * inst,enum opcode opcode)1444 brw_eu_inst_set_opcode(const struct brw_isa_info *isa,
1445                     struct brw_eu_inst *inst, enum opcode opcode)
1446 {
1447    brw_eu_inst_set_hw_opcode(isa->devinfo, inst, brw_opcode_encode(isa, opcode));
1448 }
1449 
1450 static inline enum opcode
brw_eu_inst_opcode(const struct brw_isa_info * isa,const struct brw_eu_inst * inst)1451 brw_eu_inst_opcode(const struct brw_isa_info *isa,
1452                 const struct brw_eu_inst *inst)
1453 {
1454    return brw_opcode_decode(isa, brw_eu_inst_hw_opcode(isa->devinfo, inst));
1455 }
1456 
1457 #ifdef __cplusplus
1458 }
1459 #endif
1460