sync with tizen_2.2
[sdk/emulator/qemu.git] / gl / mesa / src / gallium / drivers / nv50 / nv50_pc.h
1 /*
2  * Copyright 2010 Christoph Bumiller
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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
20  * SOFTWARE.
21  */
22
23 #ifndef __NV50_COMPILER_H__
24 #define __NV50_COMPILER_H__
25
26 #include "nv50_debug.h"
27
28 #include "pipe/p_defines.h"
29 #include "util/u_inlines.h"
30 #include "util/u_memory.h"
31
32 #define NV_OP_PHI       0
33 #define NV_OP_EXTRACT   1
34 #define NV_OP_COMBINE   2
35 #define NV_OP_LDA       3
36 #define NV_OP_STA       4
37 #define NV_OP_MOV       5
38 #define NV_OP_ADD       6
39 #define NV_OP_SUB       7
40 #define NV_OP_NEG       8
41 #define NV_OP_MUL       9
42 #define NV_OP_MAD       10
43 #define NV_OP_CVT       11
44 #define NV_OP_SAT       12
45 #define NV_OP_NOT       13
46 #define NV_OP_AND       14
47 #define NV_OP_OR        15
48 #define NV_OP_XOR       16
49 #define NV_OP_SHL       17
50 #define NV_OP_SHR       18
51 #define NV_OP_RCP       19
52 #define NV_OP_UNDEF     20
53 #define NV_OP_RSQ       21
54 #define NV_OP_LG2       22
55 #define NV_OP_SIN       23
56 #define NV_OP_COS       24
57 #define NV_OP_EX2       25
58 #define NV_OP_PRESIN    26
59 #define NV_OP_PREEX2    27
60 #define NV_OP_MIN       28
61 #define NV_OP_MAX       29
62 #define NV_OP_SET       30
63 #define NV_OP_SAD       31
64 #define NV_OP_KIL       32
65 #define NV_OP_BRA       33
66 #define NV_OP_CALL      34
67 #define NV_OP_RET       35
68 #define NV_OP_BREAK     36
69 #define NV_OP_BREAKADDR 37
70 #define NV_OP_JOINAT    38
71 #define NV_OP_TEX       39
72 #define NV_OP_TXB       40
73 #define NV_OP_TXL       41
74 #define NV_OP_TXF       42
75 #define NV_OP_TXQ       43
76 #define NV_OP_DFDX      44
77 #define NV_OP_DFDY      45
78 #define NV_OP_QUADOP    46
79 #define NV_OP_LINTERP   47
80 #define NV_OP_PINTERP   48
81 #define NV_OP_ABS       49
82 #define NV_OP_CEIL      50
83 #define NV_OP_FLOOR     51
84 #define NV_OP_TRUNC     52
85 #define NV_OP_NOP       53
86 #define NV_OP_SELECT    54
87 #define NV_OP_EXPORT    55
88 #define NV_OP_JOIN      56
89 #define NV_OP_ROUND     57
90 #define NV_OP_COUNT     58
91
92 #define NV_FILE_GPR      0
93 #define NV_FILE_OUT      1
94 #define NV_FILE_ADDR     2
95 #define NV_FILE_FLAGS    3
96 #define NV_FILE_IMM      16
97 #define NV_FILE_MEM_S    32
98 #define NV_FILE_MEM_P    33
99 #define NV_FILE_MEM_V    34
100 #define NV_FILE_MEM_L    48
101 #define NV_FILE_MEM_G(i) (64 + i)
102 #define NV_FILE_MEM_C(i) (80 + i)
103
104 #define NV_MOD_NEG 1
105 #define NV_MOD_ABS 2
106 #define NV_MOD_NOT 4
107 #define NV_MOD_SAT 8
108
109 #define NV_TYPE_U8  0x00
110 #define NV_TYPE_S8  0x01
111 #define NV_TYPE_U16 0x02
112 #define NV_TYPE_S16 0x03
113 #define NV_TYPE_U32 0x04
114 #define NV_TYPE_S32 0x05
115 #define NV_TYPE_P32 0x07
116 #define NV_TYPE_F32 0x09
117 #define NV_TYPE_F64 0x0b
118 #define NV_TYPE_VEC(x, n) (NV_TYPE_##x | (n << 4))
119 #define NV_TYPE_LO  0x00
120 #define NV_TYPE_HI  0x80
121 #define NV_TYPE_ANY 0xff
122
123 #define NV_TYPE_ISINT(t) ((t) <= 5)
124 #define NV_TYPE_ISFLT(t) ((t) & 0x08)
125
126 /* $cX registers contain 4 bits: OCSZ (Z is bit 0) */
127 #define NV_CC_FL 0x0
128 #define NV_CC_LT 0x1
129 #define NV_CC_EQ 0x2
130 #define NV_CC_LE 0x3
131 #define NV_CC_GT 0x4
132 #define NV_CC_NE 0x5
133 #define NV_CC_GE 0x6
134 #define NV_CC_U  0x8
135 #define NV_CC_TR 0xf
136 #define NV_CC_O  0x10
137 #define NV_CC_C  0x11
138 #define NV_CC_A  0x12
139 #define NV_CC_S  0x13
140
141 #define NV_PC_MAX_INSTRUCTIONS 2048
142 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
143
144 #define NV_PC_MAX_BASIC_BLOCKS 1024
145
146 static INLINE boolean
147 nv_is_vector_op(uint opcode)
148 {
149    return (opcode >= NV_OP_TEX) && (opcode <= NV_OP_TXQ);
150 }
151
152 static INLINE uint
153 nv_type_order(ubyte type)
154 {
155    switch (type & 0xf) {
156    case NV_TYPE_U8:
157    case NV_TYPE_S8:
158       return 0;
159    case NV_TYPE_U16:
160    case NV_TYPE_S16:
161       return 1;
162    case NV_TYPE_U32:
163    case NV_TYPE_F32:
164    case NV_TYPE_S32:
165    case NV_TYPE_P32:
166       return 2;
167    case NV_TYPE_F64:
168       return 3;
169    }
170    assert(0);
171    return 0;
172 }
173
174 static INLINE uint
175 nv_type_sizeof(ubyte type)
176 {
177    if (type & 0xf0)
178       return (1 << nv_type_order(type)) * (type >> 4);
179    return 1 << nv_type_order(type);
180 }
181
182 static INLINE uint
183 nv_type_sizeof_base(ubyte type)
184 {
185    return 1 << nv_type_order(type);
186 }
187
188 struct nv_reg {
189    int id;
190    ubyte file;
191    ubyte type; /* type of generating instruction's result */
192    ubyte as_type; /* default type for new references to this value */
193    union {
194       float f32;
195       double f64;
196       int32_t s32;
197       uint32_t u32;
198    } imm;
199 };
200
201 struct nv_range {
202    struct nv_range *next;
203    int bgn;
204    int end;
205 };
206
207 struct nv_value {
208    struct nv_reg reg; 
209    struct nv_instruction *insn;
210    struct nv_value *join;
211    int n;
212    struct nv_range *livei;
213    int refc;
214
215    struct nv_value *next;
216    struct nv_value *prev;
217 };
218
219 struct nv_ref {
220    struct nv_value *value;
221    ubyte mod;
222    ubyte typecast;
223    ubyte flags; /* not used yet */
224 };
225
226 #define NV_REF_FLAG_REGALLOC_PRIV (1 << 0)
227
228 struct nv_basic_block;
229
230 struct nv_instruction {
231    struct nv_instruction *next;
232    struct nv_instruction *prev;
233    uint opcode;
234    int serial;
235    struct nv_value *def[4];
236    struct nv_value *flags_def;
237    struct nv_ref *src[5];
238    struct nv_ref *flags_src;
239    struct nv_basic_block *bb;
240    struct nv_basic_block *target; /* target block of control flow insn */
241    ubyte cc;
242    unsigned set_cond      : 4;
243    unsigned fixed         : 1; /* don't optimize away */
244    unsigned is_terminator : 1;
245    unsigned is_join       : 1;
246    unsigned is_long       : 1; /* for emission */
247    /* */
248    unsigned saturate : 1;
249    unsigned centroid : 1;
250    unsigned flat     : 1;
251    unsigned lanes    : 4;
252    unsigned tex_live : 1;
253    /* */
254    ubyte tex_t; /* TIC binding */
255    ubyte tex_s; /* TSC binding */
256    unsigned tex_argc : 3;
257    unsigned tex_cube : 1;
258    unsigned tex_mask : 4;
259    /* */
260    ubyte quadop;
261 };
262
263 static INLINE int
264 nvi_vector_size(struct nv_instruction *nvi)
265 {
266    int i;
267    assert(nvi);
268    for (i = 0; i < 4 && nvi->def[i]; ++i);
269    return i;
270 }
271
272 #define CFG_EDGE_FORWARD     0
273 #define CFG_EDGE_BACK        1
274 #define CFG_EDGE_LOOP_ENTER  2
275 #define CFG_EDGE_LOOP_LEAVE  4
276 #define CFG_EDGE_FAKE        8
277
278 /* 'WALL' edge means where reachability check doesn't follow */
279 /* 'LOOP' edge means just having to do with loops */
280 #define IS_LOOP_EDGE(k) ((k) & 7)
281 #define IS_WALL_EDGE(k) ((k) & 9)
282
283 struct nv_basic_block {
284    struct nv_instruction *entry; /* first non-phi instruction */
285    struct nv_instruction *exit;
286    struct nv_instruction *phi; /* very first instruction */
287    int num_instructions;
288
289    struct nv_basic_block *out[2]; /* no indirect branches -> 2 */
290    struct nv_basic_block *in[8]; /* hope that suffices */
291    uint num_in;
292    ubyte out_kind[2];
293    ubyte in_kind[8];
294
295    int id;
296    int subroutine;
297    uint priv; /* reset to 0 after you're done */
298    uint pass_seq;
299
300    uint32_t bin_pos; /* position, size in emitted code */
301    uint32_t bin_size;
302
303    uint32_t live_set[NV_PC_MAX_VALUES / 32];
304 };
305
306 struct nv50_translation_info;
307
308 struct nv_pc {
309    struct nv_basic_block **root;
310    struct nv_basic_block *current_block;
311    struct nv_basic_block *parent_block;
312
313    int loop_nesting_bound;
314    uint pass_seq;
315
316    struct nv_value values[NV_PC_MAX_VALUES];
317    struct nv_instruction instructions[NV_PC_MAX_INSTRUCTIONS];
318    struct nv_ref **refs;
319    struct nv_basic_block *bb_list[NV_PC_MAX_BASIC_BLOCKS];
320    int num_values;
321    int num_instructions;
322    int num_refs;
323    int num_blocks;
324    int num_subroutines;
325
326    int max_reg[4];
327
328    uint32_t *immd_buf; /* populated on emit */
329    unsigned immd_count;
330
331    uint32_t *emit;
332    unsigned bin_size;
333    unsigned bin_pos;
334
335    void *fixups;
336    unsigned num_fixups;
337
338    /* optimization enables */
339    boolean opt_reload_elim;
340 };
341
342 void nvbb_insert_tail(struct nv_basic_block *, struct nv_instruction *);
343 void nvi_insert_after(struct nv_instruction *, struct nv_instruction *);
344
345 static INLINE struct nv_instruction *
346 nv_alloc_instruction(struct nv_pc *pc, uint opcode)
347 {
348    struct nv_instruction *insn;
349
350    insn = &pc->instructions[pc->num_instructions++];
351    assert(pc->num_instructions < NV_PC_MAX_INSTRUCTIONS);
352
353    insn->cc = NV_CC_TR;
354    insn->opcode = opcode;
355
356    return insn;
357 }
358
359 static INLINE struct nv_instruction *
360 new_instruction(struct nv_pc *pc, uint opcode)
361 {
362    struct nv_instruction *insn = nv_alloc_instruction(pc, opcode);
363
364    nvbb_insert_tail(pc->current_block, insn);
365    return insn;
366 }
367
368 static INLINE struct nv_instruction *
369 new_instruction_at(struct nv_pc *pc, struct nv_instruction *at, uint opcode)
370 {
371    struct nv_instruction *insn = nv_alloc_instruction(pc, opcode);
372
373    nvi_insert_after(at, insn);
374    return insn;
375 }
376
377 static INLINE struct nv_value *
378 new_value(struct nv_pc *pc, ubyte file, ubyte type)
379 {
380    struct nv_value *value = &pc->values[pc->num_values];
381
382    assert(pc->num_values < NV_PC_MAX_VALUES - 1);
383
384    value->n = pc->num_values++;
385    value->join = value;
386    value->reg.id = -1;
387    value->reg.file = file;
388    value->reg.type = value->reg.as_type = type;
389    return value;
390 }
391
392 static INLINE struct nv_value *
393 new_value_like(struct nv_pc *pc, struct nv_value *like)
394 {
395    struct nv_value *val = new_value(pc, like->reg.file, like->reg.type);
396    val->reg.as_type = like->reg.as_type;
397    return val;
398 }
399
400 static INLINE struct nv_ref *
401 new_ref(struct nv_pc *pc, struct nv_value *val)
402 {
403    int i;
404    struct nv_ref *ref;
405
406    if ((pc->num_refs % 64) == 0) {
407       const unsigned old_size = pc->num_refs * sizeof(struct nv_ref *);
408       const unsigned new_size = (pc->num_refs + 64) * sizeof(struct nv_ref *);
409
410       pc->refs = REALLOC(pc->refs, old_size, new_size);
411
412       ref = CALLOC(64, sizeof(struct nv_ref));
413       for (i = 0; i < 64; ++i)
414          pc->refs[pc->num_refs + i] = &ref[i];
415    }
416
417    ref = pc->refs[pc->num_refs++];
418    ref->value = val;
419    ref->typecast = val->reg.as_type;
420
421    ++val->refc;
422    return ref;
423 }
424
425 static INLINE struct nv_basic_block *
426 new_basic_block(struct nv_pc *pc)
427 {
428    struct nv_basic_block *bb;
429
430    if (pc->num_blocks >= NV_PC_MAX_BASIC_BLOCKS)
431       return NULL;
432
433    bb = CALLOC_STRUCT(nv_basic_block);
434
435    bb->id = pc->num_blocks;
436    pc->bb_list[pc->num_blocks++] = bb;
437    return bb;
438 }
439
440 static INLINE void
441 nv_reference(struct nv_pc *pc, struct nv_ref **d, struct nv_value *s)
442 {
443    if (*d)
444       --(*d)->value->refc;
445
446    if (s) {
447       if (!*d)
448          *d = new_ref(pc, s);
449       else {
450          (*d)->value = s;
451          ++(s->refc);
452       }
453    } else {
454       *d = NULL;
455    }
456 }
457
458 /* nv50_emit.c */
459 void nv50_emit_instruction(struct nv_pc *, struct nv_instruction *);
460 unsigned nv50_inst_min_size(struct nv_instruction *);
461
462 /* nv50_print.c */
463 const char *nv_opcode_name(uint opcode);
464 void nv_print_instruction(struct nv_instruction *);
465
466 /* nv50_pc.c */
467
468 void nv_print_function(struct nv_basic_block *root);
469 void nv_print_program(struct nv_pc *);
470
471 boolean nv_op_commutative(uint opcode);
472 int nv50_indirect_opnd(struct nv_instruction *);
473 boolean nv50_nvi_can_use_imm(struct nv_instruction *, int s);
474 boolean nv50_nvi_can_predicate(struct nv_instruction *);
475 boolean nv50_nvi_can_load(struct nv_instruction *, int s, struct nv_value *);
476 boolean nv50_op_can_write_flags(uint opcode);
477 ubyte nv50_supported_src_mods(uint opcode, int s);
478 int nv_nvi_refcount(struct nv_instruction *);
479 void nv_nvi_delete(struct nv_instruction *);
480 void nv_nvi_permute(struct nv_instruction *, struct nv_instruction *);
481 void nvbb_attach_block(struct nv_basic_block *parent,
482                        struct nv_basic_block *, ubyte edge_kind);
483 boolean nvbb_dominated_by(struct nv_basic_block *, struct nv_basic_block *);
484 boolean nvbb_reachable_by(struct nv_basic_block *, struct nv_basic_block *,
485                           struct nv_basic_block *);
486 struct nv_basic_block *nvbb_dom_frontier(struct nv_basic_block *);
487 int nvcg_replace_value(struct nv_pc *pc, struct nv_value *old_val,
488                        struct nv_value *new_val);
489 struct nv_value *nvcg_find_immediate(struct nv_ref *);
490 struct nv_value *nvcg_find_constant(struct nv_ref *);
491
492 typedef void (*nv_pc_pass_func)(void *priv, struct nv_basic_block *b);
493
494 void nv_pc_pass_in_order(struct nv_basic_block *, nv_pc_pass_func, void *);
495
496 int nv_pc_exec_pass0(struct nv_pc *pc);
497 int nv_pc_exec_pass1(struct nv_pc *pc);
498 int nv_pc_exec_pass2(struct nv_pc *pc);
499
500 int nv50_tgsi_to_nc(struct nv_pc *, struct nv50_translation_info *);
501
502 #endif // NV50_COMPILER_H