1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2013 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #include <assert.h>
7*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
8*61046927SAndroid Build Coastguard Worker #include <stdint.h>
9*61046927SAndroid Build Coastguard Worker #include <stdio.h>
10*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
11*61046927SAndroid Build Coastguard Worker #include <string.h>
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include <util/log.h>
14*61046927SAndroid Build Coastguard Worker #include <util/u_debug.h>
15*61046927SAndroid Build Coastguard Worker
16*61046927SAndroid Build Coastguard Worker #include "freedreno/isa/ir3-isa.h"
17*61046927SAndroid Build Coastguard Worker
18*61046927SAndroid Build Coastguard Worker #include "disasm.h"
19*61046927SAndroid Build Coastguard Worker #include "instr-a3xx.h"
20*61046927SAndroid Build Coastguard Worker
21*61046927SAndroid Build Coastguard Worker static enum debug_t debug;
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker static const char *levels[] = {
24*61046927SAndroid Build Coastguard Worker "",
25*61046927SAndroid Build Coastguard Worker "\t",
26*61046927SAndroid Build Coastguard Worker "\t\t",
27*61046927SAndroid Build Coastguard Worker "\t\t\t",
28*61046927SAndroid Build Coastguard Worker "\t\t\t\t",
29*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t",
30*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t",
31*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t",
32*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t\t",
33*61046927SAndroid Build Coastguard Worker "\t\t\t\t\t\t\t\t\t",
34*61046927SAndroid Build Coastguard Worker "x",
35*61046927SAndroid Build Coastguard Worker "x",
36*61046927SAndroid Build Coastguard Worker "x",
37*61046927SAndroid Build Coastguard Worker "x",
38*61046927SAndroid Build Coastguard Worker "x",
39*61046927SAndroid Build Coastguard Worker "x",
40*61046927SAndroid Build Coastguard Worker };
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker struct disasm_ctx {
43*61046927SAndroid Build Coastguard Worker FILE *out;
44*61046927SAndroid Build Coastguard Worker struct isa_decode_options *options;
45*61046927SAndroid Build Coastguard Worker unsigned level;
46*61046927SAndroid Build Coastguard Worker unsigned extra_cycles;
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker /**
49*61046927SAndroid Build Coastguard Worker * nop_count/has_end used to detect the real end of shader. Since
50*61046927SAndroid Build Coastguard Worker * in some cases there can be a epilogue following an `end` we look
51*61046927SAndroid Build Coastguard Worker * for a sequence of `nop`s following the `end`
52*61046927SAndroid Build Coastguard Worker */
53*61046927SAndroid Build Coastguard Worker int nop_count; /* number of nop's since non-nop instruction: */
54*61046927SAndroid Build Coastguard Worker bool has_end; /* have we seen end instruction */
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker int cur_n; /* current instr # */
57*61046927SAndroid Build Coastguard Worker int cur_opc_cat; /* current opc_cat */
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker int sfu_delay;
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker /**
62*61046927SAndroid Build Coastguard Worker * State accumulated decoding fields of the current instruction,
63*61046927SAndroid Build Coastguard Worker * handled after decoding is complete (ie. at start of next instr)
64*61046927SAndroid Build Coastguard Worker */
65*61046927SAndroid Build Coastguard Worker struct {
66*61046927SAndroid Build Coastguard Worker bool ss;
67*61046927SAndroid Build Coastguard Worker uint8_t nop;
68*61046927SAndroid Build Coastguard Worker uint8_t repeat;
69*61046927SAndroid Build Coastguard Worker } last;
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker /**
72*61046927SAndroid Build Coastguard Worker * State accumulated decoding fields of src or dst register
73*61046927SAndroid Build Coastguard Worker */
74*61046927SAndroid Build Coastguard Worker struct {
75*61046927SAndroid Build Coastguard Worker bool half;
76*61046927SAndroid Build Coastguard Worker bool r;
77*61046927SAndroid Build Coastguard Worker enum {
78*61046927SAndroid Build Coastguard Worker FILE_GPR = 1,
79*61046927SAndroid Build Coastguard Worker FILE_CONST = 2,
80*61046927SAndroid Build Coastguard Worker } file;
81*61046927SAndroid Build Coastguard Worker unsigned num;
82*61046927SAndroid Build Coastguard Worker } reg;
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker struct shader_stats *stats;
85*61046927SAndroid Build Coastguard Worker };
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker static void
print_stats(struct disasm_ctx * ctx)88*61046927SAndroid Build Coastguard Worker print_stats(struct disasm_ctx *ctx)
89*61046927SAndroid Build Coastguard Worker {
90*61046927SAndroid Build Coastguard Worker if (ctx->options->gpu_id >= 600) {
91*61046927SAndroid Build Coastguard Worker /* handle MERGEREGS case.. this isn't *entirely* accurate, as
92*61046927SAndroid Build Coastguard Worker * you can have shader stages not using merged register file,
93*61046927SAndroid Build Coastguard Worker * but it is good enough for a guestimate:
94*61046927SAndroid Build Coastguard Worker */
95*61046927SAndroid Build Coastguard Worker unsigned n = (ctx->stats->halfreg + 1) / 2;
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker ctx->stats->halfreg = 0;
98*61046927SAndroid Build Coastguard Worker ctx->stats->fullreg = MAX2(ctx->stats->fullreg, n);
99*61046927SAndroid Build Coastguard Worker }
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker unsigned instructions = ctx->cur_n + ctx->extra_cycles + 1;
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker fprintf(ctx->out, "%sStats:\n", levels[ctx->level]);
104*61046927SAndroid Build Coastguard Worker fprintf(ctx->out,
105*61046927SAndroid Build Coastguard Worker "%s- shaderdb: %u instr, %u nops, %u non-nops, %u mov, %u cov\n",
106*61046927SAndroid Build Coastguard Worker levels[ctx->level], instructions, ctx->stats->nops,
107*61046927SAndroid Build Coastguard Worker instructions - ctx->stats->nops, ctx->stats->mov_count,
108*61046927SAndroid Build Coastguard Worker ctx->stats->cov_count);
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker fprintf(ctx->out,
111*61046927SAndroid Build Coastguard Worker "%s- shaderdb: %u last-baryf, %d half, %d full, %u constlen\n",
112*61046927SAndroid Build Coastguard Worker levels[ctx->level], ctx->stats->last_baryf,
113*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(ctx->stats->halfreg, 4),
114*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(ctx->stats->fullreg, 4),
115*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(ctx->stats->constlen, 4));
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker fprintf(
118*61046927SAndroid Build Coastguard Worker ctx->out,
119*61046927SAndroid Build Coastguard Worker "%s- shaderdb: %u cat0, %u cat1, %u cat2, %u cat3, %u cat4, %u cat5, %u cat6, %u cat7\n",
120*61046927SAndroid Build Coastguard Worker levels[ctx->level], ctx->stats->instrs_per_cat[0],
121*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[1], ctx->stats->instrs_per_cat[2],
122*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[3], ctx->stats->instrs_per_cat[4],
123*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[5], ctx->stats->instrs_per_cat[6],
124*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[7]);
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker fprintf(ctx->out, "%s- shaderdb: %u sstall, %u (ss), %u (sy)\n",
127*61046927SAndroid Build Coastguard Worker levels[ctx->level], ctx->stats->sstall, ctx->stats->ss,
128*61046927SAndroid Build Coastguard Worker ctx->stats->sy);
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker static const struct opc_info {
132*61046927SAndroid Build Coastguard Worker const char *name;
133*61046927SAndroid Build Coastguard Worker } opcs[1 << (3 + NOPC_BITS)] = {
134*61046927SAndroid Build Coastguard Worker #define OPC(cat, opc, name) [(opc)] = {#name}
135*61046927SAndroid Build Coastguard Worker /* clang-format off */
136*61046927SAndroid Build Coastguard Worker /* category 0: */
137*61046927SAndroid Build Coastguard Worker OPC(0, OPC_NOP, nop),
138*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BR, br),
139*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BRAC, brac),
140*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BRAA, braa),
141*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BRAO, brao),
142*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BALL, ball),
143*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BANY, bany),
144*61046927SAndroid Build Coastguard Worker OPC(0, OPC_JUMP, jump),
145*61046927SAndroid Build Coastguard Worker OPC(0, OPC_CALL, call),
146*61046927SAndroid Build Coastguard Worker OPC(0, OPC_RET, ret),
147*61046927SAndroid Build Coastguard Worker OPC(0, OPC_KILL, kill),
148*61046927SAndroid Build Coastguard Worker OPC(0, OPC_DEMOTE, demote),
149*61046927SAndroid Build Coastguard Worker OPC(0, OPC_END, end),
150*61046927SAndroid Build Coastguard Worker OPC(0, OPC_EMIT, emit),
151*61046927SAndroid Build Coastguard Worker OPC(0, OPC_CUT, cut),
152*61046927SAndroid Build Coastguard Worker OPC(0, OPC_CHMASK, chmask),
153*61046927SAndroid Build Coastguard Worker OPC(0, OPC_CHSH, chsh),
154*61046927SAndroid Build Coastguard Worker OPC(0, OPC_FLOW_REV, flow_rev),
155*61046927SAndroid Build Coastguard Worker OPC(0, OPC_PREDT, predt),
156*61046927SAndroid Build Coastguard Worker OPC(0, OPC_PREDF, predf),
157*61046927SAndroid Build Coastguard Worker OPC(0, OPC_PREDE, prede),
158*61046927SAndroid Build Coastguard Worker OPC(0, OPC_BKT, bkt),
159*61046927SAndroid Build Coastguard Worker OPC(0, OPC_STKS, stks),
160*61046927SAndroid Build Coastguard Worker OPC(0, OPC_STKR, stkr),
161*61046927SAndroid Build Coastguard Worker OPC(0, OPC_XSET, xset),
162*61046927SAndroid Build Coastguard Worker OPC(0, OPC_XCLR, xclr),
163*61046927SAndroid Build Coastguard Worker OPC(0, OPC_GETLAST, getlast),
164*61046927SAndroid Build Coastguard Worker OPC(0, OPC_GETONE, getone),
165*61046927SAndroid Build Coastguard Worker OPC(0, OPC_DBG, dbg),
166*61046927SAndroid Build Coastguard Worker OPC(0, OPC_SHPS, shps),
167*61046927SAndroid Build Coastguard Worker OPC(0, OPC_SHPE, shpe),
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker /* category 1: */
170*61046927SAndroid Build Coastguard Worker OPC(1, OPC_MOV, ),
171*61046927SAndroid Build Coastguard Worker OPC(1, OPC_MOVMSK, movmsk),
172*61046927SAndroid Build Coastguard Worker OPC(1, OPC_SWZ, swz),
173*61046927SAndroid Build Coastguard Worker OPC(1, OPC_SCT, sct),
174*61046927SAndroid Build Coastguard Worker OPC(1, OPC_GAT, gat),
175*61046927SAndroid Build Coastguard Worker OPC(1, OPC_BALLOT_MACRO, ballot.macro),
176*61046927SAndroid Build Coastguard Worker OPC(1, OPC_ANY_MACRO, any.macro),
177*61046927SAndroid Build Coastguard Worker OPC(1, OPC_ALL_MACRO, all.macro),
178*61046927SAndroid Build Coastguard Worker OPC(1, OPC_ELECT_MACRO, elect.macro),
179*61046927SAndroid Build Coastguard Worker OPC(1, OPC_READ_COND_MACRO, read_cond.macro),
180*61046927SAndroid Build Coastguard Worker OPC(1, OPC_READ_FIRST_MACRO, read_first.macro),
181*61046927SAndroid Build Coastguard Worker OPC(1, OPC_SCAN_MACRO, scan.macro),
182*61046927SAndroid Build Coastguard Worker OPC(1, OPC_SCAN_CLUSTERS_MACRO, scan_clusters.macro),
183*61046927SAndroid Build Coastguard Worker OPC(1, OPC_SHPS_MACRO, shps.macro),
184*61046927SAndroid Build Coastguard Worker OPC(1, OPC_PUSH_CONSTS_LOAD_MACRO, push_consts_load.macro),
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker /* category 2: */
187*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ADD_F, add.f),
188*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MIN_F, min.f),
189*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MAX_F, max.f),
190*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MUL_F, mul.f),
191*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SIGN_F, sign.f),
192*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPS_F, cmps.f),
193*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ABSNEG_F, absneg.f),
194*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPV_F, cmpv.f),
195*61046927SAndroid Build Coastguard Worker OPC(2, OPC_FLOOR_F, floor.f),
196*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CEIL_F, ceil.f),
197*61046927SAndroid Build Coastguard Worker OPC(2, OPC_RNDNE_F, rndne.f),
198*61046927SAndroid Build Coastguard Worker OPC(2, OPC_RNDAZ_F, rndaz.f),
199*61046927SAndroid Build Coastguard Worker OPC(2, OPC_TRUNC_F, trunc.f),
200*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ADD_U, add.u),
201*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ADD_S, add.s),
202*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SUB_U, sub.u),
203*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SUB_S, sub.s),
204*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPS_U, cmps.u),
205*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPS_S, cmps.s),
206*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MIN_U, min.u),
207*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MIN_S, min.s),
208*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MAX_U, max.u),
209*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MAX_S, max.s),
210*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ABSNEG_S, absneg.s),
211*61046927SAndroid Build Coastguard Worker OPC(2, OPC_AND_B, and.b),
212*61046927SAndroid Build Coastguard Worker OPC(2, OPC_OR_B, or.b),
213*61046927SAndroid Build Coastguard Worker OPC(2, OPC_NOT_B, not.b),
214*61046927SAndroid Build Coastguard Worker OPC(2, OPC_XOR_B, xor.b),
215*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPV_U, cmpv.u),
216*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CMPV_S, cmpv.s),
217*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MUL_U24, mul.u24),
218*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MUL_S24, mul.s24),
219*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MULL_U, mull.u),
220*61046927SAndroid Build Coastguard Worker OPC(2, OPC_BFREV_B, bfrev.b),
221*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CLZ_S, clz.s),
222*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CLZ_B, clz.b),
223*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SHL_B, shl.b),
224*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SHR_B, shr.b),
225*61046927SAndroid Build Coastguard Worker OPC(2, OPC_ASHR_B, ashr.b),
226*61046927SAndroid Build Coastguard Worker OPC(2, OPC_BARY_F, bary.f),
227*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MGEN_B, mgen.b),
228*61046927SAndroid Build Coastguard Worker OPC(2, OPC_GETBIT_B, getbit.b),
229*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SETRM, setrm),
230*61046927SAndroid Build Coastguard Worker OPC(2, OPC_CBITS_B, cbits.b),
231*61046927SAndroid Build Coastguard Worker OPC(2, OPC_SHB, shb),
232*61046927SAndroid Build Coastguard Worker OPC(2, OPC_MSAD, msad),
233*61046927SAndroid Build Coastguard Worker OPC(2, OPC_FLAT_B, flat.b),
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker /* category 3: */
236*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_U16, mad.u16),
237*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MADSH_U16, madsh.u16),
238*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_S16, mad.s16),
239*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MADSH_M16, madsh.m16),
240*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_U24, mad.u24),
241*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_S24, mad.s24),
242*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_F16, mad.f16),
243*61046927SAndroid Build Coastguard Worker OPC(3, OPC_MAD_F32, mad.f32),
244*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_B16, sel.b16),
245*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_B32, sel.b32),
246*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_S16, sel.s16),
247*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_S32, sel.s32),
248*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_F16, sel.f16),
249*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SEL_F32, sel.f32),
250*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SAD_S16, sad.s16),
251*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SAD_S32, sad.s32),
252*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SHRM, shrm),
253*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SHLM, shlm),
254*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SHRG, shrg),
255*61046927SAndroid Build Coastguard Worker OPC(3, OPC_SHLG, shlg),
256*61046927SAndroid Build Coastguard Worker OPC(3, OPC_ANDG, andg),
257*61046927SAndroid Build Coastguard Worker OPC(3, OPC_DP2ACC, dp2acc),
258*61046927SAndroid Build Coastguard Worker OPC(3, OPC_DP4ACC, dp4acc),
259*61046927SAndroid Build Coastguard Worker OPC(3, OPC_WMM, wmm),
260*61046927SAndroid Build Coastguard Worker OPC(3, OPC_WMM_ACCU, wmm.accu),
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker /* category 4: */
263*61046927SAndroid Build Coastguard Worker OPC(4, OPC_RCP, rcp),
264*61046927SAndroid Build Coastguard Worker OPC(4, OPC_RSQ, rsq),
265*61046927SAndroid Build Coastguard Worker OPC(4, OPC_LOG2, log2),
266*61046927SAndroid Build Coastguard Worker OPC(4, OPC_EXP2, exp2),
267*61046927SAndroid Build Coastguard Worker OPC(4, OPC_SIN, sin),
268*61046927SAndroid Build Coastguard Worker OPC(4, OPC_COS, cos),
269*61046927SAndroid Build Coastguard Worker OPC(4, OPC_SQRT, sqrt),
270*61046927SAndroid Build Coastguard Worker OPC(4, OPC_HRSQ, hrsq),
271*61046927SAndroid Build Coastguard Worker OPC(4, OPC_HLOG2, hlog2),
272*61046927SAndroid Build Coastguard Worker OPC(4, OPC_HEXP2, hexp2),
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /* category 5: */
275*61046927SAndroid Build Coastguard Worker OPC(5, OPC_ISAM, isam),
276*61046927SAndroid Build Coastguard Worker OPC(5, OPC_ISAML, isaml),
277*61046927SAndroid Build Coastguard Worker OPC(5, OPC_ISAMM, isamm),
278*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAM, sam),
279*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMB, samb),
280*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAML, saml),
281*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMGQ, samgq),
282*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GETLOD, getlod),
283*61046927SAndroid Build Coastguard Worker OPC(5, OPC_CONV, conv),
284*61046927SAndroid Build Coastguard Worker OPC(5, OPC_CONVM, convm),
285*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GETSIZE, getsize),
286*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GETBUF, getbuf),
287*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GETPOS, getpos),
288*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GETINFO, getinfo),
289*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSX, dsx),
290*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSY, dsy),
291*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GATHER4R, gather4r),
292*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GATHER4G, gather4g),
293*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GATHER4B, gather4b),
294*61046927SAndroid Build Coastguard Worker OPC(5, OPC_GATHER4A, gather4a),
295*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMGP0, samgp0),
296*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMGP1, samgp1),
297*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMGP2, samgp2),
298*61046927SAndroid Build Coastguard Worker OPC(5, OPC_SAMGP3, samgp3),
299*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSXPP_1, dsxpp.1),
300*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSYPP_1, dsypp.1),
301*61046927SAndroid Build Coastguard Worker OPC(5, OPC_RGETPOS, rgetpos),
302*61046927SAndroid Build Coastguard Worker OPC(5, OPC_RGETINFO, rgetinfo),
303*61046927SAndroid Build Coastguard Worker OPC(5, OPC_BRCST_ACTIVE, brcst.active),
304*61046927SAndroid Build Coastguard Worker OPC(5, OPC_QUAD_SHUFFLE_BRCST, quad_shuffle.brcst),
305*61046927SAndroid Build Coastguard Worker OPC(5, OPC_QUAD_SHUFFLE_HORIZ, quad_shuffle.horiz),
306*61046927SAndroid Build Coastguard Worker OPC(5, OPC_QUAD_SHUFFLE_VERT, quad_shuffle.vert),
307*61046927SAndroid Build Coastguard Worker OPC(5, OPC_QUAD_SHUFFLE_DIAG, quad_shuffle.diag),
308*61046927SAndroid Build Coastguard Worker OPC(5, OPC_TCINV, tcinv),
309*61046927SAndroid Build Coastguard Worker /* macros are needed here for ir3_print */
310*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSXPP_MACRO, dsxpp.macro),
311*61046927SAndroid Build Coastguard Worker OPC(5, OPC_DSYPP_MACRO, dsypp.macro),
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker /* category 6: */
315*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDG, ldg),
316*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDG_A, ldg.a),
317*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDL, ldl),
318*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDP, ldp),
319*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STG, stg),
320*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STG_A, stg.a),
321*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STL, stl),
322*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STP, stp),
323*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDIB, ldib),
324*61046927SAndroid Build Coastguard Worker OPC(6, OPC_G2L, g2l),
325*61046927SAndroid Build Coastguard Worker OPC(6, OPC_L2G, l2g),
326*61046927SAndroid Build Coastguard Worker OPC(6, OPC_PREFETCH, prefetch),
327*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDLW, ldlw),
328*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STLW, stlw),
329*61046927SAndroid Build Coastguard Worker OPC(6, OPC_RESFMT, resfmt),
330*61046927SAndroid Build Coastguard Worker OPC(6, OPC_RESINFO, resinfo),
331*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_ADD, atomic.add),
332*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_SUB, atomic.sub),
333*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_XCHG, atomic.xchg),
334*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_INC, atomic.inc),
335*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_DEC, atomic.dec),
336*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_CMPXCHG, atomic.cmpxchg),
337*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_MIN, atomic.min),
338*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_MAX, atomic.max),
339*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_AND, atomic.and),
340*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_OR, atomic.or),
341*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_XOR, atomic.xor),
342*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_ADD, atomic.b.add),
343*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_SUB, atomic.b.sub),
344*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_XCHG, atomic.b.xchg),
345*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_INC, atomic.b.inc),
346*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_DEC, atomic.b.dec),
347*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_CMPXCHG, atomic.b.cmpxchg),
348*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_MIN, atomic.b.min),
349*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_MAX, atomic.b.max),
350*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_AND, atomic.b.and),
351*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_OR, atomic.b.or),
352*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_B_XOR, atomic.b.xor),
353*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_ADD, atomic.s.add),
354*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_SUB, atomic.s.sub),
355*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_XCHG, atomic.s.xchg),
356*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_INC, atomic.s.inc),
357*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_DEC, atomic.s.dec),
358*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_CMPXCHG, atomic.s.cmpxchg),
359*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_MIN, atomic.s.min),
360*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_MAX, atomic.s.max),
361*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_AND, atomic.s.and),
362*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_OR, atomic.s.or),
363*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_S_XOR, atomic.s.xor),
364*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_ADD, atomic.g.add),
365*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_SUB, atomic.g.sub),
366*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_XCHG, atomic.g.xchg),
367*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_INC, atomic.g.inc),
368*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_DEC, atomic.g.dec),
369*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_CMPXCHG, atomic.g.cmpxchg),
370*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_MIN, atomic.g.min),
371*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_MAX, atomic.g.max),
372*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_AND, atomic.g.and),
373*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_OR, atomic.g.or),
374*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ATOMIC_G_XOR, atomic.g.xor),
375*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDGB, ldgb),
376*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STGB, stgb),
377*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STIB, stib),
378*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDC, ldc),
379*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDLV, ldlv),
380*61046927SAndroid Build Coastguard Worker OPC(6, OPC_PIPR, pipr),
381*61046927SAndroid Build Coastguard Worker OPC(6, OPC_PIPC, pipc),
382*61046927SAndroid Build Coastguard Worker OPC(6, OPC_EMIT2, emit),
383*61046927SAndroid Build Coastguard Worker OPC(6, OPC_ENDLS, endls),
384*61046927SAndroid Build Coastguard Worker OPC(6, OPC_GETSPID, getspid),
385*61046927SAndroid Build Coastguard Worker OPC(6, OPC_GETWID, getwid),
386*61046927SAndroid Build Coastguard Worker OPC(6, OPC_GETFIBERID, getfiberid),
387*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STC, stc),
388*61046927SAndroid Build Coastguard Worker OPC(6, OPC_STSC, stsc),
389*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDC_K, ldc.k),
390*61046927SAndroid Build Coastguard Worker OPC(6, OPC_LDG_K, ldg.k),
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker OPC(6, OPC_SPILL_MACRO, spill.macro),
393*61046927SAndroid Build Coastguard Worker OPC(6, OPC_RELOAD_MACRO, reload.macro),
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker OPC(7, OPC_BAR, bar),
396*61046927SAndroid Build Coastguard Worker OPC(7, OPC_FENCE, fence),
397*61046927SAndroid Build Coastguard Worker OPC(7, OPC_LOCK, lock),
398*61046927SAndroid Build Coastguard Worker OPC(7, OPC_UNLOCK, unlock),
399*61046927SAndroid Build Coastguard Worker /* clang-format on */
400*61046927SAndroid Build Coastguard Worker #undef OPC
401*61046927SAndroid Build Coastguard Worker };
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker const char *
disasm_a3xx_instr_name(opc_t opc)404*61046927SAndroid Build Coastguard Worker disasm_a3xx_instr_name(opc_t opc)
405*61046927SAndroid Build Coastguard Worker {
406*61046927SAndroid Build Coastguard Worker if (opc_cat(opc) == OPC_META)
407*61046927SAndroid Build Coastguard Worker return "??meta??";
408*61046927SAndroid Build Coastguard Worker return opcs[opc].name;
409*61046927SAndroid Build Coastguard Worker }
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker static void
disasm_field_cb(void * d,const char * field_name,struct isa_decode_value * val)412*61046927SAndroid Build Coastguard Worker disasm_field_cb(void *d, const char *field_name, struct isa_decode_value *val)
413*61046927SAndroid Build Coastguard Worker {
414*61046927SAndroid Build Coastguard Worker struct disasm_ctx *ctx = d;
415*61046927SAndroid Build Coastguard Worker
416*61046927SAndroid Build Coastguard Worker if (!strcmp(field_name, "NAME")) {
417*61046927SAndroid Build Coastguard Worker if (!strcmp("nop", val->str)) {
418*61046927SAndroid Build Coastguard Worker if (ctx->has_end) {
419*61046927SAndroid Build Coastguard Worker ctx->nop_count++;
420*61046927SAndroid Build Coastguard Worker if (ctx->nop_count > 3) {
421*61046927SAndroid Build Coastguard Worker ctx->options->stop = true;
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker }
424*61046927SAndroid Build Coastguard Worker ctx->stats->nops += 1 + ctx->last.repeat;
425*61046927SAndroid Build Coastguard Worker } else {
426*61046927SAndroid Build Coastguard Worker ctx->nop_count = 0;
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker if (!strcmp("end", val->str)) {
430*61046927SAndroid Build Coastguard Worker ctx->has_end = true;
431*61046927SAndroid Build Coastguard Worker ctx->nop_count = 0;
432*61046927SAndroid Build Coastguard Worker } else if (!strcmp("chsh", val->str)) {
433*61046927SAndroid Build Coastguard Worker ctx->options->stop = true;
434*61046927SAndroid Build Coastguard Worker } else if (!strcmp("bary.f", val->str)) {
435*61046927SAndroid Build Coastguard Worker ctx->stats->last_baryf = ctx->cur_n;
436*61046927SAndroid Build Coastguard Worker }
437*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "REPEAT")) {
438*61046927SAndroid Build Coastguard Worker ctx->extra_cycles += val->num;
439*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[ctx->cur_opc_cat] += val->num;
440*61046927SAndroid Build Coastguard Worker ctx->last.repeat = val->num;
441*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "NOP")) {
442*61046927SAndroid Build Coastguard Worker ctx->extra_cycles += val->num;
443*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[0] += val->num;
444*61046927SAndroid Build Coastguard Worker ctx->stats->nops += val->num;
445*61046927SAndroid Build Coastguard Worker ctx->last.nop = val->num;
446*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "SY")) {
447*61046927SAndroid Build Coastguard Worker ctx->stats->sy += val->num;
448*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "SS")) {
449*61046927SAndroid Build Coastguard Worker ctx->stats->ss += val->num;
450*61046927SAndroid Build Coastguard Worker ctx->last.ss = !!val->num;
451*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "CONST")) {
452*61046927SAndroid Build Coastguard Worker ctx->reg.num = val->num;
453*61046927SAndroid Build Coastguard Worker ctx->reg.file = FILE_CONST;
454*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "GPR")) {
455*61046927SAndroid Build Coastguard Worker /* don't count GPR regs r48.x (shared) or higher: */
456*61046927SAndroid Build Coastguard Worker if (val->num < 48) {
457*61046927SAndroid Build Coastguard Worker ctx->reg.num = val->num;
458*61046927SAndroid Build Coastguard Worker ctx->reg.file = FILE_GPR;
459*61046927SAndroid Build Coastguard Worker }
460*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "SRC_R") || !strcmp(field_name, "SRC1_R") ||
461*61046927SAndroid Build Coastguard Worker !strcmp(field_name, "SRC2_R") || !strcmp(field_name, "SRC3_R")) {
462*61046927SAndroid Build Coastguard Worker ctx->reg.r = val->num;
463*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "DST")) {
464*61046927SAndroid Build Coastguard Worker /* Dest register is always repeated
465*61046927SAndroid Build Coastguard Worker *
466*61046927SAndroid Build Coastguard Worker * Note that this doesn't really properly handle instructions
467*61046927SAndroid Build Coastguard Worker * that write multiple components.. the old disasm didn't handle
468*61046927SAndroid Build Coastguard Worker * that case either.
469*61046927SAndroid Build Coastguard Worker */
470*61046927SAndroid Build Coastguard Worker ctx->reg.r = true;
471*61046927SAndroid Build Coastguard Worker } else if (strstr(field_name, "HALF")) {
472*61046927SAndroid Build Coastguard Worker ctx->reg.half = val->num;
473*61046927SAndroid Build Coastguard Worker } else if (!strcmp(field_name, "SWIZ")) {
474*61046927SAndroid Build Coastguard Worker unsigned num = (ctx->reg.num << 2) | val->num;
475*61046927SAndroid Build Coastguard Worker if (ctx->reg.r)
476*61046927SAndroid Build Coastguard Worker num += ctx->last.repeat;
477*61046927SAndroid Build Coastguard Worker
478*61046927SAndroid Build Coastguard Worker if (ctx->reg.file == FILE_CONST) {
479*61046927SAndroid Build Coastguard Worker ctx->stats->constlen = MAX2(ctx->stats->constlen, num);
480*61046927SAndroid Build Coastguard Worker } else if (ctx->reg.file == FILE_GPR) {
481*61046927SAndroid Build Coastguard Worker if (ctx->reg.half) {
482*61046927SAndroid Build Coastguard Worker ctx->stats->halfreg = MAX2(ctx->stats->halfreg, num);
483*61046927SAndroid Build Coastguard Worker } else {
484*61046927SAndroid Build Coastguard Worker ctx->stats->fullreg = MAX2(ctx->stats->fullreg, num);
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker }
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker memset(&ctx->reg, 0, sizeof(ctx->reg));
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker /**
493*61046927SAndroid Build Coastguard Worker * Handle stat updates dealt with at the end of instruction decoding,
494*61046927SAndroid Build Coastguard Worker * ie. before beginning of next instruction
495*61046927SAndroid Build Coastguard Worker */
496*61046927SAndroid Build Coastguard Worker static void
disasm_handle_last(struct disasm_ctx * ctx)497*61046927SAndroid Build Coastguard Worker disasm_handle_last(struct disasm_ctx *ctx)
498*61046927SAndroid Build Coastguard Worker {
499*61046927SAndroid Build Coastguard Worker if (ctx->last.ss) {
500*61046927SAndroid Build Coastguard Worker ctx->stats->sstall += ctx->sfu_delay;
501*61046927SAndroid Build Coastguard Worker ctx->sfu_delay = 0;
502*61046927SAndroid Build Coastguard Worker }
503*61046927SAndroid Build Coastguard Worker
504*61046927SAndroid Build Coastguard Worker if (ctx->cur_opc_cat == 4) {
505*61046927SAndroid Build Coastguard Worker ctx->sfu_delay = 10;
506*61046927SAndroid Build Coastguard Worker } else {
507*61046927SAndroid Build Coastguard Worker int n = MIN2(ctx->sfu_delay, 1 + ctx->last.repeat + ctx->last.nop);
508*61046927SAndroid Build Coastguard Worker ctx->sfu_delay -= n;
509*61046927SAndroid Build Coastguard Worker }
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker memset(&ctx->last, 0, sizeof(ctx->last));
512*61046927SAndroid Build Coastguard Worker }
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker static void
disasm_instr_cb(void * d,unsigned n,void * instr)515*61046927SAndroid Build Coastguard Worker disasm_instr_cb(void *d, unsigned n, void *instr)
516*61046927SAndroid Build Coastguard Worker {
517*61046927SAndroid Build Coastguard Worker struct disasm_ctx *ctx = d;
518*61046927SAndroid Build Coastguard Worker uint32_t *dwords = (uint32_t *)instr;
519*61046927SAndroid Build Coastguard Worker uint64_t val = dwords[1];
520*61046927SAndroid Build Coastguard Worker val = val << 32;
521*61046927SAndroid Build Coastguard Worker val |= dwords[0];
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker unsigned opc_cat = val >> 61;
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker /* There are some cases where we can get instr_cb called multiple
526*61046927SAndroid Build Coastguard Worker * times per instruction (like when we need an extra line for branch
527*61046927SAndroid Build Coastguard Worker * target labels), don't update stats in these cases:
528*61046927SAndroid Build Coastguard Worker */
529*61046927SAndroid Build Coastguard Worker if (n != ctx->cur_n) {
530*61046927SAndroid Build Coastguard Worker if (n > 0) {
531*61046927SAndroid Build Coastguard Worker disasm_handle_last(ctx);
532*61046927SAndroid Build Coastguard Worker }
533*61046927SAndroid Build Coastguard Worker ctx->stats->instrs_per_cat[opc_cat]++;
534*61046927SAndroid Build Coastguard Worker ctx->cur_n = n;
535*61046927SAndroid Build Coastguard Worker
536*61046927SAndroid Build Coastguard Worker /* mov vs cov stats are a bit harder to fish out of the field
537*61046927SAndroid Build Coastguard Worker * names, because current ir3-cat1.xml doesn't use {NAME} for
538*61046927SAndroid Build Coastguard Worker * this distinction. So for now just handle this case with
539*61046927SAndroid Build Coastguard Worker * some hand-coded parsing:
540*61046927SAndroid Build Coastguard Worker */
541*61046927SAndroid Build Coastguard Worker if (opc_cat == 1) {
542*61046927SAndroid Build Coastguard Worker unsigned opc = (val >> 57) & 0x3;
543*61046927SAndroid Build Coastguard Worker unsigned src_type = (val >> 50) & 0x7;
544*61046927SAndroid Build Coastguard Worker unsigned dst_type = (val >> 46) & 0x7;
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker if (opc == 0) {
547*61046927SAndroid Build Coastguard Worker if (src_type == dst_type) {
548*61046927SAndroid Build Coastguard Worker ctx->stats->mov_count++;
549*61046927SAndroid Build Coastguard Worker } else {
550*61046927SAndroid Build Coastguard Worker ctx->stats->cov_count++;
551*61046927SAndroid Build Coastguard Worker }
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker }
555*61046927SAndroid Build Coastguard Worker
556*61046927SAndroid Build Coastguard Worker ctx->cur_opc_cat = opc_cat;
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker if (debug & PRINT_RAW) {
559*61046927SAndroid Build Coastguard Worker fprintf(ctx->out, "%s:%d:%04d:%04d[%08xx_%08xx] ", levels[ctx->level],
560*61046927SAndroid Build Coastguard Worker opc_cat, n, ctx->extra_cycles + n, dwords[1], dwords[0]);
561*61046927SAndroid Build Coastguard Worker }
562*61046927SAndroid Build Coastguard Worker }
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker int
disasm_a3xx_stat(uint32_t * dwords,int sizedwords,int level,FILE * out,unsigned gpu_id,struct shader_stats * stats)565*61046927SAndroid Build Coastguard Worker disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
566*61046927SAndroid Build Coastguard Worker unsigned gpu_id, struct shader_stats *stats)
567*61046927SAndroid Build Coastguard Worker {
568*61046927SAndroid Build Coastguard Worker struct isa_decode_options decode_options = {
569*61046927SAndroid Build Coastguard Worker .gpu_id = gpu_id,
570*61046927SAndroid Build Coastguard Worker .show_errors = true,
571*61046927SAndroid Build Coastguard Worker .max_errors = 5,
572*61046927SAndroid Build Coastguard Worker .branch_labels = true,
573*61046927SAndroid Build Coastguard Worker .field_cb = disasm_field_cb,
574*61046927SAndroid Build Coastguard Worker .pre_instr_cb = disasm_instr_cb,
575*61046927SAndroid Build Coastguard Worker };
576*61046927SAndroid Build Coastguard Worker struct disasm_ctx ctx = {
577*61046927SAndroid Build Coastguard Worker .out = out,
578*61046927SAndroid Build Coastguard Worker .level = level,
579*61046927SAndroid Build Coastguard Worker .options = &decode_options,
580*61046927SAndroid Build Coastguard Worker .stats = stats,
581*61046927SAndroid Build Coastguard Worker .cur_n = -1,
582*61046927SAndroid Build Coastguard Worker };
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker memset(stats, 0, sizeof(*stats));
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker decode_options.cbdata = &ctx;
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker ir3_isa_disasm(dwords, sizedwords * 4, out, &decode_options);
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker disasm_handle_last(&ctx);
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker if (debug & PRINT_STATS)
593*61046927SAndroid Build Coastguard Worker print_stats(&ctx);
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker return 0;
596*61046927SAndroid Build Coastguard Worker }
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker void
disasm_a3xx_set_debug(enum debug_t d)599*61046927SAndroid Build Coastguard Worker disasm_a3xx_set_debug(enum debug_t d)
600*61046927SAndroid Build Coastguard Worker {
601*61046927SAndroid Build Coastguard Worker debug = d;
602*61046927SAndroid Build Coastguard Worker }
603*61046927SAndroid Build Coastguard Worker
604*61046927SAndroid Build Coastguard Worker #include <setjmp.h>
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker static bool jmp_env_valid;
607*61046927SAndroid Build Coastguard Worker static jmp_buf jmp_env;
608*61046927SAndroid Build Coastguard Worker
609*61046927SAndroid Build Coastguard Worker void
ir3_assert_handler(const char * expr,const char * file,int line,const char * func)610*61046927SAndroid Build Coastguard Worker ir3_assert_handler(const char *expr, const char *file, int line,
611*61046927SAndroid Build Coastguard Worker const char *func)
612*61046927SAndroid Build Coastguard Worker {
613*61046927SAndroid Build Coastguard Worker mesa_loge("%s:%u: %s: Assertion `%s' failed.", file, line, func, expr);
614*61046927SAndroid Build Coastguard Worker if (jmp_env_valid)
615*61046927SAndroid Build Coastguard Worker longjmp(jmp_env, 1);
616*61046927SAndroid Build Coastguard Worker abort();
617*61046927SAndroid Build Coastguard Worker }
618*61046927SAndroid Build Coastguard Worker
619*61046927SAndroid Build Coastguard Worker #define TRY(x) \
620*61046927SAndroid Build Coastguard Worker do { \
621*61046927SAndroid Build Coastguard Worker assert(!jmp_env_valid); \
622*61046927SAndroid Build Coastguard Worker if (setjmp(jmp_env) == 0) { \
623*61046927SAndroid Build Coastguard Worker jmp_env_valid = true; \
624*61046927SAndroid Build Coastguard Worker x; \
625*61046927SAndroid Build Coastguard Worker } \
626*61046927SAndroid Build Coastguard Worker jmp_env_valid = false; \
627*61046927SAndroid Build Coastguard Worker } while (0)
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker int
disasm_a3xx(uint32_t * dwords,int sizedwords,int level,FILE * out,unsigned gpu_id)630*61046927SAndroid Build Coastguard Worker disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out,
631*61046927SAndroid Build Coastguard Worker unsigned gpu_id)
632*61046927SAndroid Build Coastguard Worker {
633*61046927SAndroid Build Coastguard Worker struct shader_stats stats;
634*61046927SAndroid Build Coastguard Worker return disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats);
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker
637*61046927SAndroid Build Coastguard Worker int
try_disasm_a3xx(uint32_t * dwords,int sizedwords,int level,FILE * out,unsigned gpu_id)638*61046927SAndroid Build Coastguard Worker try_disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out,
639*61046927SAndroid Build Coastguard Worker unsigned gpu_id)
640*61046927SAndroid Build Coastguard Worker {
641*61046927SAndroid Build Coastguard Worker struct shader_stats stats;
642*61046927SAndroid Build Coastguard Worker int ret = -1;
643*61046927SAndroid Build Coastguard Worker TRY(ret = disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats));
644*61046927SAndroid Build Coastguard Worker return ret;
645*61046927SAndroid Build Coastguard Worker }
646