r300/compiler: Introduce control flow instructions and refactor dataflow
[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_register(FILE * f, rc_register_file file, int index, unsigned int reladdr)
42 {
43 if (file == RC_FILE_NONE) {
44 fprintf(f, "none");
45 } else {
46 const char * filename;
47 switch(file) {
48 case RC_FILE_TEMPORARY: filename = "temp"; break;
49 case RC_FILE_INPUT: filename = "input"; break;
50 case RC_FILE_OUTPUT: filename = "output"; break;
51 case RC_FILE_ADDRESS: filename = "addr"; break;
52 case RC_FILE_CONSTANT: filename = "const"; break;
53 default: filename = "BAD FILE"; break;
54 }
55 fprintf(f, "%s[%i%s]", filename, index, reladdr ? " + addr[0]" : "");
56 }
57 }
58
59 static void rc_print_mask(FILE * f, unsigned int mask)
60 {
61 if (mask & RC_MASK_X) fprintf(f, "x");
62 if (mask & RC_MASK_Y) fprintf(f, "y");
63 if (mask & RC_MASK_Z) fprintf(f, "z");
64 if (mask & RC_MASK_W) fprintf(f, "w");
65 }
66
67 static void rc_print_dst_register(FILE * f, struct rc_dst_register dst)
68 {
69 rc_print_register(f, dst.File, dst.Index, dst.RelAddr);
70 if (dst.WriteMask != RC_MASK_XYZW) {
71 fprintf(f, ".");
72 rc_print_mask(f, dst.WriteMask);
73 }
74 }
75
76 static void rc_print_swizzle(FILE * f, unsigned int swizzle, unsigned int negate)
77 {
78 unsigned int comp;
79 for(comp = 0; comp < 4; ++comp) {
80 rc_swizzle swz = GET_SWZ(swizzle, comp);
81 if (GET_BIT(negate, comp))
82 fprintf(f, "-");
83 switch(swz) {
84 case RC_SWIZZLE_X: fprintf(f, "x"); break;
85 case RC_SWIZZLE_Y: fprintf(f, "y"); break;
86 case RC_SWIZZLE_Z: fprintf(f, "z"); break;
87 case RC_SWIZZLE_W: fprintf(f, "w"); break;
88 case RC_SWIZZLE_ZERO: fprintf(f, "0"); break;
89 case RC_SWIZZLE_ONE: fprintf(f, "1"); break;
90 case RC_SWIZZLE_HALF: fprintf(f, "H"); break;
91 case RC_SWIZZLE_UNUSED: fprintf(f, "_"); break;
92 }
93 }
94 }
95
96 static void rc_print_src_register(FILE * f, struct rc_src_register src)
97 {
98 int trivial_negate = (src.Negate == RC_MASK_NONE || src.Negate == RC_MASK_XYZW);
99
100 if (src.Negate == RC_MASK_XYZW)
101 fprintf(f, "-");
102 if (src.Abs)
103 fprintf(f, "|");
104
105 rc_print_register(f, src.File, src.Index, src.RelAddr);
106
107 if (src.Abs && !trivial_negate)
108 fprintf(f, "|");
109
110 if (src.Swizzle != RC_SWIZZLE_XYZW || !trivial_negate) {
111 fprintf(f, ".");
112 rc_print_swizzle(f, src.Swizzle, trivial_negate ? 0 : src.Negate);
113 }
114
115 if (src.Abs && trivial_negate)
116 fprintf(f, "|");
117 }
118
119 static void rc_print_instruction(FILE * f, struct rc_instruction * inst)
120 {
121 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->I.Opcode);
122 unsigned int reg;
123
124 fprintf(f, "%s", opcode->Name);
125
126 switch(inst->I.SaturateMode) {
127 case RC_SATURATE_NONE: break;
128 case RC_SATURATE_ZERO_ONE: fprintf(f, "_SAT"); break;
129 case RC_SATURATE_MINUS_PLUS_ONE: fprintf(f, "_SAT2"); break;
130 default: fprintf(f, "_BAD_SAT"); break;
131 }
132
133 if (opcode->HasDstReg) {
134 fprintf(f, " ");
135 rc_print_dst_register(f, inst->I.DstReg);
136 if (opcode->NumSrcRegs)
137 fprintf(f, ",");
138 }
139
140 for(reg = 0; reg < opcode->NumSrcRegs; ++reg) {
141 if (reg > 0)
142 fprintf(f, ",");
143 fprintf(f, " ");
144 rc_print_src_register(f, inst->I.SrcReg[reg]);
145 }
146
147 if (opcode->HasTexture) {
148 fprintf(f, ", %s%s[%u]",
149 textarget_to_string(inst->I.TexSrcTarget),
150 inst->I.TexShadow ? "SHADOW" : "",
151 inst->I.TexSrcUnit);
152 }
153
154 fprintf(f, ";\n");
155 }
156
157 /**
158 * Print program to stderr, default options.
159 */
160 void rc_print_program(const struct rc_program *prog)
161 {
162 unsigned int linenum = 0;
163 struct rc_instruction *inst;
164
165 fprintf(stderr, "# Radeon Compiler Program\n");
166
167 for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
168 fprintf(stderr, "%3d: ", linenum);
169
170 rc_print_instruction(stderr, inst);
171
172 linenum++;
173 }
174 }