• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 == 4) {
417 			gds_op = (dw1 >> 9) & 0x1f;
418 			fetch_opcode = FETCH_OP_GDS_ADD + gds_op;
419 		} else if (mem_op == 5)
420 			fetch_opcode = FETCH_OP_TF_WRITE;
421 		bc.set_op(fetch_opcode);
422 	} else
423 		bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode));
424 
425 	if (bc.op_ptr->flags & FF_GDS)
426 		return decode_fetch_gds(i, bc);
427 
428 	if (bc.op_ptr->flags & FF_VTX)
429 		return decode_fetch_vtx(i, bc);
430 
431 	// tex
432 
433 	if (ctx.is_r600()) {
434 		TEX_WORD0_R6 w0(dw0);
435 
436 		bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
437 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
438 		bc.resource_id = w0.get_RESOURCE_ID();
439 		bc.src_gpr = w0.get_SRC_GPR();
440 		bc.src_rel = w0.get_SRC_REL();
441 
442 	} else if (ctx.is_r600()) {
443 		TEX_WORD0_R7 w0(dw0);
444 
445 		bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
446 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
447 		bc.resource_id = w0.get_RESOURCE_ID();
448 		bc.src_gpr = w0.get_SRC_GPR();
449 		bc.src_rel = w0.get_SRC_REL();
450 		bc.alt_const = w0.get_ALT_CONST();
451 
452 	} else { // eg/cm
453 		TEX_WORD0_EGCM w0(dw0);
454 
455 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
456 		bc.resource_id = w0.get_RESOURCE_ID();
457 		bc.src_gpr = w0.get_SRC_GPR();
458 		bc.src_rel = w0.get_SRC_REL();
459 		bc.alt_const = w0.get_ALT_CONST();
460 		bc.inst_mod = w0.get_INST_MOD();
461 		bc.resource_index_mode = w0.get_RESOURCE_INDEX_MODE();
462 		bc.sampler_index_mode = w0.get_SAMPLER_INDEX_MODE();
463 	}
464 
465 	TEX_WORD1_ALL w1(dw1);
466 	bc.coord_type[0] = w1.get_COORD_TYPE_X();
467 	bc.coord_type[1] = w1.get_COORD_TYPE_Y();
468 	bc.coord_type[2] = w1.get_COORD_TYPE_Z();
469 	bc.coord_type[3] = w1.get_COORD_TYPE_W();
470 	bc.dst_gpr = w1.get_DST_GPR();
471 	bc.dst_rel = w1.get_DST_REL();
472 	bc.dst_sel[0] = w1.get_DST_SEL_X();
473 	bc.dst_sel[1] = w1.get_DST_SEL_Y();
474 	bc.dst_sel[2] = w1.get_DST_SEL_Z();
475 	bc.dst_sel[3] = w1.get_DST_SEL_W();
476 	bc.lod_bias = w1.get_LOD_BIAS();
477 
478 	TEX_WORD2_ALL w2(dw2);
479 	bc.offset[0] = w2.get_OFFSET_X();
480 	bc.offset[1] = w2.get_OFFSET_Y();
481 	bc.offset[2] = w2.get_OFFSET_Z();
482 	bc.sampler_id = w2.get_SAMPLER_ID();
483 	bc.src_sel[0] = w2.get_SRC_SEL_X();
484 	bc.src_sel[1] = w2.get_SRC_SEL_Y();
485 	bc.src_sel[2] = w2.get_SRC_SEL_Z();
486 	bc.src_sel[3] = w2.get_SRC_SEL_W();
487 
488 	i += 4;
489 	return r;
490 }
491 
decode_fetch_gds(unsigned & i,bc_fetch & bc)492 int bc_decoder::decode_fetch_gds(unsigned & i, bc_fetch& bc) {
493 	int r = 0;
494 	uint32_t dw0 = dw[i];
495 	uint32_t dw1 = dw[i+1];
496 	uint32_t dw2 = dw[i+2];
497 	uint32_t tmp;
498 	/* GDS instructions align to 4 words boundaries */
499 	i+= 4;
500 	assert(i <= ndw);
501 
502 	MEM_GDS_WORD0_EGCM w0(dw0);
503 	bc.src_gpr = w0.get_SRC_GPR();
504 	tmp = w0.get_SRC_REL_MODE();
505 	bc.src_rel_global = (tmp == 2);
506 	bc.src_sel[0] = w0.get_SRC_SEL_X();
507 	bc.src_sel[1] = w0.get_SRC_SEL_Y();
508 	bc.src_sel[2] = w0.get_SRC_SEL_Z();
509 
510 	MEM_GDS_WORD1_EGCM w1(dw1);
511 	bc.dst_gpr = w1.get_DST_GPR();
512 	tmp = w1.get_DST_REL_MODE();
513 	bc.dst_rel_global = (tmp == 2);
514 	bc.src2_gpr = w1.get_SRC_GPR();
515 
516 	MEM_GDS_WORD2_EGCM w2(dw2);
517 	bc.dst_sel[0] = w2.get_DST_SEL_X();
518 	bc.dst_sel[1] = w2.get_DST_SEL_Y();
519 	bc.dst_sel[2] = w2.get_DST_SEL_Z();
520 	bc.dst_sel[3] = w2.get_DST_SEL_W();
521 	return r;
522 }
523 
decode_fetch_vtx(unsigned & i,bc_fetch & bc)524 int bc_decoder::decode_fetch_vtx(unsigned & i, bc_fetch& bc) {
525 	int r = 0;
526 	uint32_t dw0 = dw[i];
527 	uint32_t dw1 = dw[i+1];
528 	uint32_t dw2 = dw[i+2];
529 	i+= 4;
530 	assert(i <= ndw);
531 
532 	if (ctx.is_cayman()) {
533 		VTX_WORD0_CM w0(dw0);
534 		bc.resource_id = w0.get_BUFFER_ID();
535 		bc.fetch_type = w0.get_FETCH_TYPE();
536 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
537 		bc.src_gpr = w0.get_SRC_GPR();
538 		bc.src_rel = w0.get_SRC_REL();
539 		bc.src_sel[0] = w0.get_SRC_SEL_X();
540 		bc.coalesced_read = w0.get_COALESCED_READ();
541 		bc.lds_req = w0.get_LDS_REQ();
542 		bc.structured_read = w0.get_STRUCTURED_READ();
543 
544 	} else {
545 		VTX_WORD0_R6R7EG w0(dw0);
546 		bc.resource_id = w0.get_BUFFER_ID();
547 		bc.fetch_type = w0.get_FETCH_TYPE();
548 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
549 		bc.mega_fetch_count = w0.get_MEGA_FETCH_COUNT();
550 		bc.src_gpr = w0.get_SRC_GPR();
551 		bc.src_rel = w0.get_SRC_REL();
552 		bc.src_sel[0] = w0.get_SRC_SEL_X();
553 	}
554 
555 	if (bc.op == FETCH_OP_SEMFETCH) {
556 		VTX_WORD1_SEM_ALL w1(dw1);
557 		bc.data_format = w1.get_DATA_FORMAT();
558 		bc.dst_sel[0] = w1.get_DST_SEL_X();
559 		bc.dst_sel[1] = w1.get_DST_SEL_Y();
560 		bc.dst_sel[2] = w1.get_DST_SEL_Z();
561 		bc.dst_sel[3] = w1.get_DST_SEL_W();
562 		bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
563 		bc.num_format_all = w1.get_NUM_FORMAT_ALL();
564 		bc.srf_mode_all = w1.get_SRF_MODE_ALL();
565 		bc.use_const_fields = w1.get_USE_CONST_FIELDS();
566 
567 		bc.semantic_id = w1.get_SEMANTIC_ID();
568 
569 	} else {
570 		VTX_WORD1_GPR_ALL w1(dw1);
571 		bc.data_format = w1.get_DATA_FORMAT();
572 		bc.dst_sel[0] = w1.get_DST_SEL_X();
573 		bc.dst_sel[1] = w1.get_DST_SEL_Y();
574 		bc.dst_sel[2] = w1.get_DST_SEL_Z();
575 		bc.dst_sel[3] = w1.get_DST_SEL_W();
576 		bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
577 		bc.num_format_all = w1.get_NUM_FORMAT_ALL();
578 		bc.srf_mode_all = w1.get_SRF_MODE_ALL();
579 		bc.use_const_fields = w1.get_USE_CONST_FIELDS();
580 
581 		bc.dst_gpr = w1.get_DST_GPR();
582 		bc.dst_rel = w1.get_DST_REL();
583 	}
584 
585 	switch (ctx.hw_class) {
586 	case HW_CLASS_R600:
587 	{
588 		VTX_WORD2_R6 w2(dw2);
589 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
590 		bc.endian_swap = w2.get_ENDIAN_SWAP();
591 		bc.mega_fetch = w2.get_MEGA_FETCH();
592 		bc.offset[0] = w2.get_OFFSET();
593 		break;
594 	}
595 	case HW_CLASS_R700:
596 	{
597 		VTX_WORD2_R7 w2(dw2);
598 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
599 		bc.endian_swap = w2.get_ENDIAN_SWAP();
600 		bc.mega_fetch = w2.get_MEGA_FETCH();
601 		bc.offset[0] = w2.get_OFFSET();
602 		bc.alt_const = w2.get_ALT_CONST();
603 		break;
604 	}
605 	case HW_CLASS_EVERGREEN:
606 	{
607 		VTX_WORD2_EG w2(dw2);
608 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
609 		bc.endian_swap = w2.get_ENDIAN_SWAP();
610 		bc.mega_fetch = w2.get_MEGA_FETCH();
611 		bc.offset[0] = w2.get_OFFSET();
612 		bc.alt_const = w2.get_ALT_CONST();
613 		bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
614 		break;
615 	}
616 	case HW_CLASS_CAYMAN:
617 	{
618 		VTX_WORD2_CM w2(dw2);
619 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
620 		bc.endian_swap = w2.get_ENDIAN_SWAP();
621 		bc.offset[0] = w2.get_OFFSET();
622 		bc.alt_const = w2.get_ALT_CONST();
623 		bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
624 		break;
625 	}
626 	default:
627 		assert(!"unknown hw class");
628 		return -1;
629 	}
630 
631 	return r;
632 }
633 
634 }
635