2 * Copyright 2010 Christoph Bumiller
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #ifndef __NVC0_COMPILER_H__
24 #define __NVC0_COMPILER_H__
30 # define NOUVEAU_DBG(args...) debug_printf(args);
32 # define NOUVEAU_DBG(args...)
37 #define NOUVEAU_ERR(fmt, args...) \
38 fprintf(stderr, "%s:%d - "fmt, __FUNCTION__, __LINE__, ##args);
41 #include "pipe/p_defines.h"
42 #include "util/u_inlines.h"
43 #include "util/u_memory.h"
44 #include "util/u_double_list.h"
51 #define NV_OP_SELECT 4
55 * BIND forces source operand i into the same register as destination operand i,
56 * and the operands will be assigned consecutive registers (needed for TEX).
58 * SELECT forces its multiple source operands and its destination operand into
59 * one and the same register.
83 #define NV_OP_FLOOR 26
84 #define NV_OP_TRUNC 27
88 #define NV_OP_VFETCH 29
89 #define NV_OP_PFETCH 30
90 #define NV_OP_EXPORT 31
91 #define NV_OP_LINTERP 32
92 #define NV_OP_PINTERP 33
94 #define NV_OP_RESTART 35
100 #define NV_OP_QUADOP 41
101 #define NV_OP_DFDX 42
102 #define NV_OP_DFDY 43
105 /* control flow opcodes */
107 #define NV_OP_CALL 46
109 #define NV_OP_EXIT 48
110 #define NV_OP_BREAK 49
111 #define NV_OP_BREAKADDR 50
112 #define NV_OP_JOINAT 51
113 #define NV_OP_JOIN 52
116 #define NV_OP_ADD_F32 NV_OP_ADD
117 #define NV_OP_ADD_B32 53
118 #define NV_OP_MUL_F32 NV_OP_MUL
119 #define NV_OP_MUL_B32 54
120 #define NV_OP_ABS_F32 NV_OP_ABS
121 #define NV_OP_ABS_S32 55
122 #define NV_OP_NEG_F32 NV_OP_NEG
123 #define NV_OP_NEG_S32 56
124 #define NV_OP_MAX_F32 NV_OP_MAX
125 #define NV_OP_MAX_S32 57
126 #define NV_OP_MAX_U32 58
127 #define NV_OP_MIN_F32 NV_OP_MIN
128 #define NV_OP_MIN_S32 59
129 #define NV_OP_MIN_U32 60
130 #define NV_OP_SET_F32 61
131 #define NV_OP_SET_S32 62
132 #define NV_OP_SET_U32 63
140 #define NV_OP_PRESIN 71
141 #define NV_OP_PREEX2 72
144 /* newly added opcodes */
145 #define NV_OP_SET_F32_AND 74
146 #define NV_OP_SET_F32_OR 75
147 #define NV_OP_SET_F32_XOR 76
148 #define NV_OP_SELP 77
149 #define NV_OP_SLCT 78
150 #define NV_OP_SLCT_F32 NV_OP_SLCT
151 #define NV_OP_SLCT_S32 79
152 #define NV_OP_SLCT_U32 80
153 #define NV_OP_SUB_F32 NV_OP_SUB
154 #define NV_OP_SUB_S32 81
155 #define NV_OP_MAD_F32 NV_OP_MAD
156 #define NV_OP_FSET_F32 82
159 #define NV_OP_COUNT 84
161 /* nv50 files omitted */
162 #define NV_FILE_GPR 0
163 #define NV_FILE_COND 1
164 #define NV_FILE_PRED 2
165 #define NV_FILE_IMM 16
166 #define NV_FILE_MEM_S 32
167 #define NV_FILE_MEM_V 34
168 #define NV_FILE_MEM_A 35
169 #define NV_FILE_MEM_L 48
170 #define NV_FILE_MEM_G 64
171 #define NV_FILE_MEM_C(i) (80 + i)
173 #define NV_IS_MEMORY_FILE(f) ((f) >= NV_FILE_MEM_S)
180 #define NV_TYPE_U8 0x00
181 #define NV_TYPE_S8 0x01
182 #define NV_TYPE_U16 0x02
183 #define NV_TYPE_S16 0x03
184 #define NV_TYPE_U32 0x04
185 #define NV_TYPE_S32 0x05
186 #define NV_TYPE_P32 0x07
187 #define NV_TYPE_F32 0x09
188 #define NV_TYPE_F64 0x0b
189 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
190 #define NV_TYPE_ANY 0xff
192 #define NV_TYPE_ISINT(t) ((t) < 7)
193 #define NV_TYPE_ISSGD(t) ((t) & 1)
209 #define NV_PC_MAX_INSTRUCTIONS 2048
210 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
212 #define NV_PC_MAX_BASIC_BLOCKS 1024
215 uint base
; /* e.g. ADD_S32 -> ADD */
220 unsigned commutative
: 1;
222 unsigned predicate
: 1;
224 unsigned immediate
: 3;
228 extern struct nv_op_info nvc0_op_info_table
[];
230 #define NV_BASEOP(op) (nvc0_op_info_table[op].base)
231 #define NV_OPTYPE(op) (nvc0_op_info_table[op].type)
234 nv_op_base(uint opcode
)
236 return nvc0_op_info_table
[opcode
].base
;
239 static INLINE boolean
240 nv_is_texture_op(uint opcode
)
242 return (opcode
>= NV_OP_TEX
&& opcode
<= NV_OP_TXQ
);
245 static INLINE boolean
246 nv_is_vector_op(uint opcode
)
248 return nvc0_op_info_table
[opcode
].vector
? TRUE
: FALSE
;
251 static INLINE boolean
252 nv_op_commutative(uint opcode
)
254 return nvc0_op_info_table
[opcode
].commutative
? TRUE
: FALSE
;
257 static INLINE
uint8_t
258 nv_op_supported_src_mods(uint opcode
)
260 return nvc0_op_info_table
[opcode
].mods
;
263 static INLINE boolean
264 nv_op_predicateable(uint opcode
)
266 return nvc0_op_info_table
[opcode
].predicate
? TRUE
: FALSE
;
270 nv_type_order(ubyte type
)
272 switch (type
& 0xf) {
292 nv_type_sizeof(ubyte type
)
295 return (1 << nv_type_order(type
)) * (type
>> 4);
296 return 1 << nv_type_order(type
);
300 nv_type_sizeof_base(ubyte type
)
302 return 1 << nv_type_order(type
);
306 uint32_t address
; /* for memory locations */
307 int id
; /* for registers */
314 uint32_t u32
; /* expected to be 0 for $r63 */
321 struct nv_range
*next
;
330 struct nv_instruction
*insn
;
331 struct nv_value
*join
;
332 struct nv_ref
*last_use
;
334 struct nv_range
*livei
;
336 struct nv_value
*next
;
337 struct nv_value
*prev
;
341 struct nv_value
*value
;
342 struct nv_instruction
*insn
;
343 struct list_head list
; /* connects uses of the same value */
348 struct nv_basic_block
;
350 struct nv_instruction
{
351 struct nv_instruction
*next
;
352 struct nv_instruction
*prev
;
356 struct nv_value
*def
[5];
357 struct nv_ref
*src
[6];
359 int8_t predicate
; /* index of predicate src */
360 int8_t indirect
; /* index of pointer src */
364 uint8_t t
; /* TIC binding */
365 uint8_t s
; /* TSC binding */
368 uint8_t d
; /* output type */
369 uint8_t s
; /* input type */
373 struct nv_basic_block
*bb
;
374 struct nv_basic_block
*target
; /* target block of control flow insn */
376 unsigned cc
: 5; /* condition code */
377 unsigned fixed
: 1; /* don't optimize away (prematurely) */
378 unsigned terminator
: 1;
380 unsigned set_cond
: 4; /* 2nd byte */
381 unsigned saturate
: 1;
382 unsigned centroid
: 1;
385 unsigned lanes
: 4; /* 3rd byte */
386 unsigned tex_dim
: 2;
387 unsigned tex_array
: 1;
388 unsigned tex_cube
: 1;
389 unsigned tex_shadow
: 1; /* 4th byte */
390 unsigned tex_live
: 1;
391 unsigned tex_mask
: 4;
397 nvi_vector_size(struct nv_instruction
*nvi
)
401 for (i
= 0; i
< 5 && nvi
->def
[i
]; ++i
);
405 #define CFG_EDGE_FORWARD 0
406 #define CFG_EDGE_BACK 1
407 #define CFG_EDGE_LOOP_ENTER 2
408 #define CFG_EDGE_LOOP_LEAVE 4
409 #define CFG_EDGE_FAKE 8
411 /* 'WALL' edge means where reachability check doesn't follow */
412 /* 'LOOP' edge means just having to do with loops */
413 #define IS_LOOP_EDGE(k) ((k) & 7)
414 #define IS_WALL_EDGE(k) ((k) & 9)
416 struct nv_basic_block
{
417 struct nv_instruction
*entry
; /* first non-phi instruction */
418 struct nv_instruction
*exit
;
419 struct nv_instruction
*phi
; /* very first instruction */
420 int num_instructions
;
422 struct nv_basic_block
*out
[2]; /* no indirect branches -> 2 */
423 struct nv_basic_block
*in
[8]; /* hope that suffices */
430 uint priv
; /* reset to 0 after you're done */
433 uint32_t emit_pos
; /* position, size in emitted code (in bytes) */
436 uint32_t live_set
[NV_PC_MAX_VALUES
/ 32];
439 struct nvc0_translation_info
;
442 struct nv_basic_block
**root
;
443 struct nv_basic_block
*current_block
;
444 struct nv_basic_block
*parent_block
;
446 int loop_nesting_bound
;
449 struct nv_value values
[NV_PC_MAX_VALUES
];
450 struct nv_instruction instructions
[NV_PC_MAX_INSTRUCTIONS
];
451 struct nv_ref
**refs
;
452 struct nv_basic_block
*bb_list
[NV_PC_MAX_BASIC_BLOCKS
];
454 int num_instructions
;
461 uint32_t *immd_buf
; /* populated on emit */
471 /* optimization enables */
472 boolean opt_reload_elim
;
476 void nvc0_insn_append(struct nv_basic_block
*, struct nv_instruction
*);
477 void nvc0_insn_insert_before(struct nv_instruction
*, struct nv_instruction
*);
478 void nvc0_insn_insert_after(struct nv_instruction
*, struct nv_instruction
*);
480 static INLINE
struct nv_instruction
*
481 nv_alloc_instruction(struct nv_pc
*pc
, uint opcode
)
483 struct nv_instruction
*insn
;
485 insn
= &pc
->instructions
[pc
->num_instructions
++];
486 assert(pc
->num_instructions
< NV_PC_MAX_INSTRUCTIONS
);
488 insn
->opcode
= opcode
;
491 insn
->predicate
= -1;
496 static INLINE
struct nv_instruction
*
497 new_instruction(struct nv_pc
*pc
, uint opcode
)
499 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
501 nvc0_insn_append(pc
->current_block
, insn
);
505 static INLINE
struct nv_instruction
*
506 new_instruction_at(struct nv_pc
*pc
, struct nv_instruction
*at
, uint opcode
)
508 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
510 nvc0_insn_insert_after(at
, insn
);
514 static INLINE
struct nv_value
*
515 new_value(struct nv_pc
*pc
, ubyte file
, ubyte size
)
517 struct nv_value
*value
= &pc
->values
[pc
->num_values
];
519 assert(pc
->num_values
< NV_PC_MAX_VALUES
- 1);
521 value
->n
= pc
->num_values
++;
524 value
->reg
.file
= file
;
525 value
->reg
.size
= size
;
529 static INLINE
struct nv_value
*
530 new_value_like(struct nv_pc
*pc
, struct nv_value
*like
)
532 return new_value(pc
, like
->reg
.file
, like
->reg
.size
);
535 static INLINE
struct nv_ref
*
536 new_ref(struct nv_pc
*pc
, struct nv_value
*val
)
541 if ((pc
->num_refs
% 64) == 0) {
542 const unsigned old_size
= pc
->num_refs
* sizeof(struct nv_ref
*);
543 const unsigned new_size
= (pc
->num_refs
+ 64) * sizeof(struct nv_ref
*);
545 pc
->refs
= REALLOC(pc
->refs
, old_size
, new_size
);
547 ref
= CALLOC(64, sizeof(struct nv_ref
));
548 for (i
= 0; i
< 64; ++i
)
549 pc
->refs
[pc
->num_refs
+ i
] = &ref
[i
];
552 ref
= pc
->refs
[pc
->num_refs
++];
555 LIST_INITHEAD(&ref
->list
);
561 static INLINE
struct nv_basic_block
*
562 new_basic_block(struct nv_pc
*pc
)
564 struct nv_basic_block
*bb
;
566 if (pc
->num_blocks
>= NV_PC_MAX_BASIC_BLOCKS
)
569 bb
= CALLOC_STRUCT(nv_basic_block
);
571 bb
->id
= pc
->num_blocks
;
572 pc
->bb_list
[pc
->num_blocks
++] = bb
;
577 nv_reference(struct nv_pc
*pc
,
578 struct nv_instruction
*nvi
, int c
, struct nv_value
*s
)
580 struct nv_ref
**d
= &nvi
->src
[c
];
585 LIST_DEL(&(*d
)->list
);
593 LIST_DEL(&(*d
)->list
);
600 LIST_ADDTAIL(&s
->last_use
->list
, &(*d
)->list
);
610 void nvc0_emit_instruction(struct nv_pc
*, struct nv_instruction
*);
613 const char *nvc0_opcode_name(uint opcode
);
614 void nvc0_print_instruction(struct nv_instruction
*);
617 void nvc0_print_function(struct nv_basic_block
*root
);
618 void nvc0_print_program(struct nv_pc
*);
620 boolean
nvc0_insn_can_load(struct nv_instruction
*, int s
,
621 struct nv_instruction
*);
622 boolean
nvc0_insn_is_predicateable(struct nv_instruction
*);
624 int nvc0_insn_refcount(struct nv_instruction
*);
625 void nvc0_insn_delete(struct nv_instruction
*);
626 void nvc0_insns_permute(struct nv_instruction
*prev
, struct nv_instruction
*);
628 void nvc0_bblock_attach(struct nv_basic_block
*parent
,
629 struct nv_basic_block
*child
, ubyte edge_kind
);
630 boolean
nvc0_bblock_dominated_by(struct nv_basic_block
*,
631 struct nv_basic_block
*);
632 boolean
nvc0_bblock_reachable_by(struct nv_basic_block
*future
,
633 struct nv_basic_block
*past
,
634 struct nv_basic_block
*final
);
635 struct nv_basic_block
*nvc0_bblock_dom_frontier(struct nv_basic_block
*);
637 int nvc0_pc_replace_value(struct nv_pc
*pc
,
638 struct nv_value
*old_val
,
639 struct nv_value
*new_val
);
641 struct nv_value
*nvc0_pc_find_immediate(struct nv_ref
*);
642 struct nv_value
*nvc0_pc_find_constant(struct nv_ref
*);
644 typedef void (*nv_pc_pass_func
)(void *priv
, struct nv_basic_block
*b
);
646 void nvc0_pc_pass_in_order(struct nv_basic_block
*, nv_pc_pass_func
, void *);
648 int nvc0_pc_exec_pass0(struct nv_pc
*pc
);
649 int nvc0_pc_exec_pass1(struct nv_pc
*pc
);
650 int nvc0_pc_exec_pass2(struct nv_pc
*pc
);
652 int nvc0_tgsi_to_nc(struct nv_pc
*, struct nvc0_translation_info
*);
654 #endif // NV50_COMPILER_H