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 "pipe/p_defines.h"
27 #include "util/u_inlines.h"
28 #include "util/u_memory.h"
31 #define NV_OP_EXTRACT 1
32 #define NV_OP_COMBINE 2
50 #define NV_OP_UNDEF 20
56 #define NV_OP_PRESIN 26
57 #define NV_OP_PREEX2 27
66 #define NV_OP_BREAK 36
67 #define NV_OP_BREAKADDR 37
68 #define NV_OP_JOINAT 38
76 #define NV_OP_QUADOP 46
77 #define NV_OP_LINTERP 47
78 #define NV_OP_PINTERP 48
81 #define NV_OP_FLOOR 51
82 #define NV_OP_TRUNC 52
84 #define NV_OP_SELECT 54
85 #define NV_OP_EXPORT 55
87 #define NV_OP_COUNT 57
91 #define NV_FILE_ADDR 2
92 #define NV_FILE_FLAGS 3
93 #define NV_FILE_IMM 16
94 #define NV_FILE_MEM_S 32
95 #define NV_FILE_MEM_P 33
96 #define NV_FILE_MEM_V 34
97 #define NV_FILE_MEM_L 48
98 #define NV_FILE_MEM_G(i) (64 + i)
99 #define NV_FILE_MEM_C(i) (80 + i)
106 #define NV_TYPE_U8 0x00
107 #define NV_TYPE_S8 0x01
108 #define NV_TYPE_U16 0x02
109 #define NV_TYPE_S16 0x03
110 #define NV_TYPE_U32 0x04
111 #define NV_TYPE_S32 0x05
112 #define NV_TYPE_P32 0x07
113 #define NV_TYPE_F32 0x09
114 #define NV_TYPE_F64 0x0b
115 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
116 #define NV_TYPE_LO 0x00
117 #define NV_TYPE_HI 0x80
118 #define NV_TYPE_ANY 0xff
120 #define NV_TYPE_ISINT(t) ((t) <= 5)
121 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
133 #define NV_PC_MAX_INSTRUCTIONS 2048
134 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
136 static INLINE boolean
137 nv_is_vector_op(uint opcode
)
139 return (opcode
>= NV_OP_TEX
) && (opcode
<= NV_OP_TXQ
);
143 nv_type_order(ubyte type
)
145 switch (type
& 0xf) {
164 nv_type_sizeof(ubyte type
)
167 return (1 << nv_type_order(type
)) * (type
>> 4);
168 return 1 << nv_type_order(type
);
172 nv_type_sizeof_base(ubyte type
)
174 return 1 << nv_type_order(type
);
180 ubyte type
; /* type of generating instruction's result */
190 struct nv_range
*next
;
197 struct nv_instruction
*insn
;
198 struct nv_value
*join
;
200 struct nv_range
*livei
;
203 struct nv_value
*next
;
204 struct nv_value
*prev
;
208 struct nv_value
*value
;
209 struct nv_instruction
*insn
;
212 ubyte flags
; /* not used yet */
215 struct nv_basic_block
;
217 struct nv_instruction
{
218 struct nv_instruction
*next
;
219 struct nv_instruction
*prev
;
222 struct nv_value
*def
[4];
223 struct nv_value
*flags_def
;
224 struct nv_ref
*src
[5];
225 struct nv_ref
*flags_src
;
226 struct nv_basic_block
*bb
;
227 struct nv_basic_block
*target
; /* target block of control flow insn */
230 ubyte fixed
: 1; /* don't optimize away */
231 ubyte is_terminator
: 1;
233 ubyte is_long
: 1; /* for emission */
241 ubyte tex_t
; /* TIC binding */
242 ubyte tex_s
; /* TSC binding */
250 #define CFG_EDGE_FORWARD 0
251 #define CFG_EDGE_BACK 1
252 #define CFG_EDGE_LOOP_ENTER 2
253 #define CFG_EDGE_LOOP_LEAVE 4
255 struct nv_basic_block
{
256 struct nv_instruction
*entry
; /* first non-phi instruction */
257 struct nv_instruction
*exit
;
258 struct nv_instruction
*phi
; /* very first instruction */
259 int num_instructions
;
261 struct nv_basic_block
*out
[2]; /* no indirect branches -> 2 */
262 struct nv_basic_block
*in
[8]; /* hope that suffices */
268 struct nv_basic_block
*last_visitor
;
272 uint32_t bin_pos
; /* position, size in emitted code */
275 uint32_t live_set
[NV_PC_MAX_VALUES
/ 32];
278 #define NV_FIXUP_CFLOW_RELOC 0
279 #define NV_FIXUP_PARAM_RELOC 1
290 nv_fixup_apply(uint32_t *bin
, struct nv_fixup
*fixup
, uint32_t data
)
294 val
= bin
[fixup
->offset
/ 4] & ~fixup
->mask
;
295 data
= (fixup
->shift
< 0) ? (data
>> fixup
->shift
) : (data
<< fixup
->shift
);
296 val
|= (fixup
->data
+ data
) & fixup
->mask
;
297 bin
[fixup
->offset
/ 4] = val
;
301 struct nv50_translation_info
*ti
;
303 struct nv_basic_block
*root
;
304 struct nv_basic_block
*current_block
;
305 struct nv_basic_block
*parent_block
;
307 int loop_nesting_bound
;
310 struct nv_value values
[NV_PC_MAX_VALUES
];
311 struct nv_instruction instructions
[NV_PC_MAX_INSTRUCTIONS
];
312 struct nv_ref
**refs
;
313 struct nv_basic_block
**bb_list
;
315 int num_instructions
;
321 uint32_t *immd_buf
; /* populated on emit */
328 struct nv_fixup
*fixups
;
332 void nvbb_insert_tail(struct nv_basic_block
*, struct nv_instruction
*);
334 static INLINE
struct nv_instruction
*
335 new_instruction(struct nv_pc
*pc
, uint opcode
)
337 struct nv_instruction
*insn
;
339 insn
= &pc
->instructions
[pc
->num_instructions
++];
340 assert(pc
->num_instructions
< NV_PC_MAX_INSTRUCTIONS
);
343 insn
->opcode
= opcode
;
345 nvbb_insert_tail(pc
->current_block
, insn
);
349 static INLINE
struct nv_value
*
350 new_value(struct nv_pc
*pc
, ubyte file
, ubyte type
)
352 struct nv_value
*value
= &pc
->values
[pc
->num_values
];
354 assert(pc
->num_values
< NV_PC_MAX_VALUES
- 1);
356 value
->n
= pc
->num_values
++;
359 value
->reg
.file
= file
;
360 value
->reg
.type
= type
;
364 static INLINE
struct nv_value
*
365 new_value_like(struct nv_pc
*pc
, struct nv_value
*like
)
367 return new_value(pc
, like
->reg
.file
, like
->reg
.type
);
370 static INLINE
struct nv_ref
*
371 new_ref(struct nv_pc
*pc
, struct nv_value
*val
)
376 if ((pc
->num_refs
% 64) == 0) {
377 const unsigned old_size
= pc
->num_refs
* sizeof(struct nv_ref
*);
378 const unsigned new_size
= (pc
->num_refs
+ 64) * sizeof(struct nv_ref
*);
380 pc
->refs
= REALLOC(pc
->refs
, old_size
, new_size
);
382 ref
= CALLOC(64, sizeof(struct nv_ref
));
383 for (i
= 0; i
< 64; ++i
)
384 pc
->refs
[pc
->num_refs
+ i
] = &ref
[i
];
387 ref
= pc
->refs
[pc
->num_refs
++];
389 ref
->typecast
= val
->reg
.type
;
395 static INLINE
struct nv_basic_block
*
396 new_basic_block(struct nv_pc
*pc
)
398 struct nv_basic_block
*bb
= CALLOC_STRUCT(nv_basic_block
);
400 bb
->id
= pc
->num_blocks
++;
405 nv_reference(struct nv_pc
*pc
, struct nv_ref
**d
, struct nv_value
*s
)
423 void nv50_emit_instruction(struct nv_pc
*, struct nv_instruction
*);
426 const char *nv_opcode_name(uint opcode
);
427 void nv_print_instruction(struct nv_instruction
*);
431 void nv_print_program(struct nv_basic_block
*b
);
433 boolean
nv_op_commutative(uint opcode
);
434 int nv50_indirect_opnd(struct nv_instruction
*);
435 boolean
nv50_nvi_can_use_imm(struct nv_instruction
*, int s
);
436 boolean
nv50_nvi_can_predicate(struct nv_instruction
*);
437 boolean
nv50_nvi_can_load(struct nv_instruction
*, int s
, struct nv_value
*);
438 ubyte
nv50_supported_src_mods(uint opcode
, int s
);
439 int nv_nvi_refcount(struct nv_instruction
*);
440 void nv_nvi_delete(struct nv_instruction
*);
441 void nv_nvi_permute(struct nv_instruction
*, struct nv_instruction
*);
442 void nvbb_attach_block(struct nv_basic_block
*parent
,
443 struct nv_basic_block
*, ubyte edge_kind
);
444 boolean
nvbb_dominated_by(struct nv_basic_block
*, struct nv_basic_block
*);
445 boolean
nvbb_reachable_by(struct nv_basic_block
*, struct nv_basic_block
*,
446 struct nv_basic_block
*);
447 struct nv_basic_block
*nvbb_dom_frontier(struct nv_basic_block
*);
448 int nvcg_replace_value(struct nv_pc
*pc
, struct nv_value
*old_val
,
449 struct nv_value
*new_val
);
451 typedef void (*nv_pc_pass_func
)(void *priv
, struct nv_basic_block
*b
);
453 void nv_pc_pass_in_order(struct nv_basic_block
*, nv_pc_pass_func
, void *);
455 int nv_pc_exec_pass0(struct nv_pc
*pc
);
456 int nv_pc_exec_pass1(struct nv_pc
*pc
);
457 int nv_pc_exec_pass2(struct nv_pc
*pc
);
459 int nv50_tgsi_to_nc(struct nv_pc
*, struct nv50_translation_info
*);
461 #endif // NV50_COMPILER_H