• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_compiler.h"
24 #include "radeon_code.h"
25 #include "r300_reg.h"
26 
27 #include <stdio.h>
28 
29 static char* r300_vs_ve_ops[] = {
30 	/* R300 vector ops */
31 	"                 VE_NO_OP",
32 	"           VE_DOT_PRODUCT",
33 	"              VE_MULTIPLY",
34 	"                   VE_ADD",
35 	"          VE_MULTIPLY_ADD",
36 	"       VE_DISTANCE_FACTOR",
37 	"              VE_FRACTION",
38 	"               VE_MAXIMUM",
39 	"               VE_MINIMUM",
40 	"VE_SET_GREATER_THAN_EQUAL",
41 	"         VE_SET_LESS_THAN",
42 	"        VE_MULTIPLYX2_ADD",
43 	"        VE_MULTIPLY_CLAMP",
44 	"            VE_FLT2FIX_DX",
45 	"        VE_FLT2FIX_DX_RND",
46 	/* R500 vector ops */
47 	"      VE_PRED_SET_EQ_PUSH",
48 	"      VE_PRED_SET_GT_PUSH",
49 	"     VE_PRED_SET_GTE_PUSH",
50 	"     VE_PRED_SET_NEQ_PUSH",
51 	"         VE_COND_WRITE_EQ",
52 	"         VE_COND_WRITE_GT",
53 	"        VE_COND_WRITE_GTE",
54 	"        VE_COND_WRITE_NEQ",
55 	"           VE_COND_MUX_EQ",
56 	"           VE_COND_MUX_GT",
57 	"          VE_COND_MUX_GTE",
58 	"      VE_SET_GREATER_THAN",
59 	"             VE_SET_EQUAL",
60 	"         VE_SET_NOT_EQUAL",
61 	"               (reserved)",
62 	"               (reserved)",
63 	"               (reserved)",
64 };
65 
66 static char* r300_vs_me_ops[] = {
67 	/* R300 math ops */
68 	"                 ME_NO_OP",
69 	"          ME_EXP_BASE2_DX",
70 	"          ME_LOG_BASE2_DX",
71 	"          ME_EXP_BASEE_FF",
72 	"        ME_LIGHT_COEFF_DX",
73 	"         ME_POWER_FUNC_FF",
74 	"              ME_RECIP_DX",
75 	"              ME_RECIP_FF",
76 	"         ME_RECIP_SQRT_DX",
77 	"         ME_RECIP_SQRT_FF",
78 	"              ME_MULTIPLY",
79 	"     ME_EXP_BASE2_FULL_DX",
80 	"     ME_LOG_BASE2_FULL_DX",
81 	" ME_POWER_FUNC_FF_CLAMP_B",
82 	"ME_POWER_FUNC_FF_CLAMP_B1",
83 	"ME_POWER_FUNC_FF_CLAMP_01",
84 	"                   ME_SIN",
85 	"                   ME_COS",
86 	/* R500 math ops */
87 	"        ME_LOG_BASE2_IEEE",
88 	"            ME_RECIP_IEEE",
89 	"       ME_RECIP_SQRT_IEEE",
90 	"           ME_PRED_SET_EQ",
91 	"           ME_PRED_SET_GT",
92 	"          ME_PRED_SET_GTE",
93 	"          ME_PRED_SET_NEQ",
94 	"          ME_PRED_SET_CLR",
95 	"          ME_PRED_SET_INV",
96 	"          ME_PRED_SET_POP",
97 	"      ME_PRED_SET_RESTORE",
98 	"               (reserved)",
99 	"               (reserved)",
100 	"               (reserved)",
101 };
102 
103 /* XXX refactor to avoid clashing symbols */
104 static char* r300_vs_src_debug[] = {
105 	"t",
106 	"i",
107 	"c",
108 	"a",
109 };
110 
111 static char* r300_vs_dst_debug[] = {
112 	"t",
113 	"a0",
114 	"o",
115 	"ox",
116 	"a",
117 	"i",
118 	"u",
119 	"u",
120 };
121 
122 static char* r300_vs_swiz_debug[] = {
123 	"X",
124 	"Y",
125 	"Z",
126 	"W",
127 	"0",
128 	"1",
129 	"U",
130 	"U",
131 };
132 
133 
r300_vs_op_dump(uint32_t op)134 static void r300_vs_op_dump(uint32_t op)
135 {
136 	fprintf(stderr, " dst: %d%s op: ",
137 			(op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
138 	if ((op >> PVS_DST_PRED_ENABLE_SHIFT) & 0x1) {
139 		fprintf(stderr, "PRED %u",
140 				(op >> PVS_DST_PRED_SENSE_SHIFT) & 0x1);
141 	}
142 	if (op & 0x80) {
143 		if (op & 0x1) {
144 			fprintf(stderr, "PVS_MACRO_OP_2CLK_M2X_ADD\n");
145 		} else {
146 			fprintf(stderr, "   PVS_MACRO_OP_2CLK_MADD\n");
147 		}
148 	} else if (op & 0x40) {
149 		fprintf(stderr, "%s\n", r300_vs_me_ops[op & 0x1f]);
150 	} else {
151 		fprintf(stderr, "%s\n", r300_vs_ve_ops[op & 0x1f]);
152 	}
153 }
154 
r300_vs_src_dump(uint32_t src)155 static void r300_vs_src_dump(uint32_t src)
156 {
157 	fprintf(stderr, " reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
158 			(src >> 5) & 0xff, r300_vs_src_debug[src & 0x3],
159 			src & (1 << 25) ? "-" : " ",
160 			r300_vs_swiz_debug[(src >> 13) & 0x7],
161 			src & (1 << 26) ? "-" : " ",
162 			r300_vs_swiz_debug[(src >> 16) & 0x7],
163 			src & (1 << 27) ? "-" : " ",
164 			r300_vs_swiz_debug[(src >> 19) & 0x7],
165 			src & (1 << 28) ? "-" : " ",
166 			r300_vs_swiz_debug[(src >> 22) & 0x7]);
167 }
168 
r300_vertex_program_dump(struct radeon_compiler * compiler,void * user)169 void r300_vertex_program_dump(struct radeon_compiler *compiler, void *user)
170 {
171 	struct r300_vertex_program_compiler *c = (struct r300_vertex_program_compiler*)compiler;
172 	struct r300_vertex_program_code * vs = c->code;
173 	unsigned instrcount = vs->length / 4;
174 	unsigned i;
175 
176 	fprintf(stderr, "Final vertex program code:\n");
177 
178 	for(i = 0; i < instrcount; i++) {
179 		unsigned offset = i*4;
180 		unsigned src;
181 
182 		fprintf(stderr, "%d: op: 0x%08x", i, vs->body.d[offset]);
183 		r300_vs_op_dump(vs->body.d[offset]);
184 
185 		for(src = 0; src < 3; ++src) {
186 			fprintf(stderr, " src%i: 0x%08x", src, vs->body.d[offset+1+src]);
187 			r300_vs_src_dump(vs->body.d[offset+1+src]);
188 		}
189 	}
190 
191 	fprintf(stderr, "Flow Control Ops: 0x%08x\n",vs->fc_ops);
192 	for(i = 0; i < vs->num_fc_ops; i++) {
193 		unsigned is_loop = 0;
194 		switch((vs->fc_ops >> (i * 2)) & 0x3 ) {
195 		case 0: fprintf(stderr, "NOP"); break;
196 		case 1: fprintf(stderr, "JUMP"); break;
197 		case 2: fprintf(stderr, "LOOP"); is_loop = 1; break;
198 		case 3: fprintf(stderr, "JSR"); break;
199 		}
200 		if (c->Base.is_r500) {
201 			fprintf(stderr,": uw-> 0x%08x lw-> 0x%08x "
202 							"loop data->0x%08x\n",
203 				vs->fc_op_addrs.r500[i].uw,
204 				vs->fc_op_addrs.r500[i].lw,
205 				vs->fc_loop_index[i]);
206 			if (is_loop) {
207 				fprintf(stderr, "Before = %u First = %u Last = %u\n",
208 					vs->fc_op_addrs.r500[i].lw & 0xffff,
209 					(vs->fc_op_addrs.r500[i].uw >> 16) & 0xffff,
210 					vs->fc_op_addrs.r500[i].uw  & 0xffff);
211 			}
212 		} else {
213 			fprintf(stderr,": 0x%08x\n", vs->fc_op_addrs.r300[i]);
214 		}
215 	}
216 }
217