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__
27 # define NV50_DBGMSG(args...) debug_printf(args)
29 # define NV50_DBGMSG(args...)
32 #include "pipe/p_defines.h"
33 #include "util/u_inlines.h"
34 #include "util/u_memory.h"
37 #define NV_OP_EXTRACT 1
38 #define NV_OP_COMBINE 2
56 #define NV_OP_UNDEF 20
62 #define NV_OP_PRESIN 26
63 #define NV_OP_PREEX2 27
72 #define NV_OP_BREAK 36
73 #define NV_OP_BREAKADDR 37
74 #define NV_OP_JOINAT 38
82 #define NV_OP_QUADOP 46
83 #define NV_OP_LINTERP 47
84 #define NV_OP_PINTERP 48
87 #define NV_OP_FLOOR 51
88 #define NV_OP_TRUNC 52
90 #define NV_OP_SELECT 54
91 #define NV_OP_EXPORT 55
93 #define NV_OP_COUNT 57
97 #define NV_FILE_ADDR 2
98 #define NV_FILE_FLAGS 3
99 #define NV_FILE_IMM 16
100 #define NV_FILE_MEM_S 32
101 #define NV_FILE_MEM_P 33
102 #define NV_FILE_MEM_V 34
103 #define NV_FILE_MEM_L 48
104 #define NV_FILE_MEM_G(i) (64 + i)
105 #define NV_FILE_MEM_C(i) (80 + i)
112 #define NV_TYPE_U8 0x00
113 #define NV_TYPE_S8 0x01
114 #define NV_TYPE_U16 0x02
115 #define NV_TYPE_S16 0x03
116 #define NV_TYPE_U32 0x04
117 #define NV_TYPE_S32 0x05
118 #define NV_TYPE_P32 0x07
119 #define NV_TYPE_F32 0x09
120 #define NV_TYPE_F64 0x0b
121 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
122 #define NV_TYPE_LO 0x00
123 #define NV_TYPE_HI 0x80
124 #define NV_TYPE_ANY 0xff
126 #define NV_TYPE_ISINT(t) ((t) <= 5)
127 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
129 /* $cX registers contain 4 bits: OCSZ (Z is bit 0) */
144 #define NV_PC_MAX_INSTRUCTIONS 2048
145 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
147 #define NV_PC_MAX_BASIC_BLOCKS 1024
149 static INLINE boolean
150 nv_is_vector_op(uint opcode
)
152 return (opcode
>= NV_OP_TEX
) && (opcode
<= NV_OP_TXQ
);
156 nv_type_order(ubyte type
)
158 switch (type
& 0xf) {
178 nv_type_sizeof(ubyte type
)
181 return (1 << nv_type_order(type
)) * (type
>> 4);
182 return 1 << nv_type_order(type
);
186 nv_type_sizeof_base(ubyte type
)
188 return 1 << nv_type_order(type
);
194 ubyte type
; /* type of generating instruction's result */
195 ubyte as_type
; /* default type for new references to this value */
205 struct nv_range
*next
;
212 struct nv_instruction
*insn
;
213 struct nv_value
*join
;
215 struct nv_range
*livei
;
218 struct nv_value
*next
;
219 struct nv_value
*prev
;
223 struct nv_value
*value
;
226 ubyte flags
; /* not used yet */
229 struct nv_basic_block
;
231 struct nv_instruction
{
232 struct nv_instruction
*next
;
233 struct nv_instruction
*prev
;
236 struct nv_value
*def
[4];
237 struct nv_value
*flags_def
;
238 struct nv_ref
*src
[5];
239 struct nv_ref
*flags_src
;
240 struct nv_basic_block
*bb
;
241 struct nv_basic_block
*target
; /* target block of control flow insn */
243 unsigned set_cond
: 4;
244 unsigned fixed
: 1; /* don't optimize away */
245 unsigned is_terminator
: 1;
246 unsigned is_join
: 1;
247 unsigned is_long
: 1; /* for emission */
249 unsigned saturate
: 1;
250 unsigned centroid
: 1;
253 unsigned tex_live
: 1;
255 ubyte tex_t
; /* TIC binding */
256 ubyte tex_s
; /* TSC binding */
257 unsigned tex_argc
: 3;
258 unsigned tex_cube
: 1;
259 unsigned tex_mask
: 4;
264 #define CFG_EDGE_FORWARD 0
265 #define CFG_EDGE_BACK 1
266 #define CFG_EDGE_LOOP_ENTER 2
267 #define CFG_EDGE_LOOP_LEAVE 4
268 #define CFG_EDGE_FAKE 8
270 /* 'WALL' edge means where reachability check doesn't follow */
271 /* 'LOOP' edge means just having to do with loops */
272 #define IS_LOOP_EDGE(k) ((k) & 7)
273 #define IS_WALL_EDGE(k) ((k) & 9)
275 struct nv_basic_block
{
276 struct nv_instruction
*entry
; /* first non-phi instruction */
277 struct nv_instruction
*exit
;
278 struct nv_instruction
*phi
; /* very first instruction */
279 int num_instructions
;
281 struct nv_basic_block
*out
[2]; /* no indirect branches -> 2 */
282 struct nv_basic_block
*in
[8]; /* hope that suffices */
289 uint priv
; /* reset to 0 after you're done */
292 uint32_t bin_pos
; /* position, size in emitted code */
295 uint32_t live_set
[NV_PC_MAX_VALUES
/ 32];
298 struct nv50_translation_info
;
301 struct nv_basic_block
**root
;
302 struct nv_basic_block
*current_block
;
303 struct nv_basic_block
*parent_block
;
305 int loop_nesting_bound
;
308 struct nv_value values
[NV_PC_MAX_VALUES
];
309 struct nv_instruction instructions
[NV_PC_MAX_INSTRUCTIONS
];
310 struct nv_ref
**refs
;
311 struct nv_basic_block
*bb_list
[NV_PC_MAX_BASIC_BLOCKS
];
313 int num_instructions
;
320 uint32_t *immd_buf
; /* populated on emit */
330 /* optimization enables */
331 boolean opt_reload_elim
;
334 void nvbb_insert_tail(struct nv_basic_block
*, struct nv_instruction
*);
335 void nvi_insert_after(struct nv_instruction
*, struct nv_instruction
*);
337 static INLINE
struct nv_instruction
*
338 nv_alloc_instruction(struct nv_pc
*pc
, uint opcode
)
340 struct nv_instruction
*insn
;
342 insn
= &pc
->instructions
[pc
->num_instructions
++];
343 assert(pc
->num_instructions
< NV_PC_MAX_INSTRUCTIONS
);
346 insn
->opcode
= opcode
;
351 static INLINE
struct nv_instruction
*
352 new_instruction(struct nv_pc
*pc
, uint opcode
)
354 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
356 nvbb_insert_tail(pc
->current_block
, insn
);
360 static INLINE
struct nv_instruction
*
361 new_instruction_at(struct nv_pc
*pc
, struct nv_instruction
*at
, uint opcode
)
363 struct nv_instruction
*insn
= nv_alloc_instruction(pc
, opcode
);
365 nvi_insert_after(at
, insn
);
369 static INLINE
struct nv_value
*
370 new_value(struct nv_pc
*pc
, ubyte file
, ubyte type
)
372 struct nv_value
*value
= &pc
->values
[pc
->num_values
];
374 assert(pc
->num_values
< NV_PC_MAX_VALUES
- 1);
376 value
->n
= pc
->num_values
++;
379 value
->reg
.file
= file
;
380 value
->reg
.type
= value
->reg
.as_type
= type
;
384 static INLINE
struct nv_value
*
385 new_value_like(struct nv_pc
*pc
, struct nv_value
*like
)
387 struct nv_value
*val
= new_value(pc
, like
->reg
.file
, like
->reg
.type
);
388 val
->reg
.as_type
= like
->reg
.as_type
;
392 static INLINE
struct nv_ref
*
393 new_ref(struct nv_pc
*pc
, struct nv_value
*val
)
398 if ((pc
->num_refs
% 64) == 0) {
399 const unsigned old_size
= pc
->num_refs
* sizeof(struct nv_ref
*);
400 const unsigned new_size
= (pc
->num_refs
+ 64) * sizeof(struct nv_ref
*);
402 pc
->refs
= REALLOC(pc
->refs
, old_size
, new_size
);
404 ref
= CALLOC(64, sizeof(struct nv_ref
));
405 for (i
= 0; i
< 64; ++i
)
406 pc
->refs
[pc
->num_refs
+ i
] = &ref
[i
];
409 ref
= pc
->refs
[pc
->num_refs
++];
411 ref
->typecast
= val
->reg
.as_type
;
417 static INLINE
struct nv_basic_block
*
418 new_basic_block(struct nv_pc
*pc
)
420 struct nv_basic_block
*bb
;
422 if (pc
->num_blocks
>= NV_PC_MAX_BASIC_BLOCKS
)
425 bb
= CALLOC_STRUCT(nv_basic_block
);
427 bb
->id
= pc
->num_blocks
;
428 pc
->bb_list
[pc
->num_blocks
++] = bb
;
433 nv_reference(struct nv_pc
*pc
, struct nv_ref
**d
, struct nv_value
*s
)
451 void nv50_emit_instruction(struct nv_pc
*, struct nv_instruction
*);
452 unsigned nv50_inst_min_size(struct nv_instruction
*);
455 const char *nv_opcode_name(uint opcode
);
456 void nv_print_instruction(struct nv_instruction
*);
460 void nv_print_function(struct nv_basic_block
*root
);
461 void nv_print_program(struct nv_pc
*);
463 boolean
nv_op_commutative(uint opcode
);
464 int nv50_indirect_opnd(struct nv_instruction
*);
465 boolean
nv50_nvi_can_use_imm(struct nv_instruction
*, int s
);
466 boolean
nv50_nvi_can_predicate(struct nv_instruction
*);
467 boolean
nv50_nvi_can_load(struct nv_instruction
*, int s
, struct nv_value
*);
468 boolean
nv50_op_can_write_flags(uint opcode
);
469 ubyte
nv50_supported_src_mods(uint opcode
, int s
);
470 int nv_nvi_refcount(struct nv_instruction
*);
471 void nv_nvi_delete(struct nv_instruction
*);
472 void nv_nvi_permute(struct nv_instruction
*, struct nv_instruction
*);
473 void nvbb_attach_block(struct nv_basic_block
*parent
,
474 struct nv_basic_block
*, ubyte edge_kind
);
475 boolean
nvbb_dominated_by(struct nv_basic_block
*, struct nv_basic_block
*);
476 boolean
nvbb_reachable_by(struct nv_basic_block
*, struct nv_basic_block
*,
477 struct nv_basic_block
*);
478 struct nv_basic_block
*nvbb_dom_frontier(struct nv_basic_block
*);
479 int nvcg_replace_value(struct nv_pc
*pc
, struct nv_value
*old_val
,
480 struct nv_value
*new_val
);
481 struct nv_value
*nvcg_find_immediate(struct nv_ref
*);
482 struct nv_value
*nvcg_find_constant(struct nv_ref
*);
484 typedef void (*nv_pc_pass_func
)(void *priv
, struct nv_basic_block
*b
);
486 void nv_pc_pass_in_order(struct nv_basic_block
*, nv_pc_pass_func
, void *);
488 int nv_pc_exec_pass0(struct nv_pc
*pc
);
489 int nv_pc_exec_pass1(struct nv_pc
*pc
);
490 int nv_pc_exec_pass2(struct nv_pc
*pc
);
492 int nv50_tgsi_to_nc(struct nv_pc
*, struct nv50_translation_info
*);
494 #endif // NV50_COMPILER_H