1 /*
2 * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Vadim Girlin
25 */
26
27 #include "sb_bc.h"
28
29 namespace r600_sb {
30
decode_cf(unsigned & i,bc_cf & bc)31 int bc_decoder::decode_cf(unsigned &i, bc_cf& bc) {
32 int r = 0;
33 uint32_t dw0 = dw[i];
34 uint32_t dw1 = dw[i+1];
35 assert(i+1 <= ndw);
36
37 if ((dw1 >> 29) & 1) { // CF_ALU
38 return decode_cf_alu(i, bc);
39 } else {
40 // CF_INST field encoding on cayman is the same as on evergreen
41 unsigned opcode = ctx.is_egcm() ?
42 CF_WORD1_EG(dw1).get_CF_INST() :
43 CF_WORD1_R6R7(dw1).get_CF_INST();
44
45 bc.set_op(r600_isa_cf_by_opcode(ctx.isa, opcode, 0));
46
47 if (bc.op_ptr->flags & CF_EXP) {
48 return decode_cf_exp(i, bc);
49 } else if (bc.op_ptr->flags & CF_MEM) {
50 return decode_cf_mem(i, bc);
51 }
52
53 if (ctx.is_egcm()) {
54 CF_WORD0_EGCM w0(dw0);
55 bc.addr = w0.get_ADDR();
56 bc.jumptable_sel = w0.get_JUMPTABLE_SEL();
57
58 if (ctx.is_evergreen()) {
59 CF_WORD1_EG w1(dw1);
60
61 bc.barrier = w1.get_BARRIER();
62 bc.cf_const = w1.get_CF_CONST();
63 bc.cond = w1.get_COND();
64 bc.count = w1.get_COUNT();
65 bc.end_of_program = w1.get_END_OF_PROGRAM();
66 bc.pop_count = w1.get_POP_COUNT();
67 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
68 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
69
70 } else { // cayman
71 CF_WORD1_CM w1(dw1);
72
73 bc.barrier = w1.get_BARRIER();
74 bc.cf_const = w1.get_CF_CONST();
75 bc.cond = w1.get_COND();
76 bc.count = w1.get_COUNT();
77 bc.pop_count = w1.get_POP_COUNT();
78 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
79 }
80
81
82 } else {
83 CF_WORD0_R6R7 w0(dw0);
84 bc.addr = w0.get_ADDR();
85
86 CF_WORD1_R6R7 w1(dw1);
87 bc.barrier = w1.get_BARRIER();
88 bc.cf_const = w1.get_CF_CONST();
89 bc.cond = w1.get_COND();
90
91 if (ctx.is_r600())
92 bc.count = w1.get_COUNT();
93 else
94 bc.count = w1.get_COUNT() + (w1.get_COUNT_3() << 3);
95
96 bc.end_of_program = w1.get_END_OF_PROGRAM();
97 bc.pop_count = w1.get_POP_COUNT();
98 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
99 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
100 bc.call_count = w1.get_CALL_COUNT();
101 }
102 }
103
104 i += 2;
105
106 return r;
107 }
108
decode_cf_alu(unsigned & i,bc_cf & bc)109 int bc_decoder::decode_cf_alu(unsigned & i, bc_cf& bc) {
110 int r = 0;
111 uint32_t dw0 = dw[i++];
112 uint32_t dw1 = dw[i++];
113
114 assert(i <= ndw);
115
116 CF_ALU_WORD0_ALL w0(dw0);
117
118 bc.kc[0].bank = w0.get_KCACHE_BANK0();
119 bc.kc[1].bank = w0.get_KCACHE_BANK1();
120 bc.kc[0].mode = w0.get_KCACHE_MODE0();
121
122 bc.addr = w0.get_ADDR();
123
124 if (ctx.is_r600()) {
125 CF_ALU_WORD1_R6 w1(dw1);
126
127 bc.set_op(r600_isa_cf_by_opcode(ctx.isa, w1.get_CF_INST(), 1));
128
129 bc.kc[0].addr = w1.get_KCACHE_ADDR0();
130 bc.kc[1].mode = w1.get_KCACHE_MODE1();
131 bc.kc[1].addr = w1.get_KCACHE_ADDR1();
132
133 bc.barrier = w1.get_BARRIER();
134 bc.count = w1.get_COUNT();
135 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
136
137 bc.uses_waterfall = w1.get_USES_WATERFALL();
138 } else {
139 CF_ALU_WORD1_R7EGCM w1(dw1);
140
141 bc.set_op(r600_isa_cf_by_opcode(ctx.isa, w1.get_CF_INST(), 1));
142
143 if (bc.op == CF_OP_ALU_EXT) {
144 CF_ALU_WORD0_EXT_EGCM w0(dw0);
145 CF_ALU_WORD1_EXT_EGCM w1(dw1);
146
147 bc.kc[0].index_mode = w0.get_KCACHE_BANK_INDEX_MODE0();
148 bc.kc[1].index_mode = w0.get_KCACHE_BANK_INDEX_MODE1();
149 bc.kc[2].index_mode = w0.get_KCACHE_BANK_INDEX_MODE2();
150 bc.kc[3].index_mode = w0.get_KCACHE_BANK_INDEX_MODE3();
151 bc.kc[2].bank = w0.get_KCACHE_BANK2();
152 bc.kc[3].bank = w0.get_KCACHE_BANK3();
153 bc.kc[2].mode = w0.get_KCACHE_MODE2();
154 bc.kc[3].mode = w1.get_KCACHE_MODE3();
155 bc.kc[2].addr = w1.get_KCACHE_ADDR2();
156 bc.kc[3].addr = w1.get_KCACHE_ADDR3();
157
158 r = decode_cf_alu(i, bc);
159
160 } else {
161
162 bc.kc[0].addr = w1.get_KCACHE_ADDR0();
163 bc.kc[1].mode = w1.get_KCACHE_MODE1();
164 bc.kc[1].addr = w1.get_KCACHE_ADDR1();
165 bc.barrier = w1.get_BARRIER();
166 bc.count = w1.get_COUNT();
167 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
168
169 bc.alt_const = w1.get_ALT_CONST();
170 }
171 }
172 return r;
173 }
174
decode_cf_exp(unsigned & i,bc_cf & bc)175 int bc_decoder::decode_cf_exp(unsigned & i, bc_cf& bc) {
176 int r = 0;
177 uint32_t dw0 = dw[i++];
178 uint32_t dw1 = dw[i++];
179 assert(i <= ndw);
180
181 CF_ALLOC_EXPORT_WORD0_ALL w0(dw0);
182 bc.array_base = w0.get_ARRAY_BASE();
183 bc.elem_size = w0.get_ELEM_SIZE();
184 bc.index_gpr = w0.get_INDEX_GPR();
185 bc.rw_gpr = w0.get_RW_GPR();
186 bc.rw_rel = w0.get_RW_REL();
187 bc.type = w0.get_TYPE();
188
189 if (ctx.is_evergreen()) {
190 CF_ALLOC_EXPORT_WORD1_SWIZ_EG w1(dw1);
191 bc.barrier = w1.get_BARRIER();
192 bc.burst_count = w1.get_BURST_COUNT();
193 bc.end_of_program = w1.get_END_OF_PROGRAM();
194 bc.sel[0] = w1.get_SEL_X();
195 bc.sel[1] = w1.get_SEL_Y();
196 bc.sel[2] = w1.get_SEL_Z();
197 bc.sel[3] = w1.get_SEL_W();
198 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
199 bc.mark = w1.get_MARK();
200
201 } else if (ctx.is_cayman()) {
202 CF_ALLOC_EXPORT_WORD1_SWIZ_CM w1(dw1);
203 bc.barrier = w1.get_BARRIER();
204 bc.burst_count = w1.get_BURST_COUNT();
205 bc.mark = w1.get_MARK();
206 bc.sel[0] = w1.get_SEL_X();
207 bc.sel[1] = w1.get_SEL_Y();
208 bc.sel[2] = w1.get_SEL_Z();
209 bc.sel[3] = w1.get_SEL_W();
210 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
211
212 } else { // r67
213 CF_ALLOC_EXPORT_WORD1_SWIZ_R6R7 w1(dw1);
214 bc.barrier = w1.get_BARRIER();
215 bc.burst_count = w1.get_BURST_COUNT();
216 bc.end_of_program = w1.get_END_OF_PROGRAM();
217 bc.sel[0] = w1.get_SEL_X();
218 bc.sel[1] = w1.get_SEL_Y();
219 bc.sel[2] = w1.get_SEL_Z();
220 bc.sel[3] = w1.get_SEL_W();
221 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
222 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
223 }
224
225 return r;
226 }
227
228
decode_cf_mem(unsigned & i,bc_cf & bc)229 int bc_decoder::decode_cf_mem(unsigned & i, bc_cf& bc) {
230 int r = 0;
231 uint32_t dw0 = dw[i++];
232 uint32_t dw1 = dw[i++];
233 assert(i <= ndw);
234
235 if (!(bc.op_ptr->flags & CF_RAT)) {
236 CF_ALLOC_EXPORT_WORD0_ALL w0(dw0);
237 bc.array_base = w0.get_ARRAY_BASE();
238 bc.elem_size = w0.get_ELEM_SIZE();
239 bc.index_gpr = w0.get_INDEX_GPR();
240 bc.rw_gpr = w0.get_RW_GPR();
241 bc.rw_rel = w0.get_RW_REL();
242 bc.type = w0.get_TYPE();
243 } else {
244 assert(ctx.is_egcm());
245 CF_ALLOC_EXPORT_WORD0_RAT_EGCM w0(dw0);
246 bc.elem_size = w0.get_ELEM_SIZE();
247 bc.index_gpr = w0.get_INDEX_GPR();
248 bc.rw_gpr = w0.get_RW_GPR();
249 bc.rw_rel = w0.get_RW_REL();
250 bc.type = w0.get_TYPE();
251 bc.rat_id = w0.get_RAT_ID();
252 bc.rat_inst = w0.get_RAT_INST();
253 bc.rat_index_mode = w0.get_RAT_INDEX_MODE();
254 }
255
256 if (ctx.is_evergreen()) {
257 CF_ALLOC_EXPORT_WORD1_BUF_EG w1(dw1);
258 bc.barrier = w1.get_BARRIER();
259 bc.burst_count = w1.get_BURST_COUNT();
260 bc.end_of_program = w1.get_END_OF_PROGRAM();
261 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
262 bc.mark = w1.get_MARK();
263 bc.array_size = w1.get_ARR_SIZE();
264 bc.comp_mask = w1.get_COMP_MASK();
265
266 } else if (ctx.is_cayman()) {
267 CF_ALLOC_EXPORT_WORD1_BUF_CM w1(dw1);
268 bc.barrier = w1.get_BARRIER();
269 bc.burst_count = w1.get_BURST_COUNT();
270 bc.mark = w1.get_MARK();
271 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
272 bc.array_size = w1.get_ARR_SIZE();
273 bc.comp_mask = w1.get_COMP_MASK();
274
275 } else { // r67
276 CF_ALLOC_EXPORT_WORD1_BUF_R6R7 w1(dw1);
277 bc.barrier = w1.get_BARRIER();
278 bc.burst_count = w1.get_BURST_COUNT();
279 bc.end_of_program = w1.get_END_OF_PROGRAM();
280 bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
281 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
282 bc.array_size = w1.get_ARR_SIZE();
283 bc.comp_mask = w1.get_COMP_MASK();
284 bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
285 }
286
287 return r;
288 }
289
decode_alu(unsigned & i,bc_alu & bc)290 int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) {
291 int r = 0;
292 uint32_t dw0 = dw[i++];
293 uint32_t dw1 = dw[i++];
294 assert(i <= ndw);
295
296 ALU_WORD0_ALL w0(dw0);
297 bc.index_mode = w0.get_INDEX_MODE();
298 bc.last = w0.get_LAST();
299 bc.pred_sel = w0.get_PRED_SEL();
300 bc.src[0].chan = w0.get_SRC0_CHAN();
301 bc.src[0].sel = w0.get_SRC0_SEL();
302 bc.src[0].neg = w0.get_SRC0_NEG();
303 bc.src[0].rel = w0.get_SRC0_REL();
304 bc.src[1].chan = w0.get_SRC1_CHAN();
305 bc.src[1].sel = w0.get_SRC1_SEL();
306 bc.src[1].neg = w0.get_SRC1_NEG();
307 bc.src[1].rel = w0.get_SRC1_REL();
308
309 if ((dw1 >> 15) & 7) { // op3
310 ALU_WORD1_OP3_ALL w1(dw1);
311 bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 1));
312
313 if (bc.op == ALU_OP3_LDS_IDX_OP) {
314 ALU_WORD0_LDS_IDX_OP_EGCM iw0(dw0);
315 ALU_WORD1_LDS_IDX_OP_EGCM iw1(dw1);
316 bc.index_mode = iw0.get_INDEX_MODE();
317 bc.last = iw0.get_LAST();
318 bc.pred_sel = iw0.get_PRED_SEL();
319 bc.src[0].chan = iw0.get_SRC0_CHAN();
320 bc.src[0].sel = iw0.get_SRC0_SEL();
321 bc.src[0].rel = iw0.get_SRC0_REL();
322
323 bc.src[1].chan = iw0.get_SRC1_CHAN();
324 bc.src[1].sel = iw0.get_SRC1_SEL();
325 bc.src[1].rel = iw0.get_SRC1_REL();
326
327 bc.bank_swizzle = iw1.get_BANK_SWIZZLE();
328 bc.src[2].chan = iw1.get_SRC2_CHAN();
329 bc.src[2].sel = iw1.get_SRC2_SEL();
330 bc.src[2].rel = iw1.get_SRC2_REL();
331 bc.dst_chan = iw1.get_DST_CHAN();
332 // TODO: clean up
333 for (size_t k = 0, e = r600_alu_op_table_size(); k != e; k++) {
334 if (((r600_alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) {
335 bc.op_ptr = &r600_alu_op_table[k];
336 bc.op = k;
337 break;
338 }
339 }
340 bc.lds_idx_offset =
341 (iw0.get_IDX_OFFSET_4() << 4) |
342 (iw0.get_IDX_OFFSET_5() << 5) |
343 (iw1.get_IDX_OFFSET_1() << 1) |
344 (iw1.get_IDX_OFFSET_0() << 0) |
345 (iw1.get_IDX_OFFSET_2() << 2) |
346 (iw1.get_IDX_OFFSET_3() << 3);
347 }
348 else {
349 bc.bank_swizzle = w1.get_BANK_SWIZZLE();
350 bc.clamp = w1.get_CLAMP();
351 bc.dst_chan = w1.get_DST_CHAN();
352 bc.dst_gpr = w1.get_DST_GPR();
353 bc.dst_rel = w1.get_DST_REL();
354
355 bc.src[2].chan = w1.get_SRC2_CHAN();
356 bc.src[2].sel = w1.get_SRC2_SEL();
357 bc.src[2].neg = w1.get_SRC2_NEG();
358 bc.src[2].rel = w1.get_SRC2_REL();
359 }
360
361 } else { // op2
362 if (ctx.is_r600()) {
363 ALU_WORD1_OP2_R6 w1(dw1);
364 bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 0));
365
366 bc.bank_swizzle = w1.get_BANK_SWIZZLE();
367 bc.clamp = w1.get_CLAMP();
368 bc.dst_chan = w1.get_DST_CHAN();
369 bc.dst_gpr = w1.get_DST_GPR();
370 bc.dst_rel = w1.get_DST_REL();
371
372 bc.omod = w1.get_OMOD();
373 bc.src[0].abs = w1.get_SRC0_ABS();
374 bc.src[1].abs = w1.get_SRC1_ABS();
375 bc.write_mask = w1.get_WRITE_MASK();
376 bc.update_exec_mask = w1.get_UPDATE_EXEC_MASK();
377 bc.update_pred = w1.get_UPDATE_PRED();
378
379 bc.fog_merge = w1.get_FOG_MERGE();
380
381 } else {
382 ALU_WORD1_OP2_R7EGCM w1(dw1);
383 bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 0));
384
385 bc.bank_swizzle = w1.get_BANK_SWIZZLE();
386 bc.clamp = w1.get_CLAMP();
387 bc.dst_chan = w1.get_DST_CHAN();
388 bc.dst_gpr = w1.get_DST_GPR();
389 bc.dst_rel = w1.get_DST_REL();
390
391 bc.omod = w1.get_OMOD();
392 bc.src[0].abs = w1.get_SRC0_ABS();
393 bc.src[1].abs = w1.get_SRC1_ABS();
394 bc.write_mask = w1.get_WRITE_MASK();
395 bc.update_exec_mask = w1.get_UPDATE_EXEC_MASK();
396 bc.update_pred = w1.get_UPDATE_PRED();
397 }
398 }
399
400 bc.slot_flags = (alu_op_flags)bc.op_ptr->slots[ctx.isa->hw_class];
401 return r;
402 }
403
decode_fetch(unsigned & i,bc_fetch & bc)404 int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) {
405 int r = 0;
406 uint32_t dw0 = dw[i];
407 uint32_t dw1 = dw[i+1];
408 uint32_t dw2 = dw[i+2];
409 assert(i + 4 <= ndw);
410
411 unsigned fetch_opcode = dw0 & 0x1F;
412
413 if (fetch_opcode == 2) { // MEM_INST_MEM
414 unsigned mem_op = (dw0 >> 8) & 0x7;
415 unsigned gds_op;
416 if (mem_op == 0 || mem_op == 2) {
417 fetch_opcode = mem_op == 0 ? FETCH_OP_READ_SCRATCH : FETCH_OP_READ_MEM;
418 } else if (mem_op == 4) {
419 gds_op = (dw1 >> 9) & 0x1f;
420 if ((dw1 >> 9) & 0x20)
421 fetch_opcode = FETCH_OP_GDS_ADD_RET + gds_op;
422 else
423 fetch_opcode = FETCH_OP_GDS_ADD + gds_op;
424 } else if (mem_op == 5)
425 fetch_opcode = FETCH_OP_TF_WRITE;
426 bc.set_op(fetch_opcode);
427 } else
428 bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode));
429
430 if (bc.op_ptr->flags & FF_MEM)
431 return decode_fetch_mem(i, bc);
432
433 if (bc.op_ptr->flags & FF_GDS)
434 return decode_fetch_gds(i, bc);
435
436 if (bc.op_ptr->flags & FF_VTX)
437 return decode_fetch_vtx(i, bc);
438
439 // tex
440
441 if (ctx.is_r600()) {
442 TEX_WORD0_R6 w0(dw0);
443
444 bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
445 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
446 bc.resource_id = w0.get_RESOURCE_ID();
447 bc.src_gpr = w0.get_SRC_GPR();
448 bc.src_rel = w0.get_SRC_REL();
449
450 } else if (ctx.is_r600()) {
451 TEX_WORD0_R7 w0(dw0);
452
453 bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
454 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
455 bc.resource_id = w0.get_RESOURCE_ID();
456 bc.src_gpr = w0.get_SRC_GPR();
457 bc.src_rel = w0.get_SRC_REL();
458 bc.alt_const = w0.get_ALT_CONST();
459
460 } else { // eg/cm
461 TEX_WORD0_EGCM w0(dw0);
462
463 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
464 bc.resource_id = w0.get_RESOURCE_ID();
465 bc.src_gpr = w0.get_SRC_GPR();
466 bc.src_rel = w0.get_SRC_REL();
467 bc.alt_const = w0.get_ALT_CONST();
468 bc.inst_mod = w0.get_INST_MOD();
469 bc.resource_index_mode = w0.get_RESOURCE_INDEX_MODE();
470 bc.sampler_index_mode = w0.get_SAMPLER_INDEX_MODE();
471 }
472
473 TEX_WORD1_ALL w1(dw1);
474 bc.coord_type[0] = w1.get_COORD_TYPE_X();
475 bc.coord_type[1] = w1.get_COORD_TYPE_Y();
476 bc.coord_type[2] = w1.get_COORD_TYPE_Z();
477 bc.coord_type[3] = w1.get_COORD_TYPE_W();
478 bc.dst_gpr = w1.get_DST_GPR();
479 bc.dst_rel = w1.get_DST_REL();
480 bc.dst_sel[0] = w1.get_DST_SEL_X();
481 bc.dst_sel[1] = w1.get_DST_SEL_Y();
482 bc.dst_sel[2] = w1.get_DST_SEL_Z();
483 bc.dst_sel[3] = w1.get_DST_SEL_W();
484 bc.lod_bias = w1.get_LOD_BIAS();
485
486 TEX_WORD2_ALL w2(dw2);
487 bc.offset[0] = w2.get_OFFSET_X();
488 bc.offset[1] = w2.get_OFFSET_Y();
489 bc.offset[2] = w2.get_OFFSET_Z();
490 bc.sampler_id = w2.get_SAMPLER_ID();
491 bc.src_sel[0] = w2.get_SRC_SEL_X();
492 bc.src_sel[1] = w2.get_SRC_SEL_Y();
493 bc.src_sel[2] = w2.get_SRC_SEL_Z();
494 bc.src_sel[3] = w2.get_SRC_SEL_W();
495
496 i += 4;
497 return r;
498 }
499
decode_fetch_gds(unsigned & i,bc_fetch & bc)500 int bc_decoder::decode_fetch_gds(unsigned & i, bc_fetch& bc) {
501 int r = 0;
502 uint32_t dw0 = dw[i];
503 uint32_t dw1 = dw[i+1];
504 uint32_t dw2 = dw[i+2];
505 uint32_t tmp;
506 /* GDS instructions align to 4 words boundaries */
507 i+= 4;
508 assert(i <= ndw);
509
510 MEM_GDS_WORD0_EGCM w0(dw0);
511 bc.src_gpr = w0.get_SRC_GPR();
512 tmp = w0.get_SRC_REL_MODE();
513 bc.src_rel_global = (tmp == 2);
514 bc.src_sel[0] = w0.get_SRC_SEL_X();
515 bc.src_sel[1] = w0.get_SRC_SEL_Y();
516 bc.src_sel[2] = w0.get_SRC_SEL_Z();
517
518 MEM_GDS_WORD1_EGCM w1(dw1);
519 bc.dst_gpr = w1.get_DST_GPR();
520 tmp = w1.get_DST_REL_MODE();
521 bc.dst_rel_global = (tmp == 2);
522 bc.src2_gpr = w1.get_SRC_GPR();
523 bc.alloc_consume = w1.get_ALLOC_CONSUME();
524 bc.uav_id = w1.get_UAV_ID();
525 bc.uav_index_mode = w1.get_UAV_INDEX_MODE();
526 bc.bcast_first_req = w1.get_BCAST_FIRST_REQ();
527
528 MEM_GDS_WORD2_EGCM w2(dw2);
529 bc.dst_sel[0] = w2.get_DST_SEL_X();
530 bc.dst_sel[1] = w2.get_DST_SEL_Y();
531 bc.dst_sel[2] = w2.get_DST_SEL_Z();
532 bc.dst_sel[3] = w2.get_DST_SEL_W();
533 return r;
534 }
535
decode_fetch_mem(unsigned & i,bc_fetch & bc)536 int bc_decoder::decode_fetch_mem(unsigned & i, bc_fetch& bc) {
537 int r = 0;
538 uint32_t dw0 = dw[i];
539 uint32_t dw1 = dw[i+1];
540 uint32_t dw2 = dw[i+2];
541
542 i += 4; // MEM instructions align to 4 words boundaries
543
544 assert(i <= ndw);
545
546 MEM_RD_WORD0_R7EGCM w0(dw0);
547 bc.elem_size = w0.get_ELEM_SIZE();
548 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
549 bc.uncached = w0.get_UNCACHED();
550 bc.indexed = w0.get_INDEXED();
551 bc.src_sel[1] = w0.get_SRC_SEL_Y();
552 bc.src_gpr = w0.get_SRC_GPR();
553 bc.src_rel = w0.get_SRC_REL();
554 bc.src_sel[0] = w0.get_SRC_SEL_X();
555 bc.burst_count = w0.get_BURST_COUNT();
556 bc.lds_req = w0.get_LDS_REQ();
557 bc.coalesced_read = w0.get_COALESCED_READ();
558
559 MEM_RD_WORD1_R7EGCM w1(dw1);
560 bc.dst_gpr = w1.get_DST_GPR();
561 bc.dst_rel = w1.get_DST_REL();
562 bc.dst_sel[0] = w1.get_DST_SEL_X();
563 bc.dst_sel[1] = w1.get_DST_SEL_Y();
564 bc.dst_sel[2] = w1.get_DST_SEL_Z();
565 bc.dst_sel[3] = w1.get_DST_SEL_W();
566 bc.data_format = w1.get_DATA_FORMAT();
567 bc.num_format_all = w1.get_NUM_FORMAT_ALL();
568 bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
569 bc.srf_mode_all = w1.get_SRF_MODE_ALL();
570
571 MEM_RD_WORD2_R7EGCM w2(dw2);
572 bc.array_base = w2.get_ARRAY_BASE();
573 bc.endian_swap = w2.get_ENDIAN_SWAP();
574 bc.array_size = w2.get_ARR_SIZE();
575
576 return r;
577 }
578
decode_fetch_vtx(unsigned & i,bc_fetch & bc)579 int bc_decoder::decode_fetch_vtx(unsigned & i, bc_fetch& bc) {
580 int r = 0;
581 uint32_t dw0 = dw[i];
582 uint32_t dw1 = dw[i+1];
583 uint32_t dw2 = dw[i+2];
584 i+= 4;
585 assert(i <= ndw);
586
587 if (ctx.is_cayman()) {
588 VTX_WORD0_CM w0(dw0);
589 bc.resource_id = w0.get_BUFFER_ID();
590 bc.fetch_type = w0.get_FETCH_TYPE();
591 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
592 bc.src_gpr = w0.get_SRC_GPR();
593 bc.src_rel = w0.get_SRC_REL();
594 bc.src_sel[0] = w0.get_SRC_SEL_X();
595 bc.coalesced_read = w0.get_COALESCED_READ();
596 bc.lds_req = w0.get_LDS_REQ();
597 bc.structured_read = w0.get_STRUCTURED_READ();
598
599 } else {
600 VTX_WORD0_R6R7EG w0(dw0);
601 bc.resource_id = w0.get_BUFFER_ID();
602 bc.fetch_type = w0.get_FETCH_TYPE();
603 bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
604 bc.mega_fetch_count = w0.get_MEGA_FETCH_COUNT();
605 bc.src_gpr = w0.get_SRC_GPR();
606 bc.src_rel = w0.get_SRC_REL();
607 bc.src_sel[0] = w0.get_SRC_SEL_X();
608 }
609
610 if (bc.op == FETCH_OP_SEMFETCH) {
611 VTX_WORD1_SEM_ALL w1(dw1);
612 bc.data_format = w1.get_DATA_FORMAT();
613 bc.dst_sel[0] = w1.get_DST_SEL_X();
614 bc.dst_sel[1] = w1.get_DST_SEL_Y();
615 bc.dst_sel[2] = w1.get_DST_SEL_Z();
616 bc.dst_sel[3] = w1.get_DST_SEL_W();
617 bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
618 bc.num_format_all = w1.get_NUM_FORMAT_ALL();
619 bc.srf_mode_all = w1.get_SRF_MODE_ALL();
620 bc.use_const_fields = w1.get_USE_CONST_FIELDS();
621
622 bc.semantic_id = w1.get_SEMANTIC_ID();
623
624 } else {
625 VTX_WORD1_GPR_ALL w1(dw1);
626 bc.data_format = w1.get_DATA_FORMAT();
627 bc.dst_sel[0] = w1.get_DST_SEL_X();
628 bc.dst_sel[1] = w1.get_DST_SEL_Y();
629 bc.dst_sel[2] = w1.get_DST_SEL_Z();
630 bc.dst_sel[3] = w1.get_DST_SEL_W();
631 bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
632 bc.num_format_all = w1.get_NUM_FORMAT_ALL();
633 bc.srf_mode_all = w1.get_SRF_MODE_ALL();
634 bc.use_const_fields = w1.get_USE_CONST_FIELDS();
635
636 bc.dst_gpr = w1.get_DST_GPR();
637 bc.dst_rel = w1.get_DST_REL();
638 }
639
640 switch (ctx.hw_class) {
641 case HW_CLASS_R600:
642 {
643 VTX_WORD2_R6 w2(dw2);
644 bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
645 bc.endian_swap = w2.get_ENDIAN_SWAP();
646 bc.mega_fetch = w2.get_MEGA_FETCH();
647 bc.offset[0] = w2.get_OFFSET();
648 break;
649 }
650 case HW_CLASS_R700:
651 {
652 VTX_WORD2_R7 w2(dw2);
653 bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
654 bc.endian_swap = w2.get_ENDIAN_SWAP();
655 bc.mega_fetch = w2.get_MEGA_FETCH();
656 bc.offset[0] = w2.get_OFFSET();
657 bc.alt_const = w2.get_ALT_CONST();
658 break;
659 }
660 case HW_CLASS_EVERGREEN:
661 {
662 VTX_WORD2_EG w2(dw2);
663 bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
664 bc.endian_swap = w2.get_ENDIAN_SWAP();
665 bc.mega_fetch = w2.get_MEGA_FETCH();
666 bc.offset[0] = w2.get_OFFSET();
667 bc.alt_const = w2.get_ALT_CONST();
668 bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
669 break;
670 }
671 case HW_CLASS_CAYMAN:
672 {
673 VTX_WORD2_CM w2(dw2);
674 bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
675 bc.endian_swap = w2.get_ENDIAN_SWAP();
676 bc.offset[0] = w2.get_OFFSET();
677 bc.alt_const = w2.get_ALT_CONST();
678 bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
679 break;
680 }
681 default:
682 assert(!"unknown hw class");
683 return -1;
684 }
685
686 return r;
687 }
688
689 }
690