1 /*
2 * Copyright © 2012 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 /** @file gen8_instruction.h
25 *
26 * A representation of a Gen8+ EU instruction, with helper methods to get
27 * and set various fields. This is the actual hardware format.
28 */
29
30 #ifndef GEN8_INSTRUCTION_H
31 #define GEN8_INSTRUCTION_H
32
33 #include <stdio.h>
34 #include <stdint.h>
35
36 #include "brw_compat.h"
37 #include "brw_reg.h"
38
39 struct gen8_instruction {
40 uint32_t data[4];
41 };
42
43 static inline unsigned gen8_bits(struct gen8_instruction *insn,
44 unsigned high,
45 unsigned low);
46 static inline void gen8_set_bits(struct gen8_instruction *insn,
47 unsigned high,
48 unsigned low,
49 unsigned value);
50
51 #define F(name, high, low) \
52 static inline void gen8_set_##name(struct gen8_instruction *insn, unsigned v) \
53 { \
54 gen8_set_bits(insn, high, low, v); \
55 } \
56 static inline unsigned gen8_##name(struct gen8_instruction *insn) \
57 { \
58 return gen8_bits(insn, high, low); \
59 }
60
61 /**
62 * Direct addressing only:
63 * @{
64 */
65 F(src1_da_reg_nr, 108, 101);
66 F(src0_da_reg_nr, 76, 69);
67 F(dst_da1_hstride, 62, 61);
68 F(dst_da_reg_nr, 60, 53);
69 F(dst_da16_subreg_nr, 52, 52);
70 F(dst_da1_subreg_nr, 52, 48);
71 F(da16_writemask, 51, 48); /* Dst.ChanEn */
72 /** @} */
73
74 F(src1_vert_stride, 120, 117)
75 F(src1_da1_width, 116, 114)
76 F(src1_da16_swiz_w, 115, 114)
77 F(src1_da16_swiz_z, 113, 112)
78 F(src1_da1_hstride, 113, 112)
79 F(src1_address_mode, 111, 111)
80 /** Src1.SrcMod @{ */
81 F(src1_negate, 110, 110)
82 F(src1_abs, 109, 109)
83 /** @} */
84 F(src1_da16_subreg_nr, 100, 100)
85 F(src1_da1_subreg_nr, 100, 96)
86 F(src1_da16_swiz_y, 99, 98)
87 F(src1_da16_swiz_x, 97, 96)
88 F(src1_reg_type, 94, 91)
89 F(src1_reg_file, 90, 89)
90 F(src0_vert_stride, 88, 85)
91 F(src0_da1_width, 84, 82)
92 F(src0_da16_swiz_w, 83, 82)
93 F(src0_da16_swiz_z, 81, 80)
94 F(src0_da1_hstride, 81, 80)
95 F(src0_address_mode, 79, 79)
96 /** Src0.SrcMod @{ */
97 F(src0_negate, 78, 78)
98 F(src0_abs, 77, 77)
99 /** @} */
100 F(src0_da16_subreg_nr, 68, 68)
101 F(src0_da1_subreg_nr, 68, 64)
102 F(src0_da16_swiz_y, 67, 66)
103 F(src0_da16_swiz_x, 65, 64)
104 F(dst_address_mode, 63, 63)
105 F(src0_reg_type, 46, 43)
106 F(src0_reg_file, 42, 41)
107 F(dst_reg_type, 40, 37)
108 F(dst_reg_file, 36, 35)
109 F(mask_control, 34, 34)
110 F(flag_reg_nr, 33, 33)
111 F(flag_subreg_nr, 32, 32)
112 F(saturate, 31, 31)
113 F(branch_control, 30, 30)
114 F(debug_control, 30, 30)
115 F(cmpt_control, 29, 29)
116 F(acc_wr_control, 28, 28)
117 F(cond_modifier, 27, 24)
118 F(exec_size, 23, 21)
119 F(pred_inv, 20, 20)
120 F(pred_control, 19, 16)
121 F(thread_control, 15, 14)
122 F(qtr_control, 13, 12)
123 F(nib_control, 11, 11)
124 F(dep_control, 10, 9)
125 F(access_mode, 8, 8)
126 /* Bit 7 is Reserve d (for future Opcode expansion) */
127 F(opcode, 6, 0)
128
129 /**
130 * Three-source instructions:
131 * @{
132 */
133 F(src2_3src_reg_nr, 125, 118)
134 F(src2_3src_subreg_nr, 117, 115)
135 F(src2_3src_swizzle, 114, 107)
136 F(src2_3src_rep_ctrl, 106, 106)
137 F(src1_3src_reg_nr, 104, 97)
138 F(src1_3src_subreg_hi, 96, 96)
139 F(src1_3src_subreg_lo, 95, 94)
140 F(src1_3src_swizzle, 93, 86)
141 F(src1_3src_rep_ctrl, 85, 85)
142 F(src0_3src_reg_nr, 83, 76)
143 F(src0_3src_subreg_nr, 75, 73)
144 F(src0_3src_swizzle, 72, 65)
145 F(src0_3src_rep_ctrl, 64, 64)
146 F(dst_3src_reg_nr, 63, 56)
147 F(dst_3src_subreg_nr, 55, 53)
148 F(dst_3src_writemask, 52, 49)
149 F(dst_3src_type, 48, 46)
150 F(src_3src_type, 45, 43)
151 F(src2_3src_negate, 42, 42)
152 F(src2_3src_abs, 41, 41)
153 F(src1_3src_negate, 40, 40)
154 F(src1_3src_abs, 39, 39)
155 F(src0_3src_negate, 38, 38)
156 F(src0_3src_abs, 37, 37)
157 /** @} */
158
159 /**
160 * Fields for SEND messages:
161 * @{
162 */
163 F(eot, 127, 127)
164 F(mlen, 124, 121)
165 F(rlen, 120, 116)
166 F(header_present, 115, 115)
167 F(function_control, 114, 96)
168 F(sfid, 27, 24)
169 F(math_function, 27, 24)
170 /** @} */
171
172 /**
173 * URB message function control bits:
174 * @{
175 */
176 F(urb_per_slot_offset, 113, 113)
177 F(urb_interleave, 111, 111)
178 F(urb_global_offset, 110, 100)
179 F(urb_opcode, 99, 96)
180 /** @} */
181
182 /**
183 * Sampler message function control bits:
184 * @{
185 */
186 F(sampler_simd_mode, 114, 113)
187 F(sampler_msg_type, 112, 108)
188 F(sampler, 107, 104)
189 F(binding_table_index, 103, 96)
190 /** @} */
191
192 /**
193 * Data port message function control bits:
194 * @ {
195 */
196 F(dp_category, 114, 114)
197 F(dp_message_type, 113, 110)
198 F(dp_message_control, 109, 104)
199 F(dp_binding_table_index, 103, 96)
200 /** @} */
201
202 /**
203 * Thread Spawn message function control bits:
204 * @ {
205 */
206 F(ts_resource_select, 100, 100)
207 F(ts_request_type, 97, 97)
208 F(ts_opcode, 96, 96)
209 /** @} */
210
211 /**
212 * Video Motion Estimation message function control bits:
213 * @ {
214 */
215 F(vme_message_type, 110, 109)
216 F(vme_binding_table_index, 103, 96)
217 /** @} */
218
219 /**
220 * Check & Refinement Engine message function control bits:
221 * @ {
222 */
223 F(cre_message_type, 110, 109)
224 F(cre_binding_table_index, 103, 96)
225 /** @} */
226
227 /* Addr Mode */
228
229 F(dst_addr_mode, 63, 63)
230 F(src0_addr_mode, 79, 79)
231 F(src1_addr_mode, 111, 111)
232
233 /* Indirect access mode for Align1. */
234 F(dst_ida1_sub_nr, 60, 57)
235 F(src0_ida1_sub_nr, 76, 73)
236 F(src1_ida1_sub_nr, 108, 105)
237
238 /* Imm[8:0] of Immediate addr offset under Indirect mode */
239 F(dst_ida1_imm8, 56, 48)
240 F(src0_ida1_imm8, 72, 64)
241 F(src1_ida1_imm8, 104, 96)
242
243 /* Imm Bit9 of Immediate addr offset under Indirect mode */
244 F(dst_ida1_imm9, 47, 47)
245 F(src0_ida1_imm9, 95, 95)
246 F(src1_ida1_imm9, 121, 121)
247
248 #undef F
249
250 #define IMM8_MASK 0x1FF
251 #define IMM9_MASK 0x200
252
253 /**
254 * Flow control instruction bits:
255 * @{
256 */
gen8_uip(struct gen8_instruction * insn)257 static inline unsigned gen8_uip(struct gen8_instruction *insn)
258 {
259 return insn->data[2];
260 }
gen8_set_uip(struct gen8_instruction * insn,unsigned uip)261 static inline void gen8_set_uip(struct gen8_instruction *insn, unsigned uip)
262 {
263 insn->data[2] = uip;
264 }
gen8_jip(struct gen8_instruction * insn)265 static inline unsigned gen8_jip(struct gen8_instruction *insn)
266 {
267 return insn->data[3];
268 }
gen8_set_jip(struct gen8_instruction * insn,unsigned jip)269 static inline void gen8_set_jip(struct gen8_instruction *insn, unsigned jip)
270 {
271 insn->data[3] = jip;
272 }
273 /** @} */
274
gen8_src1_imm_d(struct gen8_instruction * insn)275 static inline int gen8_src1_imm_d(struct gen8_instruction *insn)
276 {
277 return insn->data[3];
278 }
gen8_src1_imm_ud(struct gen8_instruction * insn)279 static inline unsigned gen8_src1_imm_ud(struct gen8_instruction *insn)
280 {
281 return insn->data[3];
282 }
gen8_src1_imm_f(struct gen8_instruction * insn)283 static inline float gen8_src1_imm_f(struct gen8_instruction *insn)
284 {
285 fi_type ft;
286
287 ft.u = insn->data[3];
288 return ft.f;
289 }
290
291 void gen8_set_dst(struct gen8_instruction *insn, struct brw_reg reg);
292 void gen8_set_src0(struct gen8_instruction *insn, struct brw_reg reg);
293 void gen8_set_src1(struct gen8_instruction *insn, struct brw_reg reg);
294
295 void gen8_set_urb_message(struct gen8_instruction *insn,
296 unsigned opcode, unsigned mlen, unsigned rlen,
297 bool eot, unsigned offset, bool interleave);
298
299 void gen8_set_sampler_message(struct gen8_instruction *insn,
300 unsigned binding_table_index, unsigned sampler,
301 unsigned msg_type, unsigned rlen, unsigned mlen,
302 bool header_present, unsigned simd_mode);
303
304 void gen8_set_dp_message(struct gen8_instruction *insn,
305 enum brw_message_target sfid,
306 unsigned binding_table_index,
307 unsigned msg_type,
308 unsigned msg_control,
309 unsigned msg_length,
310 unsigned response_length,
311 bool header_present,
312 bool end_of_thread);
313
314 /** Disassemble the instruction. */
315 int gen8_disassemble(FILE *file, struct gen8_instruction *insn, int gen);
316
317
318 /**
319 * Fetch a set of contiguous bits from the instruction.
320 *
321 * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
322 */
323 static inline unsigned
gen8_bits(struct gen8_instruction * insn,unsigned high,unsigned low)324 gen8_bits(struct gen8_instruction *insn, unsigned high, unsigned low)
325 {
326 /* We assume the field doesn't cross 32-bit boundaries. */
327 const unsigned word = high / 32;
328 assert(word == low / 32);
329
330 high %= 32;
331 low %= 32;
332
333 const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
334
335 return (insn->data[word] & mask) >> low;
336 }
337
338 /**
339 * Set bits in the instruction, with proper shifting and masking.
340 *
341 * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
342 */
343 static inline void
gen8_set_bits(struct gen8_instruction * insn,unsigned high,unsigned low,unsigned value)344 gen8_set_bits(struct gen8_instruction *insn,
345 unsigned high,
346 unsigned low,
347 unsigned value)
348 {
349 const unsigned word = high / 32;
350 assert(word == low / 32);
351
352 high %= 32;
353 low %= 32;
354
355 const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
356
357 insn->data[word] = (insn->data[word] & ~mask) | ((value << low) & mask);
358 }
359
360 void gen9_set_send_extdesc(struct gen8_instruction *insn, unsigned int value);
361
362 #endif
363