1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * Authors:
6*61046927SAndroid Build Coastguard Worker * Rob Clark <[email protected]>
7*61046927SAndroid Build Coastguard Worker */
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
10*61046927SAndroid Build Coastguard Worker #include <stdio.h>
11*61046927SAndroid Build Coastguard Worker
12*61046927SAndroid Build Coastguard Worker #include "util/log.h"
13*61046927SAndroid Build Coastguard Worker #include "ir3.h"
14*61046927SAndroid Build Coastguard Worker
15*61046927SAndroid Build Coastguard Worker #define PTRID(x) ((unsigned long)(x))
16*61046927SAndroid Build Coastguard Worker
17*61046927SAndroid Build Coastguard Worker /* ansi escape sequences: */
18*61046927SAndroid Build Coastguard Worker #define RESET "\x1b[0m"
19*61046927SAndroid Build Coastguard Worker #define RED "\x1b[0;31m"
20*61046927SAndroid Build Coastguard Worker #define GREEN "\x1b[0;32m"
21*61046927SAndroid Build Coastguard Worker #define BLUE "\x1b[0;34m"
22*61046927SAndroid Build Coastguard Worker #define MAGENTA "\x1b[0;35m"
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker /* syntax coloring, mostly to make it easier to see different sorts of
25*61046927SAndroid Build Coastguard Worker * srcs (immediate, constant, ssa, array, ...)
26*61046927SAndroid Build Coastguard Worker */
27*61046927SAndroid Build Coastguard Worker #define SYN_REG(x) RED x RESET
28*61046927SAndroid Build Coastguard Worker #define SYN_IMMED(x) GREEN x RESET
29*61046927SAndroid Build Coastguard Worker #define SYN_CONST(x) GREEN x RESET
30*61046927SAndroid Build Coastguard Worker #define SYN_SSA(x) BLUE x RESET
31*61046927SAndroid Build Coastguard Worker #define SYN_ARRAY(x) MAGENTA x RESET
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker static const char *
type_name(type_t type)34*61046927SAndroid Build Coastguard Worker type_name(type_t type)
35*61046927SAndroid Build Coastguard Worker {
36*61046927SAndroid Build Coastguard Worker static const char *type_names[] = {
37*61046927SAndroid Build Coastguard Worker /* clang-format off */
38*61046927SAndroid Build Coastguard Worker [TYPE_F16] = "f16",
39*61046927SAndroid Build Coastguard Worker [TYPE_F32] = "f32",
40*61046927SAndroid Build Coastguard Worker [TYPE_U16] = "u16",
41*61046927SAndroid Build Coastguard Worker [TYPE_U32] = "u32",
42*61046927SAndroid Build Coastguard Worker [TYPE_S16] = "s16",
43*61046927SAndroid Build Coastguard Worker [TYPE_S32] = "s32",
44*61046927SAndroid Build Coastguard Worker [TYPE_U8] = "u8",
45*61046927SAndroid Build Coastguard Worker [TYPE_U8_32] = "u8_32",
46*61046927SAndroid Build Coastguard Worker /* clang-format on */
47*61046927SAndroid Build Coastguard Worker };
48*61046927SAndroid Build Coastguard Worker return type_names[type];
49*61046927SAndroid Build Coastguard Worker }
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker static void
print_instr_name(struct log_stream * stream,struct ir3_instruction * instr,bool flags)52*61046927SAndroid Build Coastguard Worker print_instr_name(struct log_stream *stream, struct ir3_instruction *instr,
53*61046927SAndroid Build Coastguard Worker bool flags)
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker if (!instr)
56*61046927SAndroid Build Coastguard Worker return;
57*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
58*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%04u:", instr->serialno);
59*61046927SAndroid Build Coastguard Worker #endif
60*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%04u:", instr->ip);
61*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_UNUSED) {
62*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "XXX: ");
63*61046927SAndroid Build Coastguard Worker } else {
64*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%03u: ", instr->use_count);
65*61046927SAndroid Build Coastguard Worker }
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker if (flags) {
68*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "\t");
69*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_SY)
70*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(sy)");
71*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_SS)
72*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(ss)");
73*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_JP)
74*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(jp)");
75*61046927SAndroid Build Coastguard Worker if (instr->repeat)
76*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(rpt%d)", instr->repeat);
77*61046927SAndroid Build Coastguard Worker if (instr->nop)
78*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(nop%d)", instr->nop);
79*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_UL)
80*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(ul)");
81*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_SAT)
82*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(sat)");
83*61046927SAndroid Build Coastguard Worker } else {
84*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " ");
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker if (is_meta(instr)) {
88*61046927SAndroid Build Coastguard Worker switch (instr->opc) {
89*61046927SAndroid Build Coastguard Worker case OPC_META_INPUT:
90*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:in");
91*61046927SAndroid Build Coastguard Worker break;
92*61046927SAndroid Build Coastguard Worker case OPC_META_SPLIT:
93*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:split");
94*61046927SAndroid Build Coastguard Worker break;
95*61046927SAndroid Build Coastguard Worker case OPC_META_COLLECT:
96*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:collect");
97*61046927SAndroid Build Coastguard Worker break;
98*61046927SAndroid Build Coastguard Worker case OPC_META_TEX_PREFETCH:
99*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:tex_prefetch");
100*61046927SAndroid Build Coastguard Worker break;
101*61046927SAndroid Build Coastguard Worker case OPC_META_PARALLEL_COPY:
102*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:parallel_copy");
103*61046927SAndroid Build Coastguard Worker break;
104*61046927SAndroid Build Coastguard Worker case OPC_META_PHI:
105*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:phi");
106*61046927SAndroid Build Coastguard Worker break;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /* shouldn't hit here.. just for debugging: */
109*61046927SAndroid Build Coastguard Worker default:
110*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "_meta:%d", instr->opc);
111*61046927SAndroid Build Coastguard Worker break;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker } else if (opc_cat(instr->opc) == 1) {
114*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_MOV) {
115*61046927SAndroid Build Coastguard Worker if (instr->cat1.src_type == instr->cat1.dst_type)
116*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "mov");
117*61046927SAndroid Build Coastguard Worker else
118*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "cov");
119*61046927SAndroid Build Coastguard Worker } else {
120*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%s",
121*61046927SAndroid Build Coastguard Worker disasm_a3xx_instr_name(instr->opc));
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_SCAN_MACRO ||
125*61046927SAndroid Build Coastguard Worker instr->opc == OPC_SCAN_CLUSTERS_MACRO) {
126*61046927SAndroid Build Coastguard Worker switch (instr->cat1.reduce_op) {
127*61046927SAndroid Build Coastguard Worker case REDUCE_OP_ADD_U:
128*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".add.u");
129*61046927SAndroid Build Coastguard Worker break;
130*61046927SAndroid Build Coastguard Worker case REDUCE_OP_ADD_F:
131*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".add.f");
132*61046927SAndroid Build Coastguard Worker break;
133*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MUL_U:
134*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".mul.u");
135*61046927SAndroid Build Coastguard Worker break;
136*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MUL_F:
137*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".mul.f");
138*61046927SAndroid Build Coastguard Worker break;
139*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MIN_U:
140*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".min.u");
141*61046927SAndroid Build Coastguard Worker break;
142*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MIN_S:
143*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".min.s");
144*61046927SAndroid Build Coastguard Worker break;
145*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MIN_F:
146*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".min.f");
147*61046927SAndroid Build Coastguard Worker break;
148*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MAX_U:
149*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".max.u");
150*61046927SAndroid Build Coastguard Worker break;
151*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MAX_S:
152*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".max.s");
153*61046927SAndroid Build Coastguard Worker break;
154*61046927SAndroid Build Coastguard Worker case REDUCE_OP_MAX_F:
155*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".max.f");
156*61046927SAndroid Build Coastguard Worker break;
157*61046927SAndroid Build Coastguard Worker case REDUCE_OP_AND_B:
158*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".and.b");
159*61046927SAndroid Build Coastguard Worker break;
160*61046927SAndroid Build Coastguard Worker case REDUCE_OP_OR_B:
161*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".or.b");
162*61046927SAndroid Build Coastguard Worker break;
163*61046927SAndroid Build Coastguard Worker case REDUCE_OP_XOR_B:
164*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".xor.b");
165*61046927SAndroid Build Coastguard Worker break;
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker if (instr->opc != OPC_MOVMSK && instr->opc != OPC_SCAN_MACRO &&
170*61046927SAndroid Build Coastguard Worker instr->opc != OPC_PUSH_CONSTS_LOAD_MACRO) {
171*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".%s%s",
172*61046927SAndroid Build Coastguard Worker type_name(instr->cat1.src_type),
173*61046927SAndroid Build Coastguard Worker type_name(instr->cat1.dst_type));
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker } else {
176*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%s", disasm_a3xx_instr_name(instr->opc));
177*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_3D)
178*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".3d");
179*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_A)
180*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".a");
181*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_O)
182*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".o");
183*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_P)
184*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".p");
185*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_S)
186*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".s");
187*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_V)
188*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".v");
189*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_A1EN)
190*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".a1en");
191*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_U)
192*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".u");
193*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_LDC)
194*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".offset%d", instr->cat6.d);
195*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_LDC_K)
196*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".%d", instr->cat6.iim_val);
197*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_B) {
198*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(
199*61046927SAndroid Build Coastguard Worker stream, ".base%d",
200*61046927SAndroid Build Coastguard Worker is_tex(instr) ? instr->cat5.tex_base : instr->cat6.base);
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker if (instr->flags & IR3_INSTR_S2EN)
203*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".s2en");
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker static const char *cond[0x7] = {
206*61046927SAndroid Build Coastguard Worker "lt", "le", "gt", "ge", "eq", "ne",
207*61046927SAndroid Build Coastguard Worker };
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker switch (instr->opc) {
210*61046927SAndroid Build Coastguard Worker case OPC_CMPS_F:
211*61046927SAndroid Build Coastguard Worker case OPC_CMPS_U:
212*61046927SAndroid Build Coastguard Worker case OPC_CMPS_S:
213*61046927SAndroid Build Coastguard Worker case OPC_CMPV_F:
214*61046927SAndroid Build Coastguard Worker case OPC_CMPV_U:
215*61046927SAndroid Build Coastguard Worker case OPC_CMPV_S:
216*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".%s",
217*61046927SAndroid Build Coastguard Worker cond[instr->cat2.condition & 0x7]);
218*61046927SAndroid Build Coastguard Worker break;
219*61046927SAndroid Build Coastguard Worker case OPC_BRAC:
220*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".%u", instr->cat0.idx);
221*61046927SAndroid Build Coastguard Worker break;
222*61046927SAndroid Build Coastguard Worker default:
223*61046927SAndroid Build Coastguard Worker break;
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker }
226*61046927SAndroid Build Coastguard Worker }
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker static void
print_ssa_def_name(struct log_stream * stream,struct ir3_register * reg)229*61046927SAndroid Build Coastguard Worker print_ssa_def_name(struct log_stream *stream, struct ir3_register *reg)
230*61046927SAndroid Build Coastguard Worker {
231*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_SSA("ssa_%u"), reg->instr->serialno);
232*61046927SAndroid Build Coastguard Worker if (reg->name != 0)
233*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ":%u", reg->name);
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker static void
print_ssa_name(struct log_stream * stream,struct ir3_register * reg,bool dst)237*61046927SAndroid Build Coastguard Worker print_ssa_name(struct log_stream *stream, struct ir3_register *reg, bool dst)
238*61046927SAndroid Build Coastguard Worker {
239*61046927SAndroid Build Coastguard Worker if (!dst) {
240*61046927SAndroid Build Coastguard Worker if (!reg->def)
241*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_SSA("undef"));
242*61046927SAndroid Build Coastguard Worker else
243*61046927SAndroid Build Coastguard Worker print_ssa_def_name(stream, reg->def);
244*61046927SAndroid Build Coastguard Worker } else {
245*61046927SAndroid Build Coastguard Worker print_ssa_def_name(stream, reg);
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker if (reg->num != INVALID_REG && !(reg->flags & IR3_REG_ARRAY)) {
249*61046927SAndroid Build Coastguard Worker const char *prefix = "r";
250*61046927SAndroid Build Coastguard Worker unsigned num = reg_num(reg);
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_PREDICATE) {
253*61046927SAndroid Build Coastguard Worker prefix = "p";
254*61046927SAndroid Build Coastguard Worker num = 0;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(" SYN_REG("%s%u.%c") ")", prefix, num,
258*61046927SAndroid Build Coastguard Worker "xyzw"[reg_comp(reg)]);
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker static void
print_reg_name(struct log_stream * stream,struct ir3_instruction * instr,struct ir3_register * reg,bool dest)263*61046927SAndroid Build Coastguard Worker print_reg_name(struct log_stream *stream, struct ir3_instruction *instr,
264*61046927SAndroid Build Coastguard Worker struct ir3_register *reg, bool dest)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker if ((reg->flags & (IR3_REG_FABS | IR3_REG_SABS)) &&
267*61046927SAndroid Build Coastguard Worker (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT)))
268*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(absneg)");
269*61046927SAndroid Build Coastguard Worker else if (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT))
270*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(neg)");
271*61046927SAndroid Build Coastguard Worker else if (reg->flags & (IR3_REG_FABS | IR3_REG_SABS))
272*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(abs)");
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_FIRST_KILL)
275*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(kill)");
276*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_UNUSED)
277*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(unused)");
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_R)
280*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(r)");
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_EARLY_CLOBBER)
283*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(early_clobber)");
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker /* Right now all instructions that use tied registers only have one
286*61046927SAndroid Build Coastguard Worker * destination register, so we can just print (tied) as if it's a flag,
287*61046927SAndroid Build Coastguard Worker * although it's more convenient for RA if it's a pointer.
288*61046927SAndroid Build Coastguard Worker */
289*61046927SAndroid Build Coastguard Worker if (reg->tied)
290*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(tied)");
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_BR || instr->opc == OPC_BRAA ||
293*61046927SAndroid Build Coastguard Worker instr->opc == OPC_BRAO) {
294*61046927SAndroid Build Coastguard Worker bool inv = reg == instr->srcs[0] ? instr->cat0.inv1 : instr->cat0.inv2;
295*61046927SAndroid Build Coastguard Worker if (inv)
296*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "!");
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_SHARED)
300*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "s");
301*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_HALF)
302*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "h");
303*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_PREDICATE)
304*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "p");
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_IMMED) {
307*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_IMMED("imm[%f,%d,0x%x]"), reg->fim_val,
308*61046927SAndroid Build Coastguard Worker reg->iim_val, reg->iim_val);
309*61046927SAndroid Build Coastguard Worker } else if (reg->flags & IR3_REG_ARRAY) {
310*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_SSA) {
311*61046927SAndroid Build Coastguard Worker print_ssa_name(stream, reg, dest);
312*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ":");
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream,
315*61046927SAndroid Build Coastguard Worker SYN_ARRAY("arr[id=%u, offset=%d, size=%u]"),
316*61046927SAndroid Build Coastguard Worker reg->array.id, reg->array.offset, reg->size);
317*61046927SAndroid Build Coastguard Worker if (reg->array.base != INVALID_REG)
318*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(" SYN_REG("r%u.%c") ")",
319*61046927SAndroid Build Coastguard Worker reg->array.base >> 2,
320*61046927SAndroid Build Coastguard Worker "xyzw"[reg->array.base & 0x3]);
321*61046927SAndroid Build Coastguard Worker } else if (reg->flags & IR3_REG_SSA) {
322*61046927SAndroid Build Coastguard Worker print_ssa_name(stream, reg, dest);
323*61046927SAndroid Build Coastguard Worker } else if (reg->flags & IR3_REG_RELATIV) {
324*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_CONST)
325*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_CONST("c<a0.x + %d>"),
326*61046927SAndroid Build Coastguard Worker reg->array.offset);
327*61046927SAndroid Build Coastguard Worker else
328*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_REG("r<a0.x + %d>") " (%u)",
329*61046927SAndroid Build Coastguard Worker reg->array.offset, reg->size);
330*61046927SAndroid Build Coastguard Worker } else {
331*61046927SAndroid Build Coastguard Worker if (reg->flags & IR3_REG_CONST)
332*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_CONST("c%u.%c"), reg_num(reg),
333*61046927SAndroid Build Coastguard Worker "xyzw"[reg_comp(reg)]);
334*61046927SAndroid Build Coastguard Worker else if (reg->flags & IR3_REG_PREDICATE)
335*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_REG("p0.%c"),
336*61046927SAndroid Build Coastguard Worker "xyzw"[reg_comp(reg)]);
337*61046927SAndroid Build Coastguard Worker else
338*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_REG("r%u.%c"), reg_num(reg),
339*61046927SAndroid Build Coastguard Worker "xyzw"[reg_comp(reg)]);
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker if (reg->wrmask > 0x1)
343*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " (wrmask=0x%x)", reg->wrmask);
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker static void
tab(struct log_stream * stream,int lvl)347*61046927SAndroid Build Coastguard Worker tab(struct log_stream *stream, int lvl)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker for (int i = 0; i < lvl; i++)
350*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "\t");
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker static void
print_instr(struct log_stream * stream,struct ir3_instruction * instr,int lvl)354*61046927SAndroid Build Coastguard Worker print_instr(struct log_stream *stream, struct ir3_instruction *instr, int lvl)
355*61046927SAndroid Build Coastguard Worker {
356*61046927SAndroid Build Coastguard Worker tab(stream, lvl);
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker print_instr_name(stream, instr, true);
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker if (is_tex(instr)) {
361*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_BRCST_ACTIVE)
362*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ".w%d", instr->cat5.cluster_size);
363*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " (%s)(", type_name(instr->cat5.type));
364*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < 4; i++)
365*61046927SAndroid Build Coastguard Worker if (instr->dsts[0]->wrmask & (1 << i))
366*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%c", "xyzw"[i]);
367*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ")");
368*61046927SAndroid Build Coastguard Worker } else if ((instr->srcs_count > 0 || instr->dsts_count > 0)) {
369*61046927SAndroid Build Coastguard Worker /* NOTE the b(ranch) instruction has a suffix, which is
370*61046927SAndroid Build Coastguard Worker * handled below
371*61046927SAndroid Build Coastguard Worker */
372*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " ");
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker if (opc_cat(instr->opc) == 1) {
376*61046927SAndroid Build Coastguard Worker switch (instr->cat1.round) {
377*61046927SAndroid Build Coastguard Worker case ROUND_ZERO:
378*61046927SAndroid Build Coastguard Worker break;
379*61046927SAndroid Build Coastguard Worker case ROUND_EVEN:
380*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(even)");
381*61046927SAndroid Build Coastguard Worker break;
382*61046927SAndroid Build Coastguard Worker case ROUND_POS_INF:
383*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(pos_infinity)");
384*61046927SAndroid Build Coastguard Worker break;
385*61046927SAndroid Build Coastguard Worker case ROUND_NEG_INF:
386*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "(neg_infinity)");
387*61046927SAndroid Build Coastguard Worker break;
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker bool first = true;
392*61046927SAndroid Build Coastguard Worker foreach_dst (reg, instr) {
393*61046927SAndroid Build Coastguard Worker if (reg->wrmask == 0)
394*61046927SAndroid Build Coastguard Worker continue;
395*61046927SAndroid Build Coastguard Worker if (!first)
396*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
397*61046927SAndroid Build Coastguard Worker print_reg_name(stream, instr, reg, true);
398*61046927SAndroid Build Coastguard Worker first = false;
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker foreach_src_n (reg, n, instr) {
401*61046927SAndroid Build Coastguard Worker if (!first)
402*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
403*61046927SAndroid Build Coastguard Worker print_reg_name(stream, instr, reg, false);
404*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_END || instr->opc == OPC_CHMASK)
405*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " (%u)", instr->end.outidxs[n]);
406*61046927SAndroid Build Coastguard Worker first = false;
407*61046927SAndroid Build Coastguard Worker }
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker if (is_tex(instr) && !(instr->flags & IR3_INSTR_S2EN) &&
410*61046927SAndroid Build Coastguard Worker !is_tex_shuffle(instr)) {
411*61046927SAndroid Build Coastguard Worker if (!!(instr->flags & IR3_INSTR_B) && !!(instr->flags & IR3_INSTR_A1EN)) {
412*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", s#%d", instr->cat5.samp);
413*61046927SAndroid Build Coastguard Worker } else {
414*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", s#%d, t#%d", instr->cat5.samp,
415*61046927SAndroid Build Coastguard Worker instr->cat5.tex);
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker }
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker if (instr->opc == OPC_META_SPLIT) {
420*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", off=%d", instr->split.off);
421*61046927SAndroid Build Coastguard Worker } else if (instr->opc == OPC_META_TEX_PREFETCH) {
422*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", tex=%d, samp=%d, input_offset=%d",
423*61046927SAndroid Build Coastguard Worker instr->prefetch.tex, instr->prefetch.samp,
424*61046927SAndroid Build Coastguard Worker instr->prefetch.input_offset);
425*61046927SAndroid Build Coastguard Worker } else if (instr->opc == OPC_PUSH_CONSTS_LOAD_MACRO) {
426*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(
427*61046927SAndroid Build Coastguard Worker stream, " dst_offset=%d, src_offset = %d, src_size = %d",
428*61046927SAndroid Build Coastguard Worker instr->push_consts.dst_base, instr->push_consts.src_base,
429*61046927SAndroid Build Coastguard Worker instr->push_consts.src_size);
430*61046927SAndroid Build Coastguard Worker } else if (instr->opc == OPC_SPILL_MACRO) {
431*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " dst_offset=%d", instr->cat6.dst_offset);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker if (is_flow(instr) && instr->cat0.target) {
435*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " target=block%u",
436*61046927SAndroid Build Coastguard Worker block_id(instr->cat0.target));
437*61046927SAndroid Build Coastguard Worker }
438*61046927SAndroid Build Coastguard Worker
439*61046927SAndroid Build Coastguard Worker if (instr->deps_count) {
440*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", false-deps:");
441*61046927SAndroid Build Coastguard Worker unsigned n = 0;
442*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < instr->deps_count; i++) {
443*61046927SAndroid Build Coastguard Worker if (!instr->deps[i])
444*61046927SAndroid Build Coastguard Worker continue;
445*61046927SAndroid Build Coastguard Worker if (n++ > 0)
446*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
447*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, SYN_SSA("ssa_%u"),
448*61046927SAndroid Build Coastguard Worker instr->deps[i]->serialno);
449*61046927SAndroid Build Coastguard Worker }
450*61046927SAndroid Build Coastguard Worker }
451*61046927SAndroid Build Coastguard Worker
452*61046927SAndroid Build Coastguard Worker if (ir3_instr_is_rpt(instr)) {
453*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", rpt: ");
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker if (ir3_instr_is_first_rpt(instr)) {
456*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "first");
457*61046927SAndroid Build Coastguard Worker } else {
458*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%u",
459*61046927SAndroid Build Coastguard Worker ir3_instr_prev_rpt(instr)->serialno);
460*61046927SAndroid Build Coastguard Worker }
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "\n");
464*61046927SAndroid Build Coastguard Worker }
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker void
ir3_print_instr_stream(struct log_stream * stream,struct ir3_instruction * instr)467*61046927SAndroid Build Coastguard Worker ir3_print_instr_stream(struct log_stream *stream, struct ir3_instruction *instr)
468*61046927SAndroid Build Coastguard Worker {
469*61046927SAndroid Build Coastguard Worker print_instr(stream, instr, 0);
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker void
ir3_print_instr(struct ir3_instruction * instr)473*61046927SAndroid Build Coastguard Worker ir3_print_instr(struct ir3_instruction *instr)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker struct log_stream *stream = mesa_log_streami();
476*61046927SAndroid Build Coastguard Worker print_instr(stream, instr, 0);
477*61046927SAndroid Build Coastguard Worker mesa_log_stream_destroy(stream);
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker
480*61046927SAndroid Build Coastguard Worker static void
print_block(struct ir3_block * block,int lvl)481*61046927SAndroid Build Coastguard Worker print_block(struct ir3_block *block, int lvl)
482*61046927SAndroid Build Coastguard Worker {
483*61046927SAndroid Build Coastguard Worker struct log_stream *stream = mesa_log_streami();
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker tab(stream, lvl);
486*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "%sblock%u {\n",
487*61046927SAndroid Build Coastguard Worker block->reconvergence_point ? "(jp)" : "",
488*61046927SAndroid Build Coastguard Worker block_id(block));
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker if (block->predecessors_count > 0) {
491*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
492*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "pred: ");
493*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < block->predecessors_count; i++) {
494*61046927SAndroid Build Coastguard Worker struct ir3_block *pred = block->predecessors[i];
495*61046927SAndroid Build Coastguard Worker if (i != 0)
496*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
497*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "block%u", block_id(pred));
498*61046927SAndroid Build Coastguard Worker }
499*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "\n");
500*61046927SAndroid Build Coastguard Worker }
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker if (block->physical_predecessors_count > 0) {
503*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
504*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "physical pred: ");
505*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < block->physical_predecessors_count; i++) {
506*61046927SAndroid Build Coastguard Worker struct ir3_block *pred = block->physical_predecessors[i];
507*61046927SAndroid Build Coastguard Worker if (i != 0)
508*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
509*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "block%u", block_id(pred));
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "\n");
512*61046927SAndroid Build Coastguard Worker }
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker foreach_instr (instr, &block->instr_list) {
515*61046927SAndroid Build Coastguard Worker print_instr(stream, instr, lvl + 1);
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
519*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "/* keeps:\n");
520*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < block->keeps_count; i++) {
521*61046927SAndroid Build Coastguard Worker print_instr(stream, block->keeps[i], lvl + 2);
522*61046927SAndroid Build Coastguard Worker }
523*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
524*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " */\n");
525*61046927SAndroid Build Coastguard Worker
526*61046927SAndroid Build Coastguard Worker if (block->successors[0]) {
527*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
528*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "/* succs: block%u",
529*61046927SAndroid Build Coastguard Worker block_id(block->successors[0]));
530*61046927SAndroid Build Coastguard Worker if (block->successors[1]) {
531*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", block%u",
532*61046927SAndroid Build Coastguard Worker block_id(block->successors[1]));
533*61046927SAndroid Build Coastguard Worker
534*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " (%s)",
535*61046927SAndroid Build Coastguard Worker block->divergent_condition ? "div" : "con");
536*61046927SAndroid Build Coastguard Worker }
537*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " */\n");
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker if (block->physical_successors_count > 0) {
540*61046927SAndroid Build Coastguard Worker tab(stream, lvl + 1);
541*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "/* physical succs: ");
542*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < block->physical_successors_count; i++) {
543*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "block%u",
544*61046927SAndroid Build Coastguard Worker block_id(block->physical_successors[i]));
545*61046927SAndroid Build Coastguard Worker if (i < block->physical_successors_count - 1)
546*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, ", ");
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, " */\n");
549*61046927SAndroid Build Coastguard Worker }
550*61046927SAndroid Build Coastguard Worker tab(stream, lvl);
551*61046927SAndroid Build Coastguard Worker mesa_log_stream_printf(stream, "}\n");
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker void
ir3_print(struct ir3 * ir)555*61046927SAndroid Build Coastguard Worker ir3_print(struct ir3 *ir)
556*61046927SAndroid Build Coastguard Worker {
557*61046927SAndroid Build Coastguard Worker foreach_block (block, &ir->block_list)
558*61046927SAndroid Build Coastguard Worker print_block(block, 0);
559*61046927SAndroid Build Coastguard Worker }
560