i965: Return NONE from brw_swap_cmod on unknown input.
[mesa.git] / src / mesa / drivers / dri / i965 / gen8_instruction.h
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 /**
25 * @file gen8_instruction.h
26 *
27 * A representation of a Gen8+ EU instruction, with helper methods to get
28 * and set various fields. This is the actual hardware format.
29 */
30
31 #ifndef GEN8_INSTRUCTION_H
32 #define GEN8_INSTRUCTION_H
33
34 #include <stdio.h>
35 #include <stdint.h>
36
37 #include "brw_context.h"
38 #include "brw_reg.h"
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 struct gen8_instruction {
45 uint32_t data[4];
46 };
47
48 static inline unsigned gen8_instruction_bits(struct gen8_instruction *inst,
49 unsigned high,
50 unsigned low);
51 static inline void gen8_instruction_set_bits(struct gen8_instruction *inst,
52 unsigned high,
53 unsigned low,
54 unsigned value);
55
56 #define F(name, high, low) \
57 static inline void gen8_set_##name(struct gen8_instruction *inst, unsigned v) \
58 { \
59 gen8_instruction_set_bits(inst, high, low, v); \
60 } \
61 static inline unsigned gen8_##name(struct gen8_instruction *inst) \
62 { \
63 return gen8_instruction_bits(inst, high, low); \
64 }
65
66 F(src1_vert_stride, 120, 117)
67 F(src1_da1_width, 116, 114)
68 F(src1_da16_swiz_w, 115, 114)
69 F(src1_da16_swiz_z, 113, 112)
70 F(src1_da1_hstride, 113, 112)
71 F(src1_address_mode, 111, 111)
72 /** Src1.SrcMod @{ */
73 F(src1_negate, 110, 110)
74 F(src1_abs, 109, 109)
75 /** @} */
76 F(src1_ia1_subreg_nr, 108, 105)
77 F(src1_da_reg_nr, 108, 101)
78 F(src1_da16_subreg_nr, 100, 100)
79 F(src1_da1_subreg_nr, 100, 96)
80 F(src1_da16_swiz_y, 99, 98)
81 F(src1_da16_swiz_x, 97, 96)
82 F(src1_reg_type, 94, 91)
83 F(src1_reg_file, 90, 89)
84 F(src0_vert_stride, 88, 85)
85 F(src0_da1_width, 84, 82)
86 F(src0_da16_swiz_w, 83, 82)
87 F(src0_da16_swiz_z, 81, 80)
88 F(src0_da1_hstride, 81, 80)
89 F(src0_address_mode, 79, 79)
90 /** Src0.SrcMod @{ */
91 F(src0_negate, 78, 78)
92 F(src0_abs, 77, 77)
93 /** @} */
94 F(src0_ia1_subreg_nr, 76, 73)
95 F(src0_da_reg_nr, 76, 69)
96 F(src0_da16_subreg_nr, 68, 68)
97 F(src0_da1_subreg_nr, 68, 64)
98 F(src0_da16_swiz_y, 67, 66)
99 F(src0_da16_swiz_x, 65, 64)
100 F(dst_address_mode, 63, 63)
101 F(dst_da1_hstride, 62, 61)
102 F(dst_ia1_subreg_nr, 60, 57)
103 F(dst_da_reg_nr, 60, 53)
104 F(dst_da16_subreg_nr, 52, 52)
105 F(dst_da1_subreg_nr, 52, 48)
106 F(da16_writemask, 51, 48) /* Dst.ChanEn */
107 F(src0_reg_type, 46, 43)
108 F(src0_reg_file, 42, 41)
109 F(dst_reg_type, 40, 37)
110 F(dst_reg_file, 36, 35)
111 F(mask_control, 34, 34)
112 F(flag_reg_nr, 33, 33)
113 F(flag_subreg_nr, 32, 32)
114 F(saturate, 31, 31)
115 F(branch_control, 30, 30)
116 F(debug_control, 30, 30)
117 F(cmpt_control, 29, 29)
118 F(acc_wr_control, 28, 28)
119 F(cond_modifier, 27, 24)
120 F(exec_size, 23, 21)
121 F(pred_inv, 20, 20)
122 F(pred_control, 19, 16)
123 F(thread_control, 15, 14)
124 F(qtr_control, 13, 12)
125 F(nib_control, 11, 11)
126 F(no_dd_check, 10, 10)
127 F(no_dd_clear, 9, 9)
128 F(access_mode, 8, 8)
129 /* Bit 7 is Reserved (for future Opcode expansion) */
130 F(opcode, 6, 0)
131
132 /**
133 * Three-source instructions:
134 * @{
135 */
136 F(src2_3src_reg_nr, 125, 118)
137 F(src2_3src_subreg_nr, 117, 115)
138 F(src2_3src_swizzle, 114, 107)
139 F(src2_3src_rep_ctrl, 106, 106)
140 F(src1_3src_reg_nr, 104, 97)
141 /* src1_3src_subreg_nr spans word boundaries and has to be handled specially */
142 F(src1_3src_swizzle, 93, 86)
143 F(src1_3src_rep_ctrl, 85, 85)
144 F(src0_3src_reg_nr, 83, 76)
145 F(src0_3src_subreg_nr, 75, 73)
146 F(src0_3src_swizzle, 72, 65)
147 F(src0_3src_rep_ctrl, 64, 64)
148 F(dst_3src_reg_nr, 63, 56)
149 F(dst_3src_subreg_nr, 55, 53)
150 F(dst_3src_writemask, 52, 49)
151 F(dst_3src_type, 48, 46)
152 F(src_3src_type, 45, 43)
153 F(src2_3src_negate, 42, 42)
154 F(src2_3src_abs, 41, 41)
155 F(src1_3src_negate, 40, 40)
156 F(src1_3src_abs, 39, 39)
157 F(src0_3src_negate, 38, 38)
158 F(src0_3src_abs, 37, 37)
159 /** @} */
160
161 /**
162 * Fields for SEND messages:
163 * @{
164 */
165 F(eot, 127, 127)
166 F(mlen, 124, 121)
167 F(rlen, 120, 116)
168 F(header_present, 115, 115)
169 F(function_control, 114, 96)
170 F(sfid, 27, 24)
171 F(math_function, 27, 24)
172 /** @} */
173
174 /**
175 * URB message function control bits:
176 * @{
177 */
178 F(urb_per_slot_offset, 113, 113)
179 F(urb_interleave, 111, 111)
180 F(urb_global_offset, 110, 100)
181 F(urb_opcode, 99, 96)
182 /** @} */
183
184 /* Message descriptor bits */
185 #define MD(name, high, low) F(name, (high + 96), (low + 96))
186
187 /**
188 * Sampler message function control bits:
189 * @{
190 */
191 MD(sampler_simd_mode, 18, 17)
192 MD(sampler_msg_type, 16, 12)
193 MD(sampler, 11, 8)
194 MD(binding_table_index, 7, 0) /* also used by other messages */
195 /** @} */
196
197 /**
198 * Data port message function control bits:
199 * @{
200 */
201 MD(dp_category, 18, 18)
202 MD(dp_message_type, 17, 14)
203 MD(dp_message_control, 13, 8)
204 /** @} */
205
206 /**
207 * Scratch message bits:
208 * @{
209 */
210 MD(scratch_read_write, 17, 17) /* 0 = read, 1 = write */
211 MD(scratch_type, 16, 16) /* 0 = OWord, 1 = DWord */
212 MD(scratch_invalidate_after_read, 15, 15)
213 MD(scratch_block_size, 13, 12)
214 MD(scratch_addr_offset, 11, 0)
215 /** @} */
216
217 /**
218 * Render Target message function control bits:
219 * @{
220 */
221 MD(rt_last, 12, 12)
222 MD(rt_slot_group, 11, 11)
223 MD(rt_message_type, 10, 8)
224 /** @} */
225
226 /**
227 * Thread Spawn message function control bits:
228 * @{
229 */
230 MD(ts_resource_select, 4, 4)
231 MD(ts_request_type, 1, 1)
232 MD(ts_opcode, 0, 0)
233 /** @} */
234
235 /**
236 * Video Motion Estimation message function control bits:
237 * @{
238 */
239 F(vme_message_type, 14, 13)
240 /** @} */
241
242 /**
243 * Check & Refinement Engine message function control bits:
244 * @{
245 */
246 F(cre_message_type, 14, 13)
247 /** @} */
248
249 #undef MD
250 #undef F
251
252 static inline void
253 gen8_set_src1_3src_subreg_nr(struct gen8_instruction *inst, unsigned v)
254 {
255 assert((v & ~0x7) == 0);
256
257 gen8_instruction_set_bits(inst, 95, 94, v & 0x3);
258 gen8_instruction_set_bits(inst, 96, 96, v >> 2);
259 }
260
261 static inline unsigned
262 gen8_src1_3src_subreg_nr(struct gen8_instruction *inst)
263 {
264 return gen8_instruction_bits(inst, 95, 94) |
265 (gen8_instruction_bits(inst, 96, 96) << 2);
266 }
267
268 #define GEN8_IA1_ADDR_IMM(reg, nine, high, low) \
269 static inline void \
270 gen8_set_##reg##_ia1_addr_imm(struct gen8_instruction *inst, unsigned value) \
271 { \
272 assert((value & ~0x3ff) == 0); \
273 gen8_instruction_set_bits(inst, high, low, value & 0x1ff); \
274 gen8_instruction_set_bits(inst, nine, nine, value >> 9); \
275 } \
276 \
277 static inline unsigned \
278 gen8_##reg##_ia1_addr_imm(struct gen8_instruction *inst) \
279 { \
280 return gen8_instruction_bits(inst, high, low) | \
281 (gen8_instruction_bits(inst, nine, nine) << 9); \
282 }
283
284 /* AddrImm[9:0] for Align1 Indirect Addressing */
285 GEN8_IA1_ADDR_IMM(src1, 121, 104, 96)
286 GEN8_IA1_ADDR_IMM(src0, 95, 72, 64)
287 GEN8_IA1_ADDR_IMM(dst, 47, 56, 48)
288
289 /**
290 * Flow control instruction bits:
291 * @{
292 */
293 static inline unsigned gen8_uip(struct gen8_instruction *inst)
294 {
295 return inst->data[2];
296 }
297 static inline void gen8_set_uip(struct gen8_instruction *inst, unsigned uip)
298 {
299 inst->data[2] = uip;
300 }
301 static inline unsigned gen8_jip(struct gen8_instruction *inst)
302 {
303 return inst->data[3];
304 }
305 static inline void gen8_set_jip(struct gen8_instruction *inst, unsigned jip)
306 {
307 inst->data[3] = jip;
308 }
309 /** @} */
310
311 static inline int gen8_src1_imm_d(struct gen8_instruction *inst)
312 {
313 return inst->data[3];
314 }
315 static inline unsigned gen8_src1_imm_ud(struct gen8_instruction *inst)
316 {
317 return inst->data[3];
318 }
319 static inline float gen8_src1_imm_f(struct gen8_instruction *inst)
320 {
321 fi_type ft;
322
323 ft.u = inst->data[3];
324 return ft.f;
325 }
326
327 void gen8_set_dst(const struct brw_context *brw,
328 struct gen8_instruction *inst, struct brw_reg reg);
329 void gen8_set_src0(const struct brw_context *brw,
330 struct gen8_instruction *inst, struct brw_reg reg);
331 void gen8_set_src1(const struct brw_context *brw,
332 struct gen8_instruction *inst, struct brw_reg reg);
333
334 void gen8_set_urb_message(const struct brw_context *brw,
335 struct gen8_instruction *inst,
336 enum brw_urb_write_flags flags,
337 unsigned mlen, unsigned rlen,
338 unsigned offset, bool interleave);
339
340 void gen8_set_sampler_message(const struct brw_context *brw,
341 struct gen8_instruction *inst,
342 unsigned binding_table_index, unsigned sampler,
343 unsigned msg_type, unsigned rlen, unsigned mlen,
344 bool header_present, unsigned simd_mode);
345
346 void gen8_set_dp_message(const struct brw_context *brw,
347 struct gen8_instruction *inst,
348 enum brw_message_target sfid,
349 unsigned binding_table_index,
350 unsigned msg_type,
351 unsigned msg_control,
352 unsigned msg_length,
353 unsigned response_length,
354 bool header_present,
355 bool end_of_thread);
356
357 void gen8_set_dp_scratch_message(const struct brw_context *brw,
358 struct gen8_instruction *inst,
359 bool write,
360 bool dword,
361 bool invalidate_after_read,
362 unsigned num_regs,
363 unsigned addr_offset,
364 unsigned msg_length,
365 unsigned response_length,
366 bool header_present,
367 bool end_of_thread);
368
369 /**
370 * Fetch a set of contiguous bits from the instruction.
371 *
372 * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
373 */
374 static inline unsigned
375 gen8_instruction_bits(struct gen8_instruction *inst, unsigned high, unsigned low)
376 {
377 /* We assume the field doesn't cross 32-bit boundaries. */
378 const unsigned word = high / 32;
379 assert(word == low / 32);
380
381 high %= 32;
382 low %= 32;
383
384 const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
385
386 return (inst->data[word] & mask) >> low;
387 }
388
389 /**
390 * Set bits in the instruction, with proper shifting and masking.
391 *
392 * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
393 */
394 static inline void
395 gen8_instruction_set_bits(struct gen8_instruction *inst,
396 unsigned high,
397 unsigned low,
398 unsigned value)
399 {
400 const unsigned word = high / 32;
401 assert(word == low / 32);
402
403 high %= 32;
404 low %= 32;
405
406 const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
407
408 /* Make sure the supplied value actually fits in the given bitfield. */
409 assert((value & (mask >> low)) == value);
410
411 inst->data[word] = (inst->data[word] & ~mask) | ((value << low) & mask);
412 }
413
414 #ifdef __cplusplus
415 }
416 #endif
417
418 #endif