5d19f6f6800a06f2fd230b2b7e681ee8d40cf957
[mesa.git] / src / panfrost / midgard / midgard_print.c
1 /*
2 * Copyright (C) 2018-2019 Alyssa Rosenzweig <alyssa@rosenzweig.io>
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include "compiler.h"
25 #include "helpers.h"
26 #include "midgard_ops.h"
27
28 /* Pretty printer for Midgard IR, for use debugging compiler-internal
29 * passes like register allocation. The output superficially resembles
30 * Midgard assembly, with the exception that unit information and such is
31 * (normally) omitted, and generic indices are usually used instead of
32 * registers */
33
34 static void
35 mir_print_index(int source)
36 {
37 if (source < 0) {
38 printf("_");
39 return;
40 }
41
42 if (source >= SSA_FIXED_MINIMUM) {
43 /* Specific register */
44 int reg = SSA_REG_FROM_FIXED(source);
45
46 /* TODO: Moving threshold */
47 if (reg > 16 && reg < 24)
48 printf("u%d", 23 - reg);
49 else
50 printf("r%d", reg);
51 } else {
52 printf("%d", source);
53 }
54 }
55
56 static const char components[16] = "xyzwefghijklmnop";
57
58 static void
59 mir_print_mask(unsigned mask)
60 {
61 printf(".");
62
63 for (unsigned i = 0; i < 16; ++i) {
64 if (mask & (1 << i))
65 putchar(components[i]);
66 }
67 }
68
69 static const char *
70 mir_get_unit(unsigned unit)
71 {
72 switch (unit) {
73 case ALU_ENAB_VEC_MUL:
74 return "vmul";
75 case ALU_ENAB_SCAL_ADD:
76 return "sadd";
77 case ALU_ENAB_VEC_ADD:
78 return "vadd";
79 case ALU_ENAB_SCAL_MUL:
80 return "smul";
81 case ALU_ENAB_VEC_LUT:
82 return "lut";
83 case ALU_ENAB_BR_COMPACT:
84 return "br";
85 case ALU_ENAB_BRANCH:
86 return "brx";
87 default:
88 return "???";
89 }
90 }
91
92 void
93 mir_print_instruction(midgard_instruction *ins)
94 {
95 printf("\t");
96
97 switch (ins->type) {
98 case TAG_ALU_4: {
99 midgard_alu_op op = ins->alu.op;
100 const char *name = alu_opcode_props[op].name;
101
102 if (ins->unit)
103 printf("%s.", mir_get_unit(ins->unit));
104
105 printf("%s", name ? name : "??");
106 break;
107 }
108
109 case TAG_LOAD_STORE_4: {
110 midgard_load_store_op op = ins->load_store.op;
111 const char *name = load_store_opcode_names[op];
112
113 assert(name);
114 printf("%s", name);
115 break;
116 }
117
118 case TAG_TEXTURE_4: {
119 printf("texture");
120 break;
121 }
122
123 default:
124 assert(0);
125 }
126
127 if (ins->invert)
128 printf(".not");
129
130 ssa_args *args = &ins->ssa_args;
131
132 printf(" ");
133 mir_print_index(args->dest);
134
135 if (ins->mask != 0xF)
136 mir_print_mask(ins->mask);
137
138 printf(", ");
139
140 mir_print_index(args->src[0]);
141 printf(", ");
142
143 if (args->inline_constant)
144 printf("#%d", ins->inline_constant);
145 else
146 mir_print_index(args->src[1]);
147
148 printf(", ");
149 mir_print_index(args->src[2]);
150
151 if (ins->has_constants)
152 printf(" <%f, %f, %f, %f>", ins->constants[0], ins->constants[1], ins->constants[2], ins->constants[3]);
153
154 if (ins->no_spill)
155 printf(" /* no spill */");
156
157 printf("\n");
158 }
159
160 /* Dumps MIR for a block or entire shader respective */
161
162 void
163 mir_print_block(midgard_block *block)
164 {
165 printf("%p: {\n", block);
166
167 mir_foreach_instr_in_block(block, ins) {
168 mir_print_instruction(ins);
169 }
170
171 printf("}");
172
173 if (block->nr_successors) {
174 printf(" -> ");
175 for (unsigned i = 0; i < block->nr_successors; ++i) {
176 printf("%p%s", block->successors[i],
177 (i + 1) != block->nr_successors ? ", " : "");
178 }
179 }
180
181 printf("\n\n");
182 }
183
184 void
185 mir_print_shader(compiler_context *ctx)
186 {
187 mir_foreach_block(ctx, block) {
188 mir_print_block(block);
189 }
190 }
191
192 void
193 mir_print_bundle(midgard_bundle *bundle)
194 {
195 printf("[\n");
196
197 for (unsigned i = 0; i < bundle->instruction_count; ++i) {
198 midgard_instruction *ins = bundle->instructions[i];
199 mir_print_instruction(ins);
200 }
201
202 printf("]\n");
203 }