r300/compiler: New dataflow structures and passes
[mesa.git] / src / mesa / drivers / dri / r300 / compiler / radeon_program_print.c
1 /*
2 * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23 #include "radeon_program.h"
24
25 #include <stdio.h>
26
27 static void print_comment(FILE * f)
28 {
29 fprintf(f, " # ");
30 }
31
32 static const char * textarget_to_string(rc_texture_target target)
33 {
34 switch(target) {
35 case RC_TEXTURE_2D_ARRAY: return "2D_ARRAY";
36 case RC_TEXTURE_1D_ARRAY: return "1D_ARRAY";
37 case RC_TEXTURE_CUBE: return "CUBE";
38 case RC_TEXTURE_3D: return "3D";
39 case RC_TEXTURE_RECT: return "RECT";
40 case RC_TEXTURE_2D: return "2D";
41 case RC_TEXTURE_1D: return "1D";
42 default: return "BAD_TEXTURE_TARGET";
43 }
44 }
45
46 static void rc_print_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)
47 {
48 if (file == RC_FILE_NONE) {
49 fprintf(f, "none");
50 } else {
51 const char * filename;
52 switch(file) {
53 case RC_FILE_TEMPORARY: filename = "temp"; break;
54 case RC_FILE_INPUT: filename = "input"; break;
55 case RC_FILE_OUTPUT: filename = "output"; break;
56 case RC_FILE_ADDRESS: filename = "addr"; break;
57 case RC_FILE_CONSTANT: filename = "const"; break;
58 default: filename = "BAD FILE"; break;
59 }
60 fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");
61 }
62 }
63
64 static void rc_print_mask(FILE * f, unsigned int mask)
65 {
66 if (mask & RC_MASK_X) fprintf(f, "x");
67 if (mask & RC_MASK_Y) fprintf(f, "y");
68 if (mask & RC_MASK_Z) fprintf(f, "z");
69 if (mask & RC_MASK_W) fprintf(f, "w");
70 }
71
72 static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)
73 {
74 rc_print_register(f, dst.File, dst.Index, dst.RelAddr);
75 if (dst.WriteMask != RC_MASK_XYZW) {
76 fprintf(f, ".");
77 rc_print_mask(f, dst.WriteMask);
78 }
79 }
80
81 static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)
82 {
83 unsigned int comp;
84 for(comp = 0; comp < 4; ++comp) {
85 rc_swizzle swz = GET_SWZ(swizzle, comp);
86 if (GET_BIT(negate, comp))
87 fprintf(f, "-");
88 switch(swz) {
89 case RC_SWIZZLE_X: fprintf(f, "x"); break;
90 case RC_SWIZZLE_Y: fprintf(f, "y"); break;
91 case RC_SWIZZLE_Z: fprintf(f, "z"); break;
92 case RC_SWIZZLE_W: fprintf(f, "w"); break;
93 case RC_SWIZZLE_ZERO: fprintf(f, "0"); break;
94 case RC_SWIZZLE_ONE: fprintf(f, "1"); break;
95 case RC_SWIZZLE_HALF: fprintf(f, "H"); break;
96 case RC_SWIZZLE_UNUSED: fprintf(f, "_"); break;
97 }
98 }
99 }
100
101 static void rc_print_src_register(FILE * f, struct rc_src_register src)
102 {
103 int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);
104
105 if (src.Negate == RC_MASK_XYZW)
106 fprintf(f, "-");
107 if (src.Abs)
108 fprintf(f, "|");
109
110 rc_print_register(f, src.File, src.Index, src.RelAddr);
111
112 if (src.Abs && !trivial_negate)
113 fprintf(f, "|");
114
115 if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {
116 fprintf(f, ".");
117 rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);
118 }
119
120 if (src.Abs && trivial_negate)
121 fprintf(f, "|");
122 }
123
124 static void rc_print_ref(FILE * f, struct rc_dataflow_ref * ref)
125 {
126 fprintf(f, "ref(%p", ref->Vector);
127
128 if (ref->UseMask != RC_MASK_XYZW) {
129 fprintf(f, ".");
130 rc_print_mask(f, ref->UseMask);
131 }
132
133 fprintf(f, ")");
134 }
135
136 static void rc_print_instruction(FILE * f, unsigned int flags, struct rc_instruction * inst)
137 {
138 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
139 unsigned int reg;
140
141 fprintf(f, "%s", opcode->Name);
142
143 switch(inst->I.SaturateMode) {
144 case RC_SATURATE_NONE: break;
145 case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;
146 case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;
147 default: fprintf(f, "_BAD_SAT"); break;
148 }
149
150 if (opcode->HasDstReg) {
151 fprintf(f, " ");
152 rc_print_dst_register(f, inst->I.DstReg);
153 if (opcode->NumSrcRegs)
154 fprintf(f, ",");
155 }
156
157 for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
158 if (reg > 0)
159 fprintf(f, ",");
160 fprintf(f, " ");
161 rc_print_src_register(f, inst->I.SrcReg[reg]);
162 }
163
164 if (opcode->HasTexture) {
165 fprintf(f, ", %s%s[%u]",
166 textarget_to_string(inst->I.TexSrcTarget),
167 inst->I.TexShadow ? "SHADOW" : "",
168 inst->I.TexSrcUnit);
169 }
170
171 fprintf(f, ";\n");
172
173 if (flags & RC_PRINT_DATAFLOW) {
174 print_comment(f);
175
176 fprintf(f, "Dst = %p", inst->Dataflow.DstReg);
177 if (inst->Dataflow.DstRegAliased)
178 fprintf(f, " aliased");
179 if (inst->Dataflow.DstRegPrev) {
180 fprintf(f, " from ");
181 rc_print_ref(f, inst->Dataflow.DstRegPrev);
182 }
183
184 for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
185 fprintf(f, ", ");
186 if (inst->Dataflow.SrcReg[reg])
187 rc_print_ref(f, inst->Dataflow.SrcReg[reg]);
188 else
189 fprintf(f, "<no ref>");
190 }
191
192 fprintf(f, "\n");
193 }
194 }
195
196 /**
197 * Print program to stderr, default options.
198 */
199 void rc_print_program(const struct rc_program *prog, unsigned int flags)
200 {
201 unsigned int linenum = 0;
202 struct rc_instruction *inst;
203
204 fprintf(stderr, "# Radeon Compiler Program%s\n",
205 flags & RC_PRINT_DATAFLOW ? " (with dataflow annotations)" : "");
206
207 for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
208 fprintf(stderr, "%3d: ", linenum);
209
210 rc_print_instruction(stderr, flags, inst);
211
212 linenum++;
213 }
214 }