r300/compiler: Refactor to allow different instruction types
[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 const char * textarget_to_string(rc_texture_target target)
28 {
29 switch(target) {
30 case RC_TEXTURE_2D_ARRAY: return "2D_ARRAY";
31 case RC_TEXTURE_1D_ARRAY: return "1D_ARRAY";
32 case RC_TEXTURE_CUBE: return "CUBE";
33 case RC_TEXTURE_3D: return "3D";
34 case RC_TEXTURE_RECT: return "RECT";
35 case RC_TEXTURE_2D: return "2D";
36 case RC_TEXTURE_1D: return "1D";
37 default: return "BAD_TEXTURE_TARGET";
38 }
39 }
40
41 static void rc_print_comparefunc(FILE * f, const char * lhs, rc_compare_func func, const char * rhs)
42 {
43 if (func == RC_COMPARE_FUNC_NEVER) {
44 fprintf(f, "false");
45 } else if (func == RC_COMPARE_FUNC_ALWAYS) {
46 fprintf(f, "true");
47 } else {
48 const char * op;
49 switch(func) {
50 case RC_COMPARE_FUNC_LESS: op = "<"; break;
51 case RC_COMPARE_FUNC_EQUAL: op = "=="; break;
52 case RC_COMPARE_FUNC_LEQUAL: op = "<="; break;
53 case RC_COMPARE_FUNC_GREATER: op = ">"; break;
54 case RC_COMPARE_FUNC_NOTEQUAL: op = "!="; break;
55 case RC_COMPARE_FUNC_GEQUAL: op = ">="; break;
56 default: op = "???"; break;
57 }
58 fprintf(f, "%s %s %s", lhs, op, rhs);
59 }
60 }
61
62 static void rc_print_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)
63 {
64 if (file == RC_FILE_NONE) {
65 fprintf(f, "none");
66 } else if (file == RC_FILE_SPECIAL) {
67 switch(index) {
68 case RC_SPECIAL_ALU_RESULT: fprintf(f, "aluresult"); break;
69 default: fprintf(f, "special[%i]", index); break;
70 }
71 } else {
72 const char * filename;
73 switch(file) {
74 case RC_FILE_TEMPORARY: filename = "temp"; break;
75 case RC_FILE_INPUT: filename = "input"; break;
76 case RC_FILE_OUTPUT: filename = "output"; break;
77 case RC_FILE_ADDRESS: filename = "addr"; break;
78 case RC_FILE_CONSTANT: filename = "const"; break;
79 default: filename = "BAD FILE"; break;
80 }
81 fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");
82 }
83 }
84
85 static void rc_print_mask(FILE * f, unsigned int mask)
86 {
87 if (mask & RC_MASK_X) fprintf(f, "x");
88 if (mask & RC_MASK_Y) fprintf(f, "y");
89 if (mask & RC_MASK_Z) fprintf(f, "z");
90 if (mask & RC_MASK_W) fprintf(f, "w");
91 }
92
93 static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)
94 {
95 rc_print_register(f, dst.File, dst.Index, dst.RelAddr);
96 if (dst.WriteMask != RC_MASK_XYZW) {
97 fprintf(f, ".");
98 rc_print_mask(f, dst.WriteMask);
99 }
100 }
101
102 static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)
103 {
104 unsigned int comp;
105 for(comp = 0; comp < 4; ++comp) {
106 rc_swizzle swz = GET_SWZ(swizzle, comp);
107 if (GET_BIT(negate, comp))
108 fprintf(f, "-");
109 switch(swz) {
110 case RC_SWIZZLE_X: fprintf(f, "x"); break;
111 case RC_SWIZZLE_Y: fprintf(f, "y"); break;
112 case RC_SWIZZLE_Z: fprintf(f, "z"); break;
113 case RC_SWIZZLE_W: fprintf(f, "w"); break;
114 case RC_SWIZZLE_ZERO: fprintf(f, "0"); break;
115 case RC_SWIZZLE_ONE: fprintf(f, "1"); break;
116 case RC_SWIZZLE_HALF: fprintf(f, "H"); break;
117 case RC_SWIZZLE_UNUSED: fprintf(f, "_"); break;
118 }
119 }
120 }
121
122 static void rc_print_src_register(FILE * f, struct rc_src_register src)
123 {
124 int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);
125
126 if (src.Negate == RC_MASK_XYZW)
127 fprintf(f, "-");
128 if (src.Abs)
129 fprintf(f, "|");
130
131 rc_print_register(f, src.File, src.Index, src.RelAddr);
132
133 if (src.Abs && !trivial_negate)
134 fprintf(f, "|");
135
136 if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {
137 fprintf(f, ".");
138 rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);
139 }
140
141 if (src.Abs && trivial_negate)
142 fprintf(f, "|");
143 }
144
145 static void rc_print_instruction(FILE * f, struct rc_instruction * inst)
146 {
147 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
148 unsigned int reg;
149
150 fprintf(f, "%s", opcode->Name);
151
152 switch(inst->U.I.SaturateMode) {
153 case RC_SATURATE_NONE: break;
154 case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;
155 case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;
156 default: fprintf(f, "_BAD_SAT"); break;
157 }
158
159 if (opcode->HasDstReg) {
160 fprintf(f, " ");
161 rc_print_dst_register(f, inst->U.I.DstReg);
162 if (opcode->NumSrcRegs)
163 fprintf(f, ",");
164 }
165
166 for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
167 if (reg > 0)
168 fprintf(f, ",");
169 fprintf(f, " ");
170 rc_print_src_register(f, inst->U.I.SrcReg[reg]);
171 }
172
173 if (opcode->HasTexture) {
174 fprintf(f, ", %s%s[%u]",
175 textarget_to_string(inst->U.I.TexSrcTarget),
176 inst->U.I.TexShadow ? "SHADOW" : "",
177 inst->U.I.TexSrcUnit);
178 }
179
180 fprintf(f, ";");
181
182 if (inst->U.I.WriteALUResult) {
183 fprintf(f, " [aluresult = (");
184 rc_print_comparefunc(f,
185 (inst->U.I.WriteALUResult == RC_ALURESULT_X) ? "x" : "w",
186 inst->U.I.ALUResultCompare, "0");
187 fprintf(f, ")]");
188 }
189
190 fprintf(f, "\n");
191 }
192
193 /**
194 * Print program to stderr, default options.
195 */
196 void rc_print_program(const struct rc_program *prog)
197 {
198 unsigned int linenum = 0;
199 struct rc_instruction *inst;
200
201 fprintf(stderr, "# Radeon Compiler Program\n");
202
203 for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
204 fprintf(stderr, "%3d: ", linenum);
205
206 rc_print_instruction(stderr, inst);
207
208 linenum++;
209 }
210 }