2 * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
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:
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
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. */
23 #include "radeon_program.h"
27 static void print_comment(FILE * f
)
32 static const char * textarget_to_string(rc_texture_target 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";
46 static void rc_print_register(FILE * f
, rc_register_file file
, int index
, unsigned int reladdr
)
48 if (file
== RC_FILE_NONE
) {
51 const char * filename
;
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;
60 fprintf(f
, "%s[%i%s]", filename
, index
, reladdr
? " + addr[0]" : "");
64 static void rc_print_mask(FILE * f
, unsigned int mask
)
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");
72 static void rc_print_dst_register(FILE * f
, struct rc_dst_register dst
)
74 rc_print_register(f
, dst
.File
, dst
.Index
, dst
.RelAddr
);
75 if (dst
.WriteMask
!= RC_MASK_XYZW
) {
77 rc_print_mask(f
, dst
.WriteMask
);
81 static void rc_print_swizzle(FILE * f
, unsigned int swizzle
, unsigned int negate
)
84 for(comp
= 0; comp
< 4; ++comp
) {
85 rc_swizzle swz
= GET_SWZ(swizzle
, comp
);
86 if (GET_BIT(negate
, comp
))
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;
101 static void rc_print_src_register(FILE * f
, struct rc_src_register src
)
103 int trivial_negate
= (src
.Negate
== RC_MASK_NONE
|| src
.Negate
== RC_MASK_XYZW
);
105 if (src
.Negate
== RC_MASK_XYZW
)
110 rc_print_register(f
, src
.File
, src
.Index
, src
.RelAddr
);
112 if (src
.Abs
&& !trivial_negate
)
115 if (src
.Swizzle
!= RC_SWIZZLE_XYZW
|| !trivial_negate
) {
117 rc_print_swizzle(f
, src
.Swizzle
, trivial_negate
? 0 : src
.Negate
);
120 if (src
.Abs
&& trivial_negate
)
124 static void rc_print_ref(FILE * f
, struct rc_dataflow_ref
* ref
)
126 fprintf(f
, "ref(%p", ref
->Vector
);
128 if (ref
->UseMask
!= RC_MASK_XYZW
) {
130 rc_print_mask(f
, ref
->UseMask
);
136 static void rc_print_instruction(FILE * f
, unsigned int flags
, struct rc_instruction
* inst
)
138 const struct rc_opcode_info
* opcode
= rc_get_opcode_info(inst
->I
.Opcode
);
141 fprintf(f
, "%s", opcode
->Name
);
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;
150 if (opcode
->HasDstReg
) {
152 rc_print_dst_register(f
, inst
->I
.DstReg
);
153 if (opcode
->NumSrcRegs
)
157 for(reg
= 0; reg
< opcode
->NumSrcRegs
; ++reg
) {
161 rc_print_src_register(f
, inst
->I
.SrcReg
[reg
]);
164 if (opcode
->HasTexture
) {
165 fprintf(f
, ", %s%s[%u]",
166 textarget_to_string(inst
->I
.TexSrcTarget
),
167 inst
->I
.TexShadow
? "SHADOW" : "",
173 if (flags
& RC_PRINT_DATAFLOW
) {
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
);
184 for(reg
= 0; reg
< opcode
->NumSrcRegs
; ++reg
) {
186 if (inst
->Dataflow
.SrcReg
[reg
])
187 rc_print_ref(f
, inst
->Dataflow
.SrcReg
[reg
]);
189 fprintf(f
, "<no ref>");
197 * Print program to stderr, default options.
199 void rc_print_program(const struct rc_program
*prog
, unsigned int flags
)
201 unsigned int linenum
= 0;
202 struct rc_instruction
*inst
;
204 fprintf(stderr
, "# Radeon Compiler Program%s\n",
205 flags
& RC_PRINT_DATAFLOW
? " (with dataflow annotations)" : "");
207 for(inst
= prog
->Instructions
.Next
; inst
!= &prog
->Instructions
; inst
= inst
->Next
) {
208 fprintf(stderr
, "%3d: ", linenum
);
210 rc_print_instruction(stderr
, flags
, inst
);