util: Add a mapping from VkFormat to PIPE_FORMAT.
[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 void
70 mir_print_swizzle(unsigned *swizzle)
71 {
72 printf(".");
73
74 for (unsigned i = 0; i < 16; ++i)
75 putchar(components[swizzle[i]]);
76 }
77
78 static const char *
79 mir_get_unit(unsigned unit)
80 {
81 switch (unit) {
82 case ALU_ENAB_VEC_MUL:
83 return "vmul";
84 case ALU_ENAB_SCAL_ADD:
85 return "sadd";
86 case ALU_ENAB_VEC_ADD:
87 return "vadd";
88 case ALU_ENAB_SCAL_MUL:
89 return "smul";
90 case ALU_ENAB_VEC_LUT:
91 return "lut";
92 case ALU_ENAB_BR_COMPACT:
93 return "br";
94 case ALU_ENAB_BRANCH:
95 return "brx";
96 default:
97 return "???";
98 }
99 }
100
101 void
102 mir_print_instruction(midgard_instruction *ins)
103 {
104 printf("\t");
105
106 switch (ins->type) {
107 case TAG_ALU_4: {
108 midgard_alu_op op = ins->alu.op;
109 const char *name = alu_opcode_props[op].name;
110
111 const char *branch_target_names[] = {
112 "goto", "break", "continue", "discard"
113 };
114
115 if (ins->compact_branch && !ins->prepacked_branch)
116 name = branch_target_names[ins->branch.target_type];
117
118 if (ins->unit)
119 printf("%s.", mir_get_unit(ins->unit));
120
121 printf("%s", name ? name : "??");
122 break;
123 }
124
125 case TAG_LOAD_STORE_4: {
126 midgard_load_store_op op = ins->load_store.op;
127 const char *name = load_store_opcode_props[op].name;
128
129 assert(name);
130 printf("%s", name);
131 break;
132 }
133
134 case TAG_TEXTURE_4: {
135 printf("texture");
136 break;
137 }
138
139 default:
140 assert(0);
141 }
142
143 if (ins->invert || (ins->compact_branch && !ins->prepacked_branch && ins->branch.invert_conditional))
144 printf(".not");
145
146 printf(" ");
147 mir_print_index(ins->dest);
148
149 if (ins->mask != 0xF)
150 mir_print_mask(ins->mask);
151
152 printf(", ");
153
154 mir_print_index(ins->src[0]);
155 mir_print_swizzle(ins->swizzle[0]);
156 printf(", ");
157
158 if (ins->has_inline_constant)
159 printf("#%d", ins->inline_constant);
160 else {
161 mir_print_index(ins->src[1]);
162 mir_print_swizzle(ins->swizzle[1]);
163 }
164
165 printf(", ");
166 mir_print_index(ins->src[2]);
167 mir_print_swizzle(ins->swizzle[2]);
168
169 if (ins->has_constants) {
170 uint32_t *uc = ins->constants;
171 float *fc = (float *) uc;
172
173 if (midgard_is_integer_op(ins->alu.op))
174 printf(" <0x%X, 0x%X, 0x%X, 0x%x>", uc[0], uc[1], uc[2], uc[3]);
175 else
176 printf(" <%f, %f, %f, %f>", fc[0], fc[1], fc[2], fc[3]);
177 }
178
179 if (ins->no_spill)
180 printf(" /* no spill */");
181
182 printf("\n");
183 }
184
185 /* Dumps MIR for a block or entire shader respective */
186
187 void
188 mir_print_block(midgard_block *block)
189 {
190 printf("block%u: {\n", block->source_id);
191
192 if (block->is_scheduled) {
193 mir_foreach_bundle_in_block(block, bundle) {
194 for (unsigned i = 0; i < bundle->instruction_count; ++i)
195 mir_print_instruction(bundle->instructions[i]);
196
197 printf("\n");
198 }
199 } else {
200 mir_foreach_instr_in_block(block, ins) {
201 mir_print_instruction(ins);
202 }
203 }
204
205 printf("}");
206
207 if (block->nr_successors) {
208 printf(" -> ");
209 for (unsigned i = 0; i < block->nr_successors; ++i) {
210 printf("block%u%s", block->successors[i]->source_id,
211 (i + 1) != block->nr_successors ? ", " : "");
212 }
213 }
214
215 printf(" from { ");
216 mir_foreach_predecessor(block, pred)
217 printf("block%u ", pred->source_id);
218 printf("}");
219
220 printf("\n\n");
221 }
222
223 void
224 mir_print_shader(compiler_context *ctx)
225 {
226 mir_foreach_block(ctx, block) {
227 mir_print_block(block);
228 }
229 }