nv50: introduce the big formats table
[mesa.git] / src / gallium / drivers / nv50 / nv50_pc.h
1 /*************************************************************************/
2 /* Copyright (C) 2010 I */
3 /* */
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 /* */
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 /* */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 /*************************************************************************/
17
18 #ifndef __NV50_COMPILER_H__
19 #define __NV50_COMPILER_H__
20
21 #include "pipe/p_defines.h"
22 #include "util/u_inlines.h"
23 #include "util/u_memory.h"
24
25 #define NV_OP_PHI 0
26 #define NV_OP_EXTRACT 1
27 #define NV_OP_COMBINE 2
28 #define NV_OP_LDA 3
29 #define NV_OP_STA 4
30 #define NV_OP_MOV 5
31 #define NV_OP_ADD 6
32 #define NV_OP_SUB 7
33 #define NV_OP_NEG 8
34 #define NV_OP_MUL 9
35 #define NV_OP_MAD 10
36 #define NV_OP_CVT 11
37 #define NV_OP_SAT 12
38 #define NV_OP_NOT 13
39 #define NV_OP_AND 14
40 #define NV_OP_OR 15
41 #define NV_OP_XOR 16
42 #define NV_OP_SHL 17
43 #define NV_OP_SHR 18
44 #define NV_OP_RCP 19
45 /* gap */
46 #define NV_OP_RSQ 21
47 #define NV_OP_LG2 22
48 #define NV_OP_SIN 23
49 #define NV_OP_COS 24
50 #define NV_OP_EX2 25
51 #define NV_OP_PRESIN 26
52 #define NV_OP_PREEX2 27
53 #define NV_OP_MIN 28
54 #define NV_OP_MAX 29
55 #define NV_OP_SET 30
56 #define NV_OP_SAD 31
57 #define NV_OP_KIL 32
58 #define NV_OP_BRA 33
59 #define NV_OP_CALL 34
60 #define NV_OP_RET 35
61 #define NV_OP_BREAK 36
62 #define NV_OP_BREAKADDR 37
63 #define NV_OP_JOINAT 38
64 #define NV_OP_TEX 39
65 #define NV_OP_TXB 40
66 #define NV_OP_TXL 41
67 #define NV_OP_TXF 42
68 #define NV_OP_TXQ 43
69 #define NV_OP_DFDX 44
70 #define NV_OP_DFDY 45
71 #define NV_OP_QUADOP 46
72 #define NV_OP_LINTERP 47
73 #define NV_OP_PINTERP 48
74 #define NV_OP_ABS 49
75 #define NV_OP_CEIL 50
76 #define NV_OP_FLOOR 51
77 #define NV_OP_TRUNC 52
78 #define NV_OP_NOP 53
79 #define NV_OP_SELECT 54
80 #define NV_OP_EXPORT 55
81 #define NV_OP_COUNT 56
82
83 #define NV_FILE_GPR 0
84 #define NV_FILE_OUT 1
85 #define NV_FILE_ADDR 2
86 #define NV_FILE_FLAGS 3
87 #define NV_FILE_IMM 16
88 #define NV_FILE_MEM_S 32
89 #define NV_FILE_MEM_P 33
90 #define NV_FILE_MEM_V 34
91 #define NV_FILE_MEM_L 48
92 #define NV_FILE_MEM_G(i) (64 + i)
93 #define NV_FILE_MEM_C(i) (80 + i)
94
95 #define NV_MOD_NEG 1
96 #define NV_MOD_ABS 2
97 #define NV_MOD_NOT 4
98 #define NV_MOD_SAT 8
99
100 #define NV_TYPE_U8 0x00
101 #define NV_TYPE_S8 0x01
102 #define NV_TYPE_U16 0x02
103 #define NV_TYPE_S16 0x03
104 #define NV_TYPE_U32 0x04
105 #define NV_TYPE_S32 0x05
106 #define NV_TYPE_P32 0x07
107 #define NV_TYPE_F32 0x09
108 #define NV_TYPE_F64 0x0b
109 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
110 #define NV_TYPE_LO 0x00
111 #define NV_TYPE_HI 0x80
112 #define NV_TYPE_ANY 0xff
113
114 #define NV_TYPE_ISINT(t) ((t) <= 5)
115 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
116
117 #define NV_CC_FL 0x0
118 #define NV_CC_LT 0x1
119 #define NV_CC_EQ 0x2
120 #define NV_CC_LE 0x3
121 #define NV_CC_GT 0x4
122 #define NV_CC_NE 0x5
123 #define NV_CC_GE 0x6
124 #define NV_CC_U 0x8
125 #define NV_CC_TR 0xf
126
127 #define NV_PC_MAX_INSTRUCTIONS 2048
128 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
129
130 static INLINE boolean
131 nv_is_vector_op(uint opcode)
132 {
133 return (opcode >= NV_OP_TEX) && (opcode <= NV_OP_TXQ);
134 }
135
136 static INLINE uint
137 nv_type_order(ubyte type)
138 {
139 switch (type & 0xf) {
140 case NV_TYPE_U8:
141 case NV_TYPE_S8:
142 return 0;
143 case NV_TYPE_U16:
144 case NV_TYPE_S16:
145 return 1;
146 case NV_TYPE_U32:
147 case NV_TYPE_F32:
148 case NV_TYPE_S32:
149 case NV_TYPE_P32:
150 return 2;
151 case NV_TYPE_F64:
152 return 3;
153 }
154 assert(0);
155 }
156
157 static INLINE uint
158 nv_type_sizeof(ubyte type)
159 {
160 if (type & 0xf0)
161 return (1 << nv_type_order(type)) * (type >> 4);
162 return 1 << nv_type_order(type);
163 }
164
165 static INLINE uint
166 nv_type_sizeof_base(ubyte type)
167 {
168 return 1 << nv_type_order(type);
169 }
170
171 struct nv_reg {
172 int id;
173 ubyte file;
174 ubyte type; /* type of generating instruction's result */
175 union {
176 float f32;
177 double f64;
178 int32_t s32;
179 uint32_t u32;
180 } imm;
181 };
182
183 struct nv_range {
184 struct nv_range *next;
185 int bgn;
186 int end;
187 };
188
189 struct nv_value {
190 struct nv_reg reg;
191 struct nv_instruction *insn;
192 struct nv_value *join;
193 int n;
194 struct nv_range *livei;
195 int refc;
196
197 struct nv_value *next;
198 struct nv_value *prev;
199 };
200
201 struct nv_ref {
202 struct nv_value *value;
203 struct nv_instruction *insn;
204 ubyte mod;
205 ubyte typecast;
206 ubyte flags; /* not used yet */
207 };
208
209 struct nv_basic_block;
210
211 struct nv_instruction {
212 struct nv_instruction *next;
213 struct nv_instruction *prev;
214 uint opcode;
215 int serial;
216 struct nv_value *def[4];
217 struct nv_value *flags_def;
218 struct nv_ref *src[5];
219 struct nv_ref *flags_src;
220 struct nv_basic_block *bb;
221 struct nv_basic_block *target; /* target block of control flow insn */
222 ubyte cc;
223 ubyte set_cond : 4;
224 ubyte fixed : 1; /* don't optimize away */
225 ubyte is_terminator : 1;
226 ubyte is_join : 1;
227 ubyte is_long : 1; /* for emission */
228 /* */
229 ubyte saturate : 1;
230 ubyte centroid : 1;
231 ubyte flat : 1;
232 ubyte padding : 4;
233 ubyte tex_live : 1;
234 /* */
235 ubyte tex_t; /* TIC binding */
236 ubyte tex_s; /* TSC binding */
237 ubyte tex_argc : 3;
238 ubyte tex_cube : 1;
239 ubyte tex_mask : 4;
240 /* */
241 ubyte quadop;
242 };
243
244 struct nv_basic_block {
245 struct nv_instruction *entry; /* first non-phi instruction */
246 struct nv_instruction *exit;
247 struct nv_instruction *phi; /* very first instruction */
248 int num_instructions;
249
250 struct nv_basic_block *out[2]; /* no indirect branches -> 2 */
251 struct nv_basic_block **in;
252 uint num_in;
253
254 int id;
255 struct nv_basic_block *last_visitor;
256 uint priv;
257 uint pass_seq;
258
259 uint32_t bin_pos; /* position, size in emitted code */
260 uint32_t bin_size;
261
262 uint32_t live_set[NV_PC_MAX_VALUES / 32];
263 };
264
265 #define NV_FIXUP_CFLOW_RELOC 0
266 #define NV_FIXUP_PARAM_RELOC 1
267
268 struct nv_fixup {
269 ubyte type;
270 ubyte shift;
271 uint32_t mask;
272 uint32_t data;
273 uint32_t offset;
274 };
275
276 static INLINE void
277 nv_fixup_apply(uint32_t *bin, struct nv_fixup *fixup, uint32_t data)
278 {
279 uint32_t val;
280
281 val = bin[fixup->offset / 4] & ~fixup->mask;
282 data = (fixup->shift < 0) ? (data >> fixup->shift) : (data << fixup->shift);
283 val |= (fixup->data + data) & fixup->mask;
284 bin[fixup->offset / 4] = val;
285 }
286
287 struct nv_pc {
288 struct nv50_translation_info *ti;
289
290 struct nv_basic_block *root;
291 struct nv_basic_block *current_block;
292 struct nv_basic_block *parent_block;
293
294 int loop_nesting_bound;
295 uint pass_seq;
296
297 struct nv_value values[NV_PC_MAX_VALUES];
298 struct nv_instruction instructions[NV_PC_MAX_INSTRUCTIONS];
299 struct nv_ref **refs;
300 struct nv_basic_block **bb_list;
301 int num_values;
302 int num_instructions;
303 int num_refs;
304 int num_blocks;
305
306 int max_reg[4];
307
308 uint32_t *immd_buf; /* populated on emit */
309 unsigned immd_count;
310
311 uint32_t *emit;
312 unsigned bin_size;
313 unsigned bin_pos;
314
315 struct nv_fixup *fixups;
316 int num_fixups;
317 };
318
319 void nvbb_insert_tail(struct nv_basic_block *, struct nv_instruction *);
320
321 static INLINE struct nv_instruction *
322 new_instruction(struct nv_pc *pc, uint opcode)
323 {
324 struct nv_instruction *insn;
325
326 insn = &pc->instructions[pc->num_instructions++];
327 assert(pc->num_instructions < NV_PC_MAX_INSTRUCTIONS);
328
329 insn->cc = NV_CC_TR;
330 insn->opcode = opcode;
331
332 nvbb_insert_tail(pc->current_block, insn);
333 return insn;
334 }
335
336 static INLINE struct nv_value *
337 new_value(struct nv_pc *pc, ubyte file, ubyte type)
338 {
339 struct nv_value *value = &pc->values[pc->num_values];
340
341 assert(pc->num_values < NV_PC_MAX_VALUES - 1);
342
343 value->n = pc->num_values++;
344 value->join = value;
345 value->reg.id = -1;
346 value->reg.file = file;
347 value->reg.type = type;
348 return value;
349 }
350
351 static INLINE struct nv_ref *
352 new_ref(struct nv_pc *pc, struct nv_value *val)
353 {
354 int i;
355 struct nv_ref *ref;
356
357 if ((pc->num_refs % 64) == 0) {
358 const unsigned old_size = pc->num_refs * sizeof(struct nv_ref *);
359 const unsigned new_size = (pc->num_refs + 64) * sizeof(struct nv_ref *);
360
361 pc->refs = REALLOC(pc->refs, old_size, new_size);
362
363 ref = CALLOC(64, sizeof(struct nv_ref));
364 for (i = 0; i < 64; ++i)
365 pc->refs[pc->num_refs + i] = &ref[i];
366 }
367
368 ref = pc->refs[pc->num_refs++];
369 ref->value = val;
370 ref->typecast = val->reg.type;
371
372 ++val->refc;
373 return ref;
374 }
375
376 static INLINE struct nv_basic_block *
377 new_basic_block(struct nv_pc *pc)
378 {
379 struct nv_basic_block *bb = CALLOC_STRUCT(nv_basic_block);
380
381 bb->in = CALLOC(sizeof(struct nv_basic_block *), 4);
382 bb->id = pc->num_blocks++;
383 return bb;
384 }
385
386 static INLINE void
387 nv_reference(struct nv_pc *pc, struct nv_ref **d, struct nv_value *s)
388 {
389 if (*d)
390 --(*d)->value->refc;
391
392 if (s) {
393 if (!*d)
394 *d = new_ref(pc, s);
395 else {
396 (*d)->value = s;
397 ++(s->refc);
398 }
399 } else {
400 assert(*d);
401 *d = NULL;
402 }
403 }
404
405 /* nv50_emit.c */
406 void nv50_emit_instruction(struct nv_pc *, struct nv_instruction *);
407
408 /* nv50_print.c */
409 const char *nv_opcode_name(uint opcode);
410 void nv_print_instruction(struct nv_instruction *);
411
412 /* nv50_pc.c */
413 void nv_print_program(struct nv_basic_block *b);
414
415 boolean nv_op_commutative(uint opcode);
416 int nv50_indirect_opnd(struct nv_instruction *);
417 boolean nv50_nvi_can_use_imm(struct nv_instruction *, int s);
418 boolean nv50_nvi_can_load(struct nv_instruction *, int s, struct nv_value *);
419 ubyte nv50_supported_src_mods(uint opcode, int s);
420 int nv_nvi_refcount(struct nv_instruction *);
421 void nv_nvi_delete(struct nv_instruction *);
422 void nv_nvi_permute(struct nv_instruction *, struct nv_instruction *);
423 void nvbb_attach_block(struct nv_basic_block *parent, struct nv_basic_block *);
424
425 int nv_pc_exec_pass0(struct nv_pc *pc);
426 int nv_pc_exec_pass1(struct nv_pc *pc);
427 int nv_pc_exec_pass2(struct nv_pc *pc);
428
429 int nv50_tgsi_to_nc(struct nv_pc *, struct nv50_translation_info *);
430
431 #endif // NV50_COMPILER_H