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