1 /*
2  * Copyright (C) 2008 Nicolai Haehnle.
3  *
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  */
27 
28 #ifndef __RADEON_PROGRAM_H_
29 #define __RADEON_PROGRAM_H_
30 
31 #include <stdint.h>
32 #include <string.h>
33 
34 #include "radeon_opcodes.h"
35 #include "radeon_code.h"
36 #include "radeon_program_constants.h"
37 #include "radeon_program_pair.h"
38 
39 struct radeon_compiler;
40 
41 struct rc_src_register {
42 	unsigned int File:4;
43 
44 	/** Negative values may be used for relative addressing. */
45 	signed int Index:(RC_REGISTER_INDEX_BITS+1);
46 	unsigned int RelAddr:1;
47 
48 	unsigned int Swizzle:12;
49 
50 	/** Take the component-wise absolute value */
51 	unsigned int Abs:1;
52 
53 	/** Post-Abs negation. */
54 	unsigned int Negate:4;
55 };
56 
57 struct rc_dst_register {
58 	unsigned int File:3;
59 	unsigned int Index:RC_REGISTER_INDEX_BITS;
60 	unsigned int WriteMask:4;
61 	unsigned int Pred:2;
62 };
63 
64 struct rc_presub_instruction {
65 	rc_presubtract_op Opcode;
66 	struct rc_src_register SrcReg[2];
67 };
68 
69 /**
70  * Instructions are maintained by the compiler in a doubly linked list
71  * of these structures.
72  *
73  * This instruction format is intended to be expanded for hardware-specific
74  * trickery. At different stages of compilation, a different set of
75  * instruction types may be valid.
76  */
77 struct rc_sub_instruction {
78 	struct rc_src_register SrcReg[3];
79 	struct rc_dst_register DstReg;
80 
81 	/**
82 	 * Opcode of this instruction, according to \ref rc_opcode enums.
83 	 */
84 	unsigned int Opcode:8;
85 
86 	/**
87 	 * Saturate each value of the result to the range [0,1] or [-1,1],
88 	 * according to \ref rc_saturate_mode enums.
89 	 */
90 	unsigned int SaturateMode:2;
91 
92 	/**
93 	 * Writing to the special register RC_SPECIAL_ALU_RESULT
94 	 */
95 	/*@{*/
96 	unsigned int WriteALUResult:2;
97 	unsigned int ALUResultCompare:3;
98 	/*@}*/
99 
100 	/**
101 	 * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
102 	 */
103 	/*@{*/
104 	/** Source texture unit. */
105 	unsigned int TexSrcUnit:5;
106 
107 	/** Source texture target, one of the \ref rc_texture_target enums */
108 	unsigned int TexSrcTarget:3;
109 
110 	/** True if tex instruction should do shadow comparison */
111 	unsigned int TexShadow:1;
112 
113 	/**/
114 	unsigned int TexSemWait:1;
115 	unsigned int TexSemAcquire:1;
116 
117 	/**R500 Only.  How to swizzle the result of a TEX lookup*/
118 	unsigned int TexSwizzle:12;
119 	/*@}*/
120 
121 	/** This holds information about the presubtract operation used by
122 	 * this instruction. */
123 	struct rc_presub_instruction PreSub;
124 
125 	rc_omod_op Omod;
126 };
127 
128 typedef enum {
129 	RC_INSTRUCTION_NORMAL = 0,
130 	RC_INSTRUCTION_PAIR
131 } rc_instruction_type;
132 
133 struct rc_instruction {
134 	struct rc_instruction * Prev;
135 	struct rc_instruction * Next;
136 
137 	rc_instruction_type Type;
138 	union {
139 		struct rc_sub_instruction I;
140 		struct rc_pair_instruction P;
141 	} U;
142 
143 	/**
144 	 * Warning: IPs are not stable. If you want to use them,
145 	 * you need to recompute them at the beginning of each pass
146 	 * using \ref rc_recompute_ips
147 	 */
148 	unsigned int IP;
149 };
150 
151 struct rc_program {
152 	/**
153 	 * Instructions.Next points to the first instruction,
154 	 * Instructions.Prev points to the last instruction.
155 	 */
156 	struct rc_instruction Instructions;
157 
158 	/* Long term, we should probably remove InputsRead & OutputsWritten,
159 	 * since updating dependent state can be fragile, and they aren't
160 	 * actually used very often. */
161 	uint32_t InputsRead;
162 	uint32_t OutputsWritten;
163 	uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */
164 
165 	struct rc_constant_list Constants;
166 };
167 
168 /**
169  * A transformation that can be passed to \ref rc_local_transform.
170  *
171  * The function will be called once for each instruction.
172  * It has to either emit the appropriate transformed code for the instruction
173  * and return true, or return false if it doesn't understand the
174  * instruction.
175  *
176  * The function gets passed the userData as last parameter.
177  */
178 struct radeon_program_transformation {
179 	int (*function)(
180 		struct radeon_compiler*,
181 		struct rc_instruction*,
182 		void*);
183 	void *userData;
184 };
185 
186 void rc_local_transform(
187 	struct radeon_compiler *c,
188 	void *user);
189 
190 void rc_get_used_temporaries(
191 	struct radeon_compiler * c,
192 	unsigned char * used,
193 	unsigned int used_length);
194 
195 int rc_find_free_temporary_list(
196 	struct radeon_compiler * c,
197 	unsigned char * used,
198 	unsigned int used_length,
199 	unsigned int mask);
200 
201 unsigned int rc_find_free_temporary(struct radeon_compiler * c);
202 
203 struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
204 struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
205 void rc_insert_instruction(struct rc_instruction * after, struct rc_instruction * inst);
206 void rc_remove_instruction(struct rc_instruction * inst);
207 
208 unsigned int rc_recompute_ips(struct radeon_compiler * c);
209 
210 void rc_print_program(const struct rc_program *prog);
211 
212 rc_swizzle rc_mask_to_swizzle(unsigned int mask);
213 #endif
214