~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/r600/sb/sb_bc_decoder.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
}