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 __NV50_COMPILER_H__
24 #define __NV50_COMPILER_H__
26 #include "nv50_debug.h"
28 #include "pipe/p_defines.h"
29 #include "util/u_inlines.h"
30 #include "util/u_memory.h"
33 #define NV_OP_EXTRACT 1
34 #define NV_OP_COMBINE 2
52 #define NV_OP_UNDEF 20
58 #define NV_OP_PRESIN 26
59 #define NV_OP_PREEX2 27
68 #define NV_OP_BREAK 36
69 #define NV_OP_BREAKADDR 37
70 #define NV_OP_JOINAT 38
78 #define NV_OP_QUADOP 46
79 #define NV_OP_LINTERP 47
80 #define NV_OP_PINTERP 48
83 #define NV_OP_FLOOR 51
84 #define NV_OP_TRUNC 52
86 #define NV_OP_SELECT 54
87 #define NV_OP_EXPORT 55
89 #define NV_OP_COUNT 57
93 #define NV_FILE_ADDR 2
94 #define NV_FILE_FLAGS 3
95 #define NV_FILE_IMM 16
96 #define NV_FILE_MEM_S 32
97 #define NV_FILE_MEM_P 33
98 #define NV_FILE_MEM_V 34
99 #define NV_FILE_MEM_L 48
100 #define NV_FILE_MEM_G(i) (64 + i)
101 #define NV_FILE_MEM_C(i) (80 + i)
108 #define NV_TYPE_U8 0x00
109 #define NV_TYPE_S8 0x01
110 #define NV_TYPE_U16 0x02
111 #define NV_TYPE_S16 0x03
112 #define NV_TYPE_U32 0x04
113 #define NV_TYPE_S32 0x05
114 #define NV_TYPE_P32 0x07
115 #define NV_TYPE_F32 0x09
116 #define NV_TYPE_F64 0x0b
117 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
118 #define NV_TYPE_LO 0x00
119 #define NV_TYPE_HI 0x80
120 #define NV_TYPE_ANY 0xff
122 #define NV_TYPE_ISINT(t) ((t) <= 5)
123 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
125 /* $cX registers contain 4 bits: OCSZ (Z is bit 0) */
140 #define NV_PC_MAX_INSTRUCTIONS 2048
141 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
143 #define NV_PC_MAX_BASIC_BLOCKS 1024
145 static INLINE boolean
146 nv_is_vector_op(uint opcode
)
148 return (opcode
>= NV_OP_TEX
) && (opcode
<= NV_OP_TXQ
);
152 nv_type_order(ubyte type
)
154 switch (type
& 0xf) {
174 nv_type_sizeof(ubyte type
)
177 return (1 << nv_type_order(type
)) * (type
>> 4);
178 return 1 << nv_type_order(type
);
182 nv_type_sizeof_base(ubyte type
)
184 return 1 << nv_type_order(type
);
190 ubyte type
; /* type of generating instruction's result */
191 ubyte as_type
; /* default type for new references to this value */
201 struct nv_range
*next
;
208 struct nv_instruction
*insn
;
209 struct nv_value
*join
;
211 struct nv_range
*livei
;
214 struct nv_value
*next
;
215 struct nv_value
*prev
;
219 struct nv_value
*value
;
222 ubyte flags
; /* not used yet */
225 #define NV_REF_FLAG_REGALLOC_PRIV (1 << 0)
227 struct nv_basic_block
;
229 struct nv_instruction
{
230 struct nv_instruction
*next
;
231 struct nv_instruction
*prev
;
234 struct nv_value
*def
[4];
235 struct nv_value
*flags_def
;
236 struct nv_ref
*src
[5];
237 struct nv_ref
*flags_src
;
238 struct nv_basic_block
*bb
;
239 struct nv_basic_block
*target
; /* target block of control flow insn */
241 unsigned set_cond
: 4;
242 unsigned fixed
: 1; /* don't optimize away */
243 unsigned is_terminator
: 1;
244 unsigned is_join
: 1;
245 unsigned is_long
: 1; /* for emission */
247 unsigned saturate
: 1;
248 unsigned centroid
: 1;
251 unsigned tex_live
: 1;
253 ubyte tex_t
; /* TIC binding */
254 ubyte tex_s
; /* TSC binding */
255 unsigned tex_argc
: 3;
256 unsigned tex_cube
: 1;
257 unsigned tex_mask
: 4;
263 nvi_vector_size(struct nv_instruction
*nvi
)
267 for (i
= 0; i
< 4 && nvi
->def
[i
]; ++i
);
271 #define CFG_EDGE_FORWARD 0
272 #define CFG_EDGE_BACK 1
273 #define CFG_EDGE_LOOP_ENTER 2
274 #define CFG_EDGE_LOOP_LEAVE 4
275 #define CFG_EDGE_FAKE 8
277 /* 'WALL' edge means where reachability check doesn't follow */
278 /* 'LOOP' edge means just having to do with loops */
279 #define IS_LOOP_EDGE(k) ((k) & 7)
280 #define IS_WALL_EDGE(k) ((k) & 9)
282 struct nv_basic_block
{
283 struct nv_instruction
*entry
; /* first non-phi instruction */
284 struct nv_instruction
*exit
;
285 struct nv_instruction
*phi
; /* very first instruction */
286 int num_instructions
;
288 struct nv_basic_block
*out
[2]; /* no indirect branches -> 2 */
289 struct nv_basic_block
*in
[8]; /* hope that suffices */
296 uint priv
; /* reset to 0 after you're done */
299 uint32_t bin_pos
; /* position, size in emitted code */
302 uint32_t live_set
[NV_PC_MAX_VALUES
/ 32];
305 struct nv50_translation_info
;
308 struct nv_basic_block
**root
;
309 struct nv_basic_block
*current_block
;
310 struct nv_basic_block
*parent_block
;
312 int loop_nesting_bound
;
315 struct nv_value values
[NV_PC_MAX_VALUES
];
316 struct nv_instruction instructions
[NV_PC_MAX_INSTRUCTIONS
];
317 struct nv_ref
**refs
;
318 struct nv_basic_block
*bb_list
[NV_PC_MAX_BASIC_BLOCKS
];
320 int num_instructions
;
327 uint32_t *immd_buf
; /* populated on emit */
337 /* optimization enables */
338 boolean opt_reload_elim
;
341 void nvbb_insert_tail(struct nv_basic_block
*, struct nv_instruction
*);
342 void nvi_insert_after(struct nv_instruction
*, struct nv_instruction
*);
344 static INLINE
struct nv_instruction
*
345 nv_alloc_instruction(struct nv_pc
*pc
, uint opcode
)
347 struct nv_instruction
*insn
;
349 insn
= &pc
->instructions
[pc
->num_instructions
++];
350 assert(pc
->num_instructions
< NV_PC_MAX_INSTRUCTIONS
);
353 insn
->opcode
= opcode
;
358 static INLINE
struct nv_instruction
*
359 new_instruction(struct nv_pc
*pc
, uint opcode
)
361 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
363 nvbb_insert_tail(pc
->current_block
, insn
);
367 static INLINE
struct nv_instruction
*
368 new_instruction_at(struct nv_pc
*pc
, struct nv_instruction
*at
, uint opcode
)
370 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
372 nvi_insert_after(at
, insn
);
376 static INLINE
struct nv_value
*
377 new_value(struct nv_pc
*pc
, ubyte file
, ubyte type
)
379 struct nv_value
*value
= &pc
->values
[pc
->num_values
];
381 assert(pc
->num_values
< NV_PC_MAX_VALUES
- 1);
383 value
->n
= pc
->num_values
++;
386 value
->reg
.file
= file
;
387 value
->reg
.type
= value
->reg
.as_type
= type
;
391 static INLINE
struct nv_value
*
392 new_value_like(struct nv_pc
*pc
, struct nv_value
*like
)
394 struct nv_value
*val
= new_value(pc
, like
->reg
.file
, like
->reg
.type
);
395 val
->reg
.as_type
= like
->reg
.as_type
;
399 static INLINE
struct nv_ref
*
400 new_ref(struct nv_pc
*pc
, struct nv_value
*val
)
405 if ((pc
->num_refs
% 64) == 0) {
406 const unsigned old_size
= pc
->num_refs
* sizeof(struct nv_ref
*);
407 const unsigned new_size
= (pc
->num_refs
+ 64) * sizeof(struct nv_ref
*);
409 pc
->refs
= REALLOC(pc
->refs
, old_size
, new_size
);
411 ref
= CALLOC(64, sizeof(struct nv_ref
));
412 for (i
= 0; i
< 64; ++i
)
413 pc
->refs
[pc
->num_refs
+ i
] = &ref
[i
];
416 ref
= pc
->refs
[pc
->num_refs
++];
418 ref
->typecast
= val
->reg
.as_type
;
424 static INLINE
struct nv_basic_block
*
425 new_basic_block(struct nv_pc
*pc
)
427 struct nv_basic_block
*bb
;
429 if (pc
->num_blocks
>= NV_PC_MAX_BASIC_BLOCKS
)
432 bb
= CALLOC_STRUCT(nv_basic_block
);
434 bb
->id
= pc
->num_blocks
;
435 pc
->bb_list
[pc
->num_blocks
++] = bb
;
440 nv_reference(struct nv_pc
*pc
, struct nv_ref
**d
, struct nv_value
*s
)
458 void nv50_emit_instruction(struct nv_pc
*, struct nv_instruction
*);
459 unsigned nv50_inst_min_size(struct nv_instruction
*);
462 const char *nv_opcode_name(uint opcode
);
463 void nv_print_instruction(struct nv_instruction
*);
467 void nv_print_function(struct nv_basic_block
*root
);
468 void nv_print_program(struct nv_pc
*);
470 boolean
nv_op_commutative(uint opcode
);
471 int nv50_indirect_opnd(struct nv_instruction
*);
472 boolean
nv50_nvi_can_use_imm(struct nv_instruction
*, int s
);
473 boolean
nv50_nvi_can_predicate(struct nv_instruction
*);
474 boolean
nv50_nvi_can_load(struct nv_instruction
*, int s
, struct nv_value
*);
475 boolean
nv50_op_can_write_flags(uint opcode
);
476 ubyte
nv50_supported_src_mods(uint opcode
, int s
);
477 int nv_nvi_refcount(struct nv_instruction
*);
478 void nv_nvi_delete(struct nv_instruction
*);
479 void nv_nvi_permute(struct nv_instruction
*, struct nv_instruction
*);
480 void nvbb_attach_block(struct nv_basic_block
*parent
,
481 struct nv_basic_block
*, ubyte edge_kind
);
482 boolean
nvbb_dominated_by(struct nv_basic_block
*, struct nv_basic_block
*);
483 boolean
nvbb_reachable_by(struct nv_basic_block
*, struct nv_basic_block
*,
484 struct nv_basic_block
*);
485 struct nv_basic_block
*nvbb_dom_frontier(struct nv_basic_block
*);
486 int nvcg_replace_value(struct nv_pc
*pc
, struct nv_value
*old_val
,
487 struct nv_value
*new_val
);
488 struct nv_value
*nvcg_find_immediate(struct nv_ref
*);
489 struct nv_value
*nvcg_find_constant(struct nv_ref
*);
491 typedef void (*nv_pc_pass_func
)(void *priv
, struct nv_basic_block
*b
);
493 void nv_pc_pass_in_order(struct nv_basic_block
*, nv_pc_pass_func
, void *);
495 int nv_pc_exec_pass0(struct nv_pc
*pc
);
496 int nv_pc_exec_pass1(struct nv_pc
*pc
);
497 int nv_pc_exec_pass2(struct nv_pc
*pc
);
499 int nv50_tgsi_to_nc(struct nv_pc
*, struct nv50_translation_info
*);
501 #endif // NV50_COMPILER_H