1 /*************************************************************************/
2 /* Copyright (C) 2010 I */
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. */
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. */
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 /*************************************************************************/
18 #ifndef __NV50_COMPILER_H__
19 #define __NV50_COMPILER_H__
21 #include "pipe/p_defines.h"
22 #include "util/u_inlines.h"
23 #include "util/u_memory.h"
26 #define NV_OP_EXTRACT 1
27 #define NV_OP_COMBINE 2
51 #define NV_OP_PRESIN 26
52 #define NV_OP_PREEX2 27
61 #define NV_OP_BREAK 36
62 #define NV_OP_BREAKADDR 37
63 #define NV_OP_JOINAT 38
71 #define NV_OP_QUADOP 46
72 #define NV_OP_LINTERP 47
73 #define NV_OP_PINTERP 48
76 #define NV_OP_FLOOR 51
77 #define NV_OP_TRUNC 52
79 #define NV_OP_SELECT 54
80 #define NV_OP_EXPORT 55
81 #define NV_OP_COUNT 56
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)
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
114 #define NV_TYPE_ISINT(t) ((t) <= 5)
115 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
127 #define NV_PC_MAX_INSTRUCTIONS 2048
128 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
130 static INLINE boolean
131 nv_is_vector_op(uint opcode
)
133 return (opcode
>= NV_OP_TEX
) && (opcode
<= NV_OP_TXQ
);
137 nv_type_order(ubyte type
)
139 switch (type
& 0xf) {
158 nv_type_sizeof(ubyte type
)
161 return (1 << nv_type_order(type
)) * (type
>> 4);
162 return 1 << nv_type_order(type
);
166 nv_type_sizeof_base(ubyte type
)
168 return 1 << nv_type_order(type
);
174 ubyte type
; /* type of generating instruction's result */
184 struct nv_range
*next
;
191 struct nv_instruction
*insn
;
192 struct nv_value
*join
;
194 struct nv_range
*livei
;
197 struct nv_value
*next
;
198 struct nv_value
*prev
;
202 struct nv_value
*value
;
203 struct nv_instruction
*insn
;
206 ubyte flags
; /* not used yet */
209 struct nv_basic_block
;
211 struct nv_instruction
{
212 struct nv_instruction
*next
;
213 struct nv_instruction
*prev
;
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 */
224 ubyte fixed
: 1; /* don't optimize away */
225 ubyte is_terminator
: 1;
227 ubyte is_long
: 1; /* for emission */
235 ubyte tex_t
; /* TIC binding */
236 ubyte tex_s
; /* TSC binding */
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
;
250 struct nv_basic_block
*out
[2]; /* no indirect branches -> 2 */
251 struct nv_basic_block
**in
;
255 struct nv_basic_block
*last_visitor
;
259 uint32_t bin_pos
; /* position, size in emitted code */
262 uint32_t live_set
[NV_PC_MAX_VALUES
/ 32];
265 #define NV_FIXUP_CFLOW_RELOC 0
266 #define NV_FIXUP_PARAM_RELOC 1
277 nv_fixup_apply(uint32_t *bin
, struct nv_fixup
*fixup
, uint32_t data
)
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
;
288 struct nv50_translation_info
*ti
;
290 struct nv_basic_block
*root
;
291 struct nv_basic_block
*current_block
;
292 struct nv_basic_block
*parent_block
;
294 int loop_nesting_bound
;
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
;
302 int num_instructions
;
308 uint32_t *immd_buf
; /* populated on emit */
315 struct nv_fixup
*fixups
;
319 void nvbb_insert_tail(struct nv_basic_block
*, struct nv_instruction
*);
321 static INLINE
struct nv_instruction
*
322 new_instruction(struct nv_pc
*pc
, uint opcode
)
324 struct nv_instruction
*insn
;
326 insn
= &pc
->instructions
[pc
->num_instructions
++];
327 assert(pc
->num_instructions
< NV_PC_MAX_INSTRUCTIONS
);
330 insn
->opcode
= opcode
;
332 nvbb_insert_tail(pc
->current_block
, insn
);
336 static INLINE
struct nv_value
*
337 new_value(struct nv_pc
*pc
, ubyte file
, ubyte type
)
339 struct nv_value
*value
= &pc
->values
[pc
->num_values
];
341 assert(pc
->num_values
< NV_PC_MAX_VALUES
- 1);
343 value
->n
= pc
->num_values
++;
346 value
->reg
.file
= file
;
347 value
->reg
.type
= type
;
351 static INLINE
struct nv_ref
*
352 new_ref(struct nv_pc
*pc
, struct nv_value
*val
)
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
*);
361 pc
->refs
= REALLOC(pc
->refs
, old_size
, new_size
);
363 ref
= CALLOC(64, sizeof(struct nv_ref
));
364 for (i
= 0; i
< 64; ++i
)
365 pc
->refs
[pc
->num_refs
+ i
] = &ref
[i
];
368 ref
= pc
->refs
[pc
->num_refs
++];
370 ref
->typecast
= val
->reg
.type
;
376 static INLINE
struct nv_basic_block
*
377 new_basic_block(struct nv_pc
*pc
)
379 struct nv_basic_block
*bb
= CALLOC_STRUCT(nv_basic_block
);
381 bb
->in
= CALLOC(sizeof(struct nv_basic_block
*), 4);
382 bb
->id
= pc
->num_blocks
++;
387 nv_reference(struct nv_pc
*pc
, struct nv_ref
**d
, struct nv_value
*s
)
406 void nv50_emit_instruction(struct nv_pc
*, struct nv_instruction
*);
409 const char *nv_opcode_name(uint opcode
);
410 void nv_print_instruction(struct nv_instruction
*);
413 void nv_print_program(struct nv_basic_block
*b
);
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
*);
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
);
429 int nv50_tgsi_to_nc(struct nv_pc
*, struct nv50_translation_info
*);
431 #endif // NV50_COMPILER_H