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 elk_inst.h
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 "elk_eu_defines.h"
37 #include "elk_isa_info.h"
38 #include "elk_reg_type.h"
39 #include "dev/intel_device_info.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /* elk_context.h has a forward declaration of elk_inst, so name the struct. */
46 typedef struct elk_inst {
47 uint64_t data[2];
48 } elk_inst;
49
50 static inline uint64_t elk_inst_bits(const elk_inst *inst,
51 unsigned high, unsigned low);
52 static inline void elk_inst_set_bits(elk_inst *inst,
53 unsigned high, unsigned low,
54 uint64_t value);
55
56 #define FC(name, hi4, lo4, assertions) \
57 static inline void \
58 elk_inst_set_##name(const struct intel_device_info *devinfo, \
59 elk_inst *inst, uint64_t v) \
60 { \
61 assert(assertions); \
62 elk_inst_set_bits(inst, hi4, lo4, v); \
63 } \
64 static inline uint64_t \
65 elk_inst_##name(const struct intel_device_info *devinfo, \
66 const elk_inst *inst) \
67 { \
68 assert(assertions); \
69 return elk_inst_bits(inst, hi4, lo4); \
70 }
71
72 /* A simple macro for fields which stay in the same place on all generations. */
73 #define F(name, hi4, lo4) FC(name, hi4, lo4, true)
74
75 #define BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
76 hi7, lo7, hi8, lo8) \
77 unsigned high, low; \
78 if (devinfo->ver >= 8) { \
79 high = hi8; low = lo8; \
80 } else if (devinfo->ver >= 7) { \
81 high = hi7; low = lo7; \
82 } else if (devinfo->ver >= 6) { \
83 high = hi6; low = lo6; \
84 } else if (devinfo->ver >= 5) { \
85 high = hi5; low = lo5; \
86 } else if (devinfo->verx10 >= 45) { \
87 high = hi45; low = lo45; \
88 } else { \
89 high = hi4; low = lo4; \
90 } \
91 assert(((int) high) != -1 && ((int) low) != -1);
92
93 /* A general macro for cases where the field has moved to several different
94 * bit locations across generations. GCC appears to combine cases where the
95 * bits are identical, removing some of the inefficiency.
96 */
97 #define FF(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
98 hi7, lo7, hi8, lo8) \
99 static inline void \
100 elk_inst_set_##name(const struct intel_device_info *devinfo, \
101 elk_inst *inst, uint64_t value) \
102 { \
103 BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
104 hi7, lo7, hi8, lo8) \
105 elk_inst_set_bits(inst, high, low, value); \
106 } \
107 static inline uint64_t \
108 elk_inst_##name(const struct intel_device_info *devinfo, const elk_inst *inst)\
109 { \
110 BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \
111 hi7, lo7, hi8, lo8) \
112 return elk_inst_bits(inst, high, low); \
113 }
114
115 /* A macro for fields which moved as of Gfx8+. */
116 #define F8(name, gfx4_high, gfx4_low, gfx8_high, gfx8_low) \
117 FF(name, \
118 /* 4: */ gfx4_high, gfx4_low, \
119 /* 4.5: */ gfx4_high, gfx4_low, \
120 /* 5: */ gfx4_high, gfx4_low, \
121 /* 6: */ gfx4_high, gfx4_low, \
122 /* 7: */ gfx4_high, gfx4_low, \
123 /* 8: */ gfx8_high, gfx8_low);
124
125 F(src1_vstride, /* 4+ */ 120, 117)
126 F(src1_width, /* 4+ */ 116, 114)
127 F(src1_da16_swiz_w, /* 4+ */ 115, 114)
128 F(src1_da16_swiz_z, /* 4+ */ 113, 112)
129 F(src1_hstride, /* 4+ */ 113, 112)
130 F(src1_address_mode, /* 4+ */ 111, 111)
131 /** Src1.SrcMod @{ */
132 F(src1_negate, /* 4+ */ 110, 110)
133 F(src1_abs, /* 4+ */ 109, 109)
134 /** @} */
135 F8(src1_ia_subreg_nr, /* 4+ */ 108, 106, /* 8+ */ 108, 105)
136 F(src1_da_reg_nr, /* 4+ */ 108, 101)
137 F(src1_da16_subreg_nr, /* 4+ */ 100, 100)
138 F(src1_da1_subreg_nr, /* 4+ */ 100, 96)
139 F(src1_da16_swiz_y, /* 4+ */ 99, 98)
140 F(src1_da16_swiz_x, /* 4+ */ 97, 96)
141 F8(src1_reg_hw_type, /* 4+ */ 46, 44, /* 8+ */ 94, 91)
142 F8(src1_reg_file, /* 4+ */ 43, 42, /* 8+ */ 90, 89)
143 F(src0_vstride, /* 4+ */ 88, 85)
144 F(src0_width, /* 4+ */ 84, 82)
145 F(src0_da16_swiz_w, /* 4+ */ 83, 82)
146 F(src0_da16_swiz_z, /* 4+ */ 81, 80)
147 F(src0_hstride, /* 4+ */ 81, 80)
148 F(src0_address_mode, /* 4+ */ 79, 79)
149 /** Src0.SrcMod @{ */
150 F(src0_negate, /* 4+ */ 78, 78)
151 F(src0_abs, /* 4+ */ 77, 77)
152 /** @} */
153 F8(src0_ia_subreg_nr, /* 4+ */ 76, 74, /* 8+ */ 76, 73)
154 F(src0_da_reg_nr, /* 4+ */ 76, 69)
155 F(src0_da16_subreg_nr, /* 4+ */ 68, 68)
156 F(src0_da1_subreg_nr, /* 4+ */ 68, 64)
157 F(src0_da16_swiz_y, /* 4+ */ 67, 66)
158 F(src0_da16_swiz_x, /* 4+ */ 65, 64)
159 F(dst_address_mode, /* 4+ */ 63, 63)
160 F(dst_hstride, /* 4+ */ 62, 61)
161 F8(dst_ia_subreg_nr, /* 4+ */ 60, 58, /* 8+ */ 60, 57)
162 F(dst_da_reg_nr, /* 4+ */ 60, 53)
163 F(dst_da16_subreg_nr, /* 4+ */ 52, 52)
164 F(dst_da1_subreg_nr, /* 4+ */ 52, 48)
165 F(da16_writemask, /* 4+ */ 51, 48) /* Dst.ChanEn */
166 F8(src0_reg_hw_type, /* 4+ */ 41, 39, /* 8+ */ 46, 43)
167 F8(src0_reg_file, /* 4+ */ 38, 37, /* 8+ */ 42, 41)
168 F(src0_is_imm, /* 4+ */ -1, -1)
169 F8(dst_reg_hw_type, /* 4+ */ 36, 34, /* 8+ */ 40, 37)
170 F8(dst_reg_file, /* 4+ */ 33, 32, /* 8+ */ 36, 35)
171 F8(mask_control, /* 4+ */ 9, 9, /* 8+ */ 34, 34)
172 FF(flag_reg_nr,
173 /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1,
174 /* 7: */ 90, 90,
175 /* 8: */ 33, 33)
176 F8(flag_subreg_nr, /* 4+ */ 89, 89, /* 8+ */ 32, 32)
177 F(saturate, /* 4+ */ 31, 31)
178 F(debug_control, /* 4+ */ 30, 30)
179 F(cmpt_control, /* 4+ */ 29, 29)
180 FC(branch_control, /* 4+ */ 28, 28, devinfo->ver >= 8)
181 FC(acc_wr_control, /* 4+ */ 28, 28, devinfo->ver >= 6)
182 FC(mask_control_ex, /* 4+ */ 28, 28, devinfo->verx10 == 45 ||
183 devinfo->ver == 5)
184 F(cond_modifier, /* 4+ */ 27, 24)
185 FC(math_function, /* 4+ */ 27, 24, devinfo->ver >= 6)
186 F(exec_size, /* 4+ */ 23, 21)
187 F(pred_inv, /* 4+ */ 20, 20)
188 F(pred_control, /* 4+ */ 19, 16)
189 F(thread_control, /* 4+ */ 15, 14)
190 F(atomic_control, /* 4+ */ -1, -1)
191 F(qtr_control, /* 4+ */ 13, 12)
192 FF(nib_control,
193 /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1,
194 /* 7: */ 47, 47,
195 /* 8: */ 11, 11);
196 F8(no_dd_check, /* 4+ */ 11, 11, /* 8+ */ 10, 10)
197 F8(no_dd_clear, /* 4+ */ 10, 10, /* 8+ */ 9, 9)
198 F(access_mode, /* 4+ */ 8, 8)
199 /* Bit 7 is Reserved (for future Opcode expansion) */
200 F(hw_opcode, /* 4+ */ 6, 0)
201
202 /**
203 * Three-source instructions:
204 * @{
205 */
206 F(3src_src2_reg_nr, /* 4+ */ 125, 118) /* same in align1 */
207 F(3src_a16_src2_subreg_nr, /* 4+ */ 117, 115) /* Extra discontiguous bit on CHV? */
208 F(3src_a16_src2_swizzle, /* 4+ */ 114, 107)
209 F(3src_a16_src2_rep_ctrl, /* 4+ */ 106, 106)
210 F(3src_src1_reg_nr, /* 4+ */ 104, 97) /* same in align1 */
211 F(3src_a16_src1_subreg_nr, /* 4+ */ 96, 94) /* Extra discontiguous bit on CHV? */
212 F(3src_a16_src1_swizzle, /* 4+ */ 93, 86)
213 F(3src_a16_src1_rep_ctrl, /* 4+ */ 85, 85)
214 F(3src_src0_reg_nr, /* 4+ */ 83, 76) /* same in align1 */
215 F(3src_a16_src0_subreg_nr, /* 4+ */ 75, 73) /* Extra discontiguous bit on CHV? */
216 F(3src_a16_src0_swizzle, /* 4+ */ 72, 65)
217 F(3src_a16_src0_rep_ctrl, /* 4+ */ 64, 64)
218 F(3src_dst_reg_nr, /* 4+ */ 63, 56) /* same in align1 */
219 F(3src_a16_dst_subreg_nr, /* 4+ */ 55, 53)
220 F(3src_a16_dst_writemask, /* 4+ */ 52, 49)
221 F8(3src_a16_nib_ctrl, /* 4+ */ 47, 47, /* 8+ */ 11, 11) /* only exists on IVB+ */
222 F8(3src_a16_dst_hw_type, /* 4+ */ 45, 44, /* 8+ */ 48, 46) /* only exists on IVB+ */
223 F8(3src_a16_src_hw_type, /* 4+ */ 43, 42, /* 8+ */ 45, 43)
224 F8(3src_src2_negate, /* 4+ */ 41, 41, /* 8+ */ 42, 42)
225 F8(3src_src2_abs, /* 4+ */ 40, 40, /* 8+ */ 41, 41)
226 F8(3src_src1_negate, /* 4+ */ 39, 39, /* 8+ */ 40, 40)
227 F8(3src_src1_abs, /* 4+ */ 38, 38, /* 8+ */ 39, 39)
228 F8(3src_src0_negate, /* 4+ */ 37, 37, /* 8+ */ 38, 38)
229 F8(3src_src0_abs, /* 4+ */ 36, 36, /* 8+ */ 37, 37)
230 F8(3src_a16_src1_type, /* 4+ */ -1, -1, /* 8+ */ 36, 36)
231 F8(3src_a16_src2_type, /* 4+ */ -1, -1, /* 8+ */ 35, 35)
232 F8(3src_a16_flag_reg_nr, /* 4+ */ 34, 34, /* 8+ */ 33, 33)
233 F8(3src_a16_flag_subreg_nr, /* 4+ */ 33, 33, /* 8+ */ 32, 32)
234 FF(3src_a16_dst_reg_file,
235 /* 4-5: doesn't exist - no 3-source instructions */ -1, -1, -1, -1, -1, -1,
236 /* 6: */ 32, 32,
237 /* 7-8: doesn't exist - no MRFs */ -1, -1, -1, -1)
238 F(3src_saturate, /* 4+ */ 31, 31)
239 F(3src_debug_control, /* 4+ */ 30, 30)
240 F(3src_cmpt_control, /* 4+ */ 29, 29)
241 F(3src_acc_wr_control, /* 4+ */ 28, 28)
242 F(3src_cond_modifier, /* 4+ */ 27, 24)
243 F(3src_exec_size, /* 4+ */ 23, 21)
244 F(3src_pred_inv, /* 4+ */ 20, 20)
245 F(3src_pred_control, /* 4+ */ 19, 16)
246 F(3src_thread_control, /* 4+ */ 15, 14)
247 F(3src_qtr_control, /* 4+ */ 13, 12)
248 F8(3src_no_dd_check, /* 4+ */ 11, 11, /* 8+ */ 10, 10)
249 F8(3src_no_dd_clear, /* 4+ */ 10, 10, /* 8+ */ 9, 9)
250 F8(3src_mask_control, /* 4+ */ 9, 9, /* 8+ */ 34, 34)
251 F(3src_access_mode, /* 4+ */ 8, 8)
252 /* Bit 7 is Reserved (for future Opcode expansion) */
253 F(3src_hw_opcode, /* 4+ */ 6, 0)
254 /** @} */
255
256 #define REG_TYPE(reg) \
257 static inline void \
258 elk_inst_set_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \
259 elk_inst *inst, enum elk_reg_type type) \
260 { \
261 unsigned hw_type = elk_reg_type_to_a16_hw_3src_type(devinfo, type); \
262 elk_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type); \
263 } \
264 \
265 static inline enum elk_reg_type \
266 elk_inst_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \
267 const elk_inst *inst) \
268 { \
269 unsigned hw_type = elk_inst_3src_a16_##reg##_hw_type(devinfo, inst); \
270 return elk_a16_hw_3src_type_to_reg_type(devinfo, hw_type); \
271 }
272
REG_TYPE(dst)273 REG_TYPE(dst)
274 REG_TYPE(src)
275 #undef REG_TYPE
276
277 /**
278 * Three-source align1 instructions:
279 * @{
280 */
281 F(3src_a1_src2_subreg_nr, /* 4+ */ 117, 113)
282 F(3src_a1_src1_subreg_nr, /* 4+ */ 96, 92)
283 F(3src_a1_src0_subreg_nr, /* 4+ */ 75, 71)
284 F8(3src_a1_src2_reg_file, /* 4+ */ -1, -1, /* 8+ */ 45, 45)
285
286 /** @} */
287
288 /**
289 * Flow control instruction bits:
290 * @{
291 */
292 static inline void
293 elk_inst_set_uip(const struct intel_device_info *devinfo,
294 elk_inst *inst, int32_t value)
295 {
296 assert(devinfo->ver >= 6);
297
298 if (devinfo->ver >= 8) {
299 elk_inst_set_bits(inst, 95, 64, (uint32_t)value);
300 } else {
301 assert(value <= (1 << 16) - 1);
302 assert(value > -(1 << 16));
303 elk_inst_set_bits(inst, 127, 112, (uint16_t)value);
304 }
305 }
306
307 static inline int32_t
elk_inst_uip(const struct intel_device_info * devinfo,const elk_inst * inst)308 elk_inst_uip(const struct intel_device_info *devinfo, const elk_inst *inst)
309 {
310 assert(devinfo->ver >= 6);
311
312 if (devinfo->ver >= 8) {
313 return elk_inst_bits(inst, 95, 64);
314 } else {
315 return (int16_t)elk_inst_bits(inst, 127, 112);
316 }
317 }
318
319 static inline void
elk_inst_set_jip(const struct intel_device_info * devinfo,elk_inst * inst,int32_t value)320 elk_inst_set_jip(const struct intel_device_info *devinfo,
321 elk_inst *inst, int32_t value)
322 {
323 assert(devinfo->ver >= 6);
324
325 if (devinfo->ver >= 8) {
326 elk_inst_set_bits(inst, 127, 96, (uint32_t)value);
327 } else {
328 assert(value <= (1 << 15) - 1);
329 assert(value >= -(1 << 15));
330 elk_inst_set_bits(inst, 111, 96, (uint16_t)value);
331 }
332 }
333
334 static inline int32_t
elk_inst_jip(const struct intel_device_info * devinfo,const elk_inst * inst)335 elk_inst_jip(const struct intel_device_info *devinfo, const elk_inst *inst)
336 {
337 assert(devinfo->ver >= 6);
338
339 if (devinfo->ver >= 8) {
340 return elk_inst_bits(inst, 127, 96);
341 } else {
342 return (int16_t)elk_inst_bits(inst, 111, 96);
343 }
344 }
345
346 /** Like FC, but using int16_t to handle negative jump targets. */
347 #define FJ(name, high, low, assertions) \
348 static inline void \
349 elk_inst_set_##name(const struct intel_device_info *devinfo, elk_inst *inst, int16_t v) \
350 { \
351 assert(assertions); \
352 (void) devinfo; \
353 elk_inst_set_bits(inst, high, low, (uint16_t) v); \
354 } \
355 static inline int16_t \
356 elk_inst_##name(const struct intel_device_info *devinfo, const elk_inst *inst)\
357 { \
358 assert(assertions); \
359 (void) devinfo; \
360 return elk_inst_bits(inst, high, low); \
361 }
362
363 FJ(gfx6_jump_count, 63, 48, devinfo->ver == 6)
364 FJ(gfx4_jump_count, 111, 96, devinfo->ver < 6)
365 FC(gfx4_pop_count, /* 4+ */ 115, 112, devinfo->ver < 6)
366 /** @} */
367
368 /**
369 * SEND instructions:
370 * @{
371 */
372 F8(send_src0_reg_file, /* 4+ */ 38, 37, /* 8+ */ 42, 41)
373 /** @} */
374
375 /* Message descriptor bits */
376 #define MD(x) ((x) + 96)
377 #define MD12(x) ((x) >= 30 ? (x) - 30 + 122 : \
378 (x) >= 25 ? (x) - 25 + 67 : \
379 (x) >= 20 ? (x) - 20 + 51 : \
380 (x) >= 11 ? (x) - 11 + 113 : \
381 (x) - 0 + 81)
382
383 /**
384 * Set the SEND(C) message descriptor immediate.
385 *
386 * This doesn't include the SFID nor the EOT field that were considered to be
387 * part of the message descriptor by ancient versions of the BSpec, because
388 * they are present in the instruction even if the message descriptor is
389 * provided indirectly in the address register, so we want to specify them
390 * separately.
391 */
392 static inline void
elk_inst_set_send_desc(const struct intel_device_info * devinfo,elk_inst * inst,uint32_t value)393 elk_inst_set_send_desc(const struct intel_device_info *devinfo,
394 elk_inst *inst, uint32_t value)
395 {
396 if (devinfo->ver >= 5) {
397 elk_inst_set_bits(inst, 124, 96, value);
398 assert(value >> 29 == 0);
399 } else {
400 elk_inst_set_bits(inst, 119, 96, value);
401 assert(value >> 24 == 0);
402 }
403 }
404
405 /**
406 * Get the SEND(C) message descriptor immediate.
407 *
408 * \sa elk_inst_set_send_desc().
409 */
410 static inline uint32_t
elk_inst_send_desc(const struct intel_device_info * devinfo,const elk_inst * inst)411 elk_inst_send_desc(const struct intel_device_info *devinfo,
412 const elk_inst *inst)
413 {
414 if (devinfo->ver >= 5) {
415 return elk_inst_bits(inst, 124, 96);
416 } else {
417 return elk_inst_bits(inst, 119, 96);
418 }
419 }
420
421 /**
422 * Fields for SEND messages:
423 * @{
424 */
425 F(eot, /* 4+ */ 127, 127)
426 FF(mlen,
427 /* 4: */ 119, 116,
428 /* 4.5: */ 119, 116,
429 /* 5: */ 124, 121,
430 /* 6: */ 124, 121,
431 /* 7: */ 124, 121,
432 /* 8: */ 124, 121)
433 FF(rlen,
434 /* 4: */ 115, 112,
435 /* 4.5: */ 115, 112,
436 /* 5: */ 120, 116,
437 /* 6: */ 120, 116,
438 /* 7: */ 120, 116,
439 /* 8: */ 120, 116)
440 FF(header_present,
441 /* 4: doesn't exist */ -1, -1, -1, -1,
442 /* 5: */ 115, 115,
443 /* 6: */ 115, 115,
444 /* 7: */ 115, 115,
445 /* 8: */ 115, 115)
446 F(gateway_notify, /* 4+ */ MD(16), MD(15))
447 FF(function_control,
448 /* 4: */ 111, 96,
449 /* 4.5: */ 111, 96,
450 /* 5: */ 114, 96,
451 /* 6: */ 114, 96,
452 /* 7: */ 114, 96,
453 /* 8: */ 114, 96)
454 FF(gateway_subfuncid,
455 /* 4: */ MD(1), MD(0),
456 /* 4.5: */ MD(1), MD(0),
457 /* 5: */ MD(1), MD(0), /* 2:0, but bit 2 is reserved MBZ */
458 /* 6: */ MD(2), MD(0),
459 /* 7: */ MD(2), MD(0),
460 /* 8: */ MD(2), MD(0))
461 FF(sfid,
462 /* 4: */ 123, 120, /* called msg_target */
463 /* 4.5 */ 123, 120,
464 /* 5: */ 95, 92,
465 /* 6: */ 27, 24,
466 /* 7: */ 27, 24,
467 /* 8: */ 27, 24)
468 F8(null_rt, /* 4+ */ -1, -1, /* 8+ */ 80, 80)
469 FC(base_mrf, /* 4+ */ 27, 24, devinfo->ver < 6);
470 /** @} */
471
472 /**
473 * URB message function control bits:
474 * @{
475 */
476 FF(urb_per_slot_offset,
477 /* 4-6: */ -1, -1, -1, -1, -1, -1, -1, -1,
478 /* 7: */ MD(16), MD(16),
479 /* 8: */ MD(17), MD(17))
480 FC(urb_channel_mask_present, /* 4+ */ MD(15), MD(15), devinfo->ver >= 8)
481 FC(urb_complete, /* 4+ */ MD(15), MD(15), devinfo->ver < 8)
482 FC(urb_used, /* 4+ */ MD(14), MD(14), devinfo->ver < 7)
483 FC(urb_allocate, /* 4+ */ MD(13), MD(13), devinfo->ver < 7)
484 FF(urb_swizzle_control,
485 /* 4: */ MD(11), MD(10),
486 /* 4.5: */ MD(11), MD(10),
487 /* 5: */ MD(11), MD(10),
488 /* 6: */ MD(11), MD(10),
489 /* 7: */ MD(14), MD(14),
490 /* 8: */ MD(15), MD(15))
491 FF(urb_global_offset,
492 /* 4: */ MD( 9), MD(4),
493 /* 4.5: */ MD( 9), MD(4),
494 /* 5: */ MD( 9), MD(4),
495 /* 6: */ MD( 9), MD(4),
496 /* 7: */ MD(13), MD(3),
497 /* 8: */ MD(14), MD(4))
498 FF(urb_opcode,
499 /* 4: */ MD( 3), MD(0),
500 /* 4.5: */ MD( 3), MD(0),
501 /* 5: */ MD( 3), MD(0),
502 /* 6: */ MD( 3), MD(0),
503 /* 7: */ MD( 2), MD(0),
504 /* 8: */ MD( 3), MD(0))
505 /** @} */
506
507 /**
508 * Gfx4-5 math messages:
509 * @{
510 */
511 FC(math_msg_data_type, /* 4+ */ MD(7), MD(7), devinfo->ver < 6)
512 FC(math_msg_saturate, /* 4+ */ MD(6), MD(6), devinfo->ver < 6)
513 FC(math_msg_precision, /* 4+ */ MD(5), MD(5), devinfo->ver < 6)
514 FC(math_msg_signed_int, /* 4+ */ MD(4), MD(4), devinfo->ver < 6)
515 FC(math_msg_function, /* 4+ */ MD(3), MD(0), devinfo->ver < 6)
516 /** @} */
517
518 /**
519 * Sampler message function control bits:
520 * @{
521 */
522 FF(sampler_simd_mode,
523 /* 4: doesn't exist */ -1, -1, -1, -1,
524 /* 5: */ MD(17), MD(16),
525 /* 6: */ MD(17), MD(16),
526 /* 7: */ MD(18), MD(17),
527 /* 8: */ MD(18), MD(17))
528 FF(sampler_msg_type,
529 /* 4: */ MD(15), MD(14),
530 /* 4.5: */ MD(15), MD(12),
531 /* 5: */ MD(15), MD(12),
532 /* 6: */ MD(15), MD(12),
533 /* 7: */ MD(16), MD(12),
534 /* 8: */ MD(16), MD(12))
535 FC(sampler_return_format, /* 4+ */ MD(13), MD(12), devinfo->verx10 == 40)
536 FF(sampler,
537 /* 4: */ MD(11), MD(8),
538 /* 4.5: */ MD(11), MD(8),
539 /* 5: */ MD(11), MD(8),
540 /* 6: */ MD(11), MD(8),
541 /* 7: */ MD(11), MD(8),
542 /* 8: */ MD(11), MD(8))
543 F(binding_table_index, /* 4+ */ MD(7), MD(0)) /* also used by other messages */
544 /** @} */
545
546 /**
547 * Data port message function control bits:
548 * @{
549 */
550 FC(dp_category, /* 4+ */ MD(18), MD(18), devinfo->ver >= 7)
551
552 /* Gfx4-5 store fields in different bits for read/write messages. */
553 FF(dp_read_msg_type,
554 /* 4: */ MD(13), MD(12),
555 /* 4.5: */ MD(13), MD(11),
556 /* 5: */ MD(13), MD(11),
557 /* 6: */ MD(16), MD(13),
558 /* 7: */ MD(17), MD(14),
559 /* 8: */ MD(17), MD(14))
560 FF(dp_write_msg_type,
561 /* 4: */ MD(14), MD(12),
562 /* 4.5: */ MD(14), MD(12),
563 /* 5: */ MD(14), MD(12),
564 /* 6: */ MD(16), MD(13),
565 /* 7: */ MD(17), MD(14),
566 /* 8: */ MD(17), MD(14))
567 FF(dp_read_msg_control,
568 /* 4: */ MD(11), MD( 8),
569 /* 4.5: */ MD(10), MD( 8),
570 /* 5: */ MD(10), MD( 8),
571 /* 6: */ MD(12), MD( 8),
572 /* 7: */ MD(13), MD( 8),
573 /* 8: */ MD(13), MD( 8))
574 FF(dp_write_msg_control,
575 /* 4: */ MD(11), MD( 8),
576 /* 4.5: */ MD(11), MD( 8),
577 /* 5: */ MD(11), MD( 8),
578 /* 6: */ MD(12), MD( 8),
579 /* 7: */ MD(13), MD( 8),
580 /* 8: */ MD(13), MD( 8))
581 FC(dp_read_target_cache, /* 4+ */ MD(15), MD(14), devinfo->ver < 6);
582
583 FF(dp_write_commit,
584 /* 4: */ MD(15), MD(15),
585 /* 4.5: */ MD(15), MD(15),
586 /* 5: */ MD(15), MD(15),
587 /* 6: */ MD(17), MD(17),
588 /* 7+: does not exist */ -1, -1, -1, -1)
589
590 /* Gfx6+ use the same bit locations for everything. */
591 FF(dp_msg_type,
592 /* 4-5: use dp_read_msg_type or dp_write_msg_type instead */
593 -1, -1, -1, -1, -1, -1,
594 /* 6: */ MD(16), MD(13),
595 /* 7: */ MD(17), MD(14),
596 /* 8: */ MD(18), MD(14))
597 FF(dp_msg_control,
598 /* 4: */ MD(11), MD( 8),
599 /* 4.5-5: use dp_read_msg_control or dp_write_msg_control */ -1, -1, -1, -1,
600 /* 6: */ MD(12), MD( 8),
601 /* 7: */ MD(13), MD( 8),
602 /* 8: */ MD(13), MD( 8))
603 /** @} */
604
605 /**
606 * Scratch message bits (Gfx7+):
607 * @{
608 */
609 FC(scratch_read_write, /* 4+ */ MD(17), MD(17), devinfo->ver >= 7) /* 0 = read, 1 = write */
610 FC(scratch_type, /* 4+ */ MD(16), MD(16), devinfo->ver >= 7) /* 0 = OWord, 1 = DWord */
611 FC(scratch_invalidate_after_read, /* 4+ */ MD(15), MD(15), devinfo->ver >= 7)
612 FC(scratch_block_size, /* 4+ */ MD(13), MD(12), devinfo->ver >= 7)
613 FF(scratch_addr_offset,
614 /* 4: */ -1, -1,
615 /* 4.5: */ -1, -1,
616 /* 5: */ -1, -1,
617 /* 6: */ -1, -1,
618 /* 7: */ MD(11), MD(0),
619 /* 8: */ MD(11), MD(0))
620 /** @} */
621
622 /**
623 * Render Target message function control bits:
624 * @{
625 */
626 FF(rt_last,
627 /* 4: */ MD(11), MD(11),
628 /* 4.5: */ MD(11), MD(11),
629 /* 5: */ MD(11), MD(11),
630 /* 6: */ MD(12), MD(12),
631 /* 7: */ MD(12), MD(12),
632 /* 8: */ MD(12), MD(12))
633 FC(rt_slot_group, /* 4+ */ MD(11), MD(11), devinfo->ver >= 6)
634 F(rt_message_type, /* 4+ */ MD(10), MD( 8))
635 /** @} */
636
637 /**
638 * Thread Spawn message function control bits:
639 * @{
640 */
641 F(ts_resource_select, /* 4+ */ MD( 4), MD( 4))
642 F(ts_request_type, /* 4+ */ MD( 1), MD( 1))
643 F(ts_opcode, /* 4+ */ MD( 0), MD( 0))
644 /** @} */
645
646 /**
647 * Pixel Interpolator message function control bits:
648 * @{
649 */
650 F(pi_simd_mode, /* 4+ */ MD(16), MD(16))
651 F(pi_nopersp, /* 4+ */ MD(14), MD(14))
652 F(pi_message_type, /* 4+ */ MD(13), MD(12))
653 F(pi_slot_group, /* 4+ */ MD(11), MD(11))
654 F(pi_message_data, /* 4+ */ MD(7), MD(0))
655 /** @} */
656
657 /**
658 * Immediates:
659 * @{
660 */
661 static inline int
elk_inst_imm_d(const struct intel_device_info * devinfo,const elk_inst * insn)662 elk_inst_imm_d(const struct intel_device_info *devinfo, const elk_inst *insn)
663 {
664 (void) devinfo;
665 return elk_inst_bits(insn, 127, 96);
666 }
667
668 static inline unsigned
elk_inst_imm_ud(const struct intel_device_info * devinfo,const elk_inst * insn)669 elk_inst_imm_ud(const struct intel_device_info *devinfo, const elk_inst *insn)
670 {
671 (void) devinfo;
672 return elk_inst_bits(insn, 127, 96);
673 }
674
675 static inline uint64_t
elk_inst_imm_uq(const struct intel_device_info * devinfo,const elk_inst * insn)676 elk_inst_imm_uq(const struct intel_device_info *devinfo,
677 const elk_inst *insn)
678 {
679 assert(devinfo->ver >= 8);
680 return elk_inst_bits(insn, 127, 64);
681 }
682
683 static inline float
elk_inst_imm_f(const struct intel_device_info * devinfo,const elk_inst * insn)684 elk_inst_imm_f(const struct intel_device_info *devinfo, const elk_inst *insn)
685 {
686 union {
687 float f;
688 uint32_t u;
689 } ft;
690 (void) devinfo;
691 ft.u = elk_inst_bits(insn, 127, 96);
692 return ft.f;
693 }
694
695 static inline double
elk_inst_imm_df(const struct intel_device_info * devinfo,const elk_inst * insn)696 elk_inst_imm_df(const struct intel_device_info *devinfo, const elk_inst *insn)
697 {
698 union {
699 double d;
700 uint64_t u;
701 } dt;
702 dt.u = elk_inst_imm_uq(devinfo, insn);
703 return dt.d;
704 }
705
706 static inline void
elk_inst_set_imm_d(const struct intel_device_info * devinfo,elk_inst * insn,int value)707 elk_inst_set_imm_d(const struct intel_device_info *devinfo,
708 elk_inst *insn, int value)
709 {
710 (void) devinfo;
711 return elk_inst_set_bits(insn, 127, 96, value);
712 }
713
714 static inline void
elk_inst_set_imm_ud(const struct intel_device_info * devinfo,elk_inst * insn,unsigned value)715 elk_inst_set_imm_ud(const struct intel_device_info *devinfo,
716 elk_inst *insn, unsigned value)
717 {
718 (void) devinfo;
719 return elk_inst_set_bits(insn, 127, 96, value);
720 }
721
722 static inline void
elk_inst_set_imm_f(const struct intel_device_info * devinfo,elk_inst * insn,float value)723 elk_inst_set_imm_f(const struct intel_device_info *devinfo,
724 elk_inst *insn, float value)
725 {
726 union {
727 float f;
728 uint32_t u;
729 } ft;
730 (void) devinfo;
731 ft.f = value;
732 elk_inst_set_bits(insn, 127, 96, ft.u);
733 }
734
735 static inline void
elk_inst_set_imm_df(const struct intel_device_info * devinfo,elk_inst * insn,double value)736 elk_inst_set_imm_df(const struct intel_device_info *devinfo,
737 elk_inst *insn, double value)
738 {
739 union {
740 double d;
741 uint64_t u;
742 } dt;
743 (void) devinfo;
744 dt.d = value;
745
746 elk_inst_set_bits(insn, 127, 64, dt.u);
747 }
748
749 static inline void
elk_inst_set_imm_uq(const struct intel_device_info * devinfo,elk_inst * insn,uint64_t value)750 elk_inst_set_imm_uq(const struct intel_device_info *devinfo,
751 elk_inst *insn, uint64_t value)
752 {
753 (void) devinfo;
754 elk_inst_set_bits(insn, 127, 64, value);
755 }
756
757 /** @} */
758
759 #define REG_TYPE(reg) \
760 static inline void \
761 elk_inst_set_##reg##_file_type(const struct intel_device_info *devinfo, \
762 elk_inst *inst, enum elk_reg_file file, \
763 enum elk_reg_type type) \
764 { \
765 assert(file <= ELK_IMMEDIATE_VALUE); \
766 unsigned hw_type = elk_reg_type_to_hw_type(devinfo, file, type); \
767 elk_inst_set_##reg##_reg_file(devinfo, inst, file); \
768 elk_inst_set_##reg##_reg_hw_type(devinfo, inst, hw_type); \
769 } \
770 \
771 static inline enum elk_reg_type \
772 elk_inst_##reg##_type(const struct intel_device_info *devinfo, \
773 const elk_inst *inst) \
774 { \
775 unsigned file = __builtin_strcmp("dst", #reg) == 0 ? \
776 (unsigned) ELK_GENERAL_REGISTER_FILE : \
777 elk_inst_##reg##_reg_file(devinfo, inst); \
778 unsigned hw_type = elk_inst_##reg##_reg_hw_type(devinfo, inst); \
779 return elk_hw_type_to_reg_type(devinfo, (enum elk_reg_file)file, hw_type); \
780 }
781
782 REG_TYPE(dst)
REG_TYPE(src0)783 REG_TYPE(src0)
784 REG_TYPE(src1)
785 #undef REG_TYPE
786
787
788 /* The AddrImm fields are split into two discontiguous sections on Gfx8+ */
789 #define ELK_IA1_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \
790 static inline void \
791 elk_inst_set_##reg##_ia1_addr_imm(const struct \
792 intel_device_info *devinfo, \
793 elk_inst *inst, \
794 unsigned value) \
795 { \
796 if (devinfo->ver >= 8) { \
797 assert((value & ~0x3ff) == 0); \
798 elk_inst_set_bits(inst, g8_high, g8_low, value & 0x1ff); \
799 elk_inst_set_bits(inst, g8_nine, g8_nine, value >> 9); \
800 } else { \
801 assert((value & ~0x3ff) == 0); \
802 elk_inst_set_bits(inst, g4_high, g4_low, value); \
803 } \
804 } \
805 static inline unsigned \
806 elk_inst_##reg##_ia1_addr_imm(const struct intel_device_info *devinfo, \
807 const elk_inst *inst) \
808 { \
809 if (devinfo->ver >= 8) { \
810 return elk_inst_bits(inst, g8_high, g8_low) | \
811 (elk_inst_bits(inst, g8_nine, g8_nine) << 9); \
812 } else { \
813 return elk_inst_bits(inst, g4_high, g4_low); \
814 } \
815 }
816
817 /* AddrImm for Align1 Indirect Addressing */
818 /* -Gen 4- ----Gfx8---- */
819 ELK_IA1_ADDR_IMM(src1, 105, 96, 121, 104, 96)
820 ELK_IA1_ADDR_IMM(src0, 73, 64, 95, 72, 64)
821 ELK_IA1_ADDR_IMM(dst, 57, 48, 47, 56, 48)
822
823 #define ELK_IA16_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \
824 static inline void \
825 elk_inst_set_##reg##_ia16_addr_imm(const struct \
826 intel_device_info *devinfo, \
827 elk_inst *inst, unsigned value) \
828 { \
829 assert((value & ~0x3ff) == 0); \
830 if (devinfo->ver >= 8) { \
831 assert(GET_BITS(value, 3, 0) == 0); \
832 elk_inst_set_bits(inst, g8_high, g8_low, GET_BITS(value, 8, 4)); \
833 elk_inst_set_bits(inst, g8_nine, g8_nine, GET_BITS(value, 9, 9)); \
834 } else { \
835 elk_inst_set_bits(inst, g4_high, g4_low, value); \
836 } \
837 } \
838 static inline unsigned \
839 elk_inst_##reg##_ia16_addr_imm(const struct intel_device_info *devinfo, \
840 const elk_inst *inst) \
841 { \
842 if (devinfo->ver >= 8) { \
843 return (elk_inst_bits(inst, g8_high, g8_low) << 4) | \
844 (elk_inst_bits(inst, g8_nine, g8_nine) << 9); \
845 } else { \
846 return elk_inst_bits(inst, g4_high, g4_low); \
847 } \
848 }
849
850 /* AddrImm[9:0] for Align16 Indirect Addressing:
851 * Compared to Align1, these are missing the low 4 bits.
852 * -Gen 4- ----Gfx8----
853 */
854 ELK_IA16_ADDR_IMM(src1, 105, 96, 121, 104, 100)
855 ELK_IA16_ADDR_IMM(src0, 73, 64, 95, 72, 68)
856 ELK_IA16_ADDR_IMM(dst, 57, 52, 47, 56, 52)
857 ELK_IA16_ADDR_IMM(send_src0, -1, -1, 78, 72, 68)
858 ELK_IA16_ADDR_IMM(send_dst, -1, -1, 62, 56, 52)
859
860 /**
861 * Fetch a set of contiguous bits from the instruction.
862 *
863 * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
864 */
865 static inline uint64_t
866 elk_inst_bits(const elk_inst *inst, unsigned high, unsigned low)
867 {
868 assume(high < 128);
869 assume(high >= low);
870 /* We assume the field doesn't cross 64-bit boundaries. */
871 const unsigned word = high / 64;
872 assert(word == low / 64);
873
874 high %= 64;
875 low %= 64;
876
877 const uint64_t mask = (~0ull >> (64 - (high - low + 1)));
878
879 return (inst->data[word] >> low) & mask;
880 }
881
882 /**
883 * Set bits in the instruction, with proper shifting and masking.
884 *
885 * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
886 */
887 static inline void
elk_inst_set_bits(elk_inst * inst,unsigned high,unsigned low,uint64_t value)888 elk_inst_set_bits(elk_inst *inst, unsigned high, unsigned low, uint64_t value)
889 {
890 assume(high < 128);
891 assume(high >= low);
892 const unsigned word = high / 64;
893 assert(word == low / 64);
894
895 high %= 64;
896 low %= 64;
897
898 const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low;
899
900 /* Make sure the supplied value actually fits in the given bitfield. */
901 assert((value & (mask >> low)) == value);
902
903 inst->data[word] = (inst->data[word] & ~mask) | (value << low);
904 }
905
906 #undef ELK_IA16_ADDR_IMM
907 #undef ELK_IA1_ADDR_IMM
908 #undef MD
909 #undef F8
910 #undef FF
911 #undef BOUNDS
912 #undef F
913 #undef FC
914 #undef F20
915 #undef FD20
916
917 typedef struct {
918 uint64_t data;
919 } elk_compact_inst;
920
921 /**
922 * Fetch a set of contiguous bits from the compacted instruction.
923 *
924 * Bits indices range from 0..63.
925 */
926 static inline unsigned
elk_compact_inst_bits(const elk_compact_inst * inst,unsigned high,unsigned low)927 elk_compact_inst_bits(const elk_compact_inst *inst, unsigned high, unsigned low)
928 {
929 assume(high < 64);
930 assume(high >= low);
931 const uint64_t mask = (1ull << (high - low + 1)) - 1;
932
933 return (inst->data >> low) & mask;
934 }
935
936 /**
937 * Set bits in the compacted instruction.
938 *
939 * Bits indices range from 0..63.
940 */
941 static inline void
elk_compact_inst_set_bits(elk_compact_inst * inst,unsigned high,unsigned low,uint64_t value)942 elk_compact_inst_set_bits(elk_compact_inst *inst, unsigned high, unsigned low,
943 uint64_t value)
944 {
945 assume(high < 64);
946 assume(high >= low);
947 const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low;
948
949 /* Make sure the supplied value actually fits in the given bitfield. */
950 assert((value & (mask >> low)) == value);
951
952 inst->data = (inst->data & ~mask) | (value << low);
953 }
954
955 #define FC(name, high, low, assertions) \
956 static inline void \
957 elk_compact_inst_set_##name(const struct \
958 intel_device_info *devinfo, \
959 elk_compact_inst *inst, unsigned v) \
960 { \
961 assert(assertions); \
962 elk_compact_inst_set_bits(inst, high, low, v); \
963 } \
964 static inline unsigned \
965 elk_compact_inst_##name(const struct intel_device_info *devinfo, \
966 const elk_compact_inst *inst) \
967 { \
968 assert(assertions); \
969 return elk_compact_inst_bits(inst, high, low); \
970 }
971
972 /* A simple macro for fields which stay in the same place on all generations. */
973 #define F(name, high, low) FC(name, high, low, true)
974
975 /* A macro for fields which moved as of Gfx8+. */
976 #define F8(name, high, low, hi8, lo8) \
977 static inline void \
978 elk_compact_inst_set_##name(const struct \
979 intel_device_info *devinfo, \
980 elk_compact_inst *inst, unsigned v) \
981 { \
982 if (devinfo->ver >= 8) \
983 elk_compact_inst_set_bits(inst, hi8, lo8, v); \
984 else \
985 elk_compact_inst_set_bits(inst, high, low, v); \
986 } \
987 static inline unsigned \
988 elk_compact_inst_##name(const struct intel_device_info *devinfo, \
989 const elk_compact_inst *inst) \
990 { \
991 if (devinfo->ver >= 8) \
992 return elk_compact_inst_bits(inst, hi8, lo8); \
993 else \
994 return elk_compact_inst_bits(inst, high, low); \
995 }
996
997 F(src1_reg_nr, /* 4+ */ 63, 56)
998 F(src0_reg_nr, /* 4+ */ 55, 48)
999 F8(dst_reg_nr, /* 4+ */ 47, 40, /* 8+ */ 47, 40)
1000 F(src1_index, /* 4+ */ 39, 35)
1001 F8(src0_index, /* 4+ */ 34, 30, /* 8+ */ 34, 30)
1002 F(cmpt_control, /* 4+ */ 29, 29) /* Same location as elk_inst */
1003 FC(flag_subreg_nr, /* 4+ */ 28, 28, devinfo->ver <= 6)
1004 F(cond_modifier, /* 4+ */ 27, 24) /* Same location as elk_inst */
1005 FC(acc_wr_control, /* 4+ */ 23, 23, devinfo->ver >= 6)
1006 FC(mask_control_ex, /* 4+ */ 23, 23, devinfo->verx10 == 45 || devinfo->ver == 5)
1007 F8(subreg_index, /* 4+ */ 22, 18, /* 8+ */ 22, 18)
1008 F8(datatype_index, /* 4+ */ 17, 13, /* 8+ */ 17, 13)
1009 F8(control_index, /* 4+ */ 12, 8, /* 8+ */ 12, 8)
1010 F(debug_control, /* 4+ */ 7, 7)
1011 F(hw_opcode, /* 4+ */ 6, 0) /* Same location as elk_inst */
1012
1013 static inline unsigned
elk_compact_inst_imm(const struct intel_device_info * devinfo,const elk_compact_inst * inst)1014 elk_compact_inst_imm(const struct intel_device_info *devinfo,
1015 const elk_compact_inst *inst)
1016 {
1017 return (elk_compact_inst_bits(inst, 39, 35) << 8) |
1018 (elk_compact_inst_bits(inst, 63, 56));
1019 }
1020
1021 /**
1022 * (Gfx8+) Compacted three-source instructions:
1023 * @{
1024 */
1025 FC(3src_src2_reg_nr, /* 4+ */ 63, 57, devinfo->ver >= 8)
1026 FC(3src_src1_reg_nr, /* 4+ */ 56, 50, devinfo->ver >= 8)
1027 FC(3src_src0_reg_nr, /* 4+ */ 49, 43, devinfo->ver >= 8)
1028 FC(3src_src2_subreg_nr, /* 4+ */ 42, 40, devinfo->ver >= 8)
1029 FC(3src_src1_subreg_nr, /* 4+ */ 39, 37, devinfo->ver >= 8)
1030 FC(3src_src0_subreg_nr, /* 4+ */ 36, 34, devinfo->ver >= 8)
1031 FC(3src_src2_rep_ctrl, /* 4+ */ 33, 33, devinfo->ver >= 8)
1032 FC(3src_src1_rep_ctrl, /* 4+ */ 32, 32, devinfo->ver >= 8)
1033 FC(3src_saturate, /* 4+ */ 31, 31, devinfo->ver >= 8)
1034 FC(3src_debug_control, /* 4+ */ 30, 30, devinfo->ver >= 8)
1035 FC(3src_cmpt_control, /* 4+ */ 29, 29, devinfo->ver >= 8)
1036 FC(3src_src0_rep_ctrl, /* 4+ */ 28, 28, devinfo->ver >= 8)
1037 /* Reserved */
1038 F8(3src_dst_reg_nr, /* 4+ */ 18, 12, /* 8+ */ 18, 12)
1039 F8(3src_source_index, /* 4+ */ -1, -1, /* 8+ */ 11, 10)
1040 F8(3src_control_index, /* 4+ */ -1, -1, /* 8+ */ 9, 8)
1041 /* Bit 7 is Reserved (for future Opcode expansion) */
1042 FC(3src_hw_opcode, /* 4+ */ 6, 0, devinfo->ver >= 8)
1043 /** @} */
1044
1045 #undef F
1046
1047 static inline void
elk_inst_set_opcode(const struct elk_isa_info * isa,struct elk_inst * inst,enum elk_opcode opcode)1048 elk_inst_set_opcode(const struct elk_isa_info *isa,
1049 struct elk_inst *inst, enum elk_opcode opcode)
1050 {
1051 elk_inst_set_hw_opcode(isa->devinfo, inst, elk_opcode_encode(isa, opcode));
1052 }
1053
1054 static inline enum elk_opcode
elk_inst_opcode(const struct elk_isa_info * isa,const struct elk_inst * inst)1055 elk_inst_opcode(const struct elk_isa_info *isa,
1056 const struct elk_inst *inst)
1057 {
1058 return elk_opcode_decode(isa, elk_inst_hw_opcode(isa->devinfo, inst));
1059 }
1060
1061 #ifdef __cplusplus
1062 }
1063 #endif
1064