r600g: initial support for geometry shaders on evergreen (v2)
[mesa.git] / src / gallium / drivers / r600 / sb / sb_bc.h
1 /*
2 * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Vadim Girlin
25 */
26
27 #ifndef SB_BC_H_
28 #define SB_BC_H_
29
30 extern "C" {
31 #include <stdint.h>
32 #include "r600_isa.h"
33 }
34
35 #include <cstdio>
36 #include <string>
37 #include <vector>
38 #include <stack>
39
40 struct r600_bytecode;
41 struct r600_shader;
42
43 namespace r600_sb {
44
45 class hw_encoding_format;
46 class node;
47 class alu_node;
48 class cf_node;
49 class fetch_node;
50 class alu_group_node;
51 class region_node;
52 class shader;
53
54 class sb_ostream {
55 public:
56 sb_ostream() {}
57
58 virtual void write(const char *s) = 0;
59
60 sb_ostream& operator <<(const char *s) {
61 write(s);
62 return *this;
63 }
64
65 sb_ostream& operator <<(const std::string& s) {
66 return *this << s.c_str();
67 }
68
69 sb_ostream& operator <<(void *p) {
70 char b[32];
71 sprintf(b, "%p", p);
72 return *this << b;
73 }
74
75 sb_ostream& operator <<(char c) {
76 char b[2];
77 sprintf(b, "%c", c);
78 return *this << b;
79 }
80
81 sb_ostream& operator <<(int n) {
82 char b[32];
83 sprintf(b, "%d", n);
84 return *this << b;
85 }
86
87 sb_ostream& operator <<(unsigned n) {
88 char b[32];
89 sprintf(b, "%u", n);
90 return *this << b;
91 }
92
93 sb_ostream& operator <<(double d) {
94 char b[32];
95 snprintf(b, 32, "%g", d);
96 return *this << b;
97 }
98
99 // print as field of specified width, right aligned
100 void print_w(int n, int width) {
101 char b[256],f[8];
102 sprintf(f, "%%%dd", width);
103 snprintf(b, 256, f, n);
104 write(b);
105 }
106
107 // print as field of specified width, left aligned
108 void print_wl(int n, int width) {
109 char b[256],f[8];
110 sprintf(f, "%%-%dd", width);
111 snprintf(b, 256, f, n);
112 write(b);
113 }
114
115 // print as field of specified width, left aligned
116 void print_wl(const std::string &s, int width) {
117 write(s.c_str());
118 int l = s.length();
119 while (l++ < width) {
120 write(" ");
121 }
122 }
123
124 // print int as field of specified width, right aligned, zero-padded
125 void print_zw(int n, int width) {
126 char b[256],f[8];
127 sprintf(f, "%%0%dd", width);
128 snprintf(b, 256, f, n);
129 write(b);
130 }
131
132 // print int as field of specified width, right aligned, zero-padded, hex
133 void print_zw_hex(int n, int width) {
134 char b[256],f[8];
135 sprintf(f, "%%0%dx", width);
136 snprintf(b, 256, f, n);
137 write(b);
138 }
139 };
140
141 class sb_ostringstream : public sb_ostream {
142 std::string data;
143 public:
144 sb_ostringstream() : data() {}
145
146 virtual void write(const char *s) {
147 data += s;
148 }
149
150 void clear() { data.clear(); }
151
152 const char* c_str() { return data.c_str(); }
153 std::string& str() { return data; }
154 };
155
156 class sb_log : public sb_ostream {
157 FILE *o;
158 public:
159 sb_log() : o(stderr) {}
160
161 virtual void write(const char *s) {
162 fputs(s, o);
163 }
164 };
165
166 extern sb_log sblog;
167
168 enum shader_target
169 {
170 TARGET_UNKNOWN,
171 TARGET_VS,
172 TARGET_ES,
173 TARGET_PS,
174 TARGET_GS,
175 TARGET_GS_COPY,
176 TARGET_COMPUTE,
177 TARGET_FETCH,
178
179 TARGET_NUM
180 };
181
182 enum sb_hw_class_bits
183 {
184 HB_R6 = (1<<0),
185 HB_R7 = (1<<1),
186 HB_EG = (1<<2),
187 HB_CM = (1<<3),
188
189 HB_R6R7 = (HB_R6 | HB_R7),
190 HB_EGCM = (HB_EG | HB_CM),
191 HB_R6R7EG = (HB_R6 | HB_R7 | HB_EG),
192 HB_R7EGCM = (HB_R7 | HB_EG | HB_CM),
193
194 HB_ALL = (HB_R6 | HB_R7 | HB_EG | HB_CM)
195 };
196
197 enum sb_hw_chip
198 {
199 HW_CHIP_UNKNOWN,
200 HW_CHIP_R600,
201 HW_CHIP_RV610,
202 HW_CHIP_RV630,
203 HW_CHIP_RV670,
204 HW_CHIP_RV620,
205 HW_CHIP_RV635,
206 HW_CHIP_RS780,
207 HW_CHIP_RS880,
208 HW_CHIP_RV770,
209 HW_CHIP_RV730,
210 HW_CHIP_RV710,
211 HW_CHIP_RV740,
212 HW_CHIP_CEDAR,
213 HW_CHIP_REDWOOD,
214 HW_CHIP_JUNIPER,
215 HW_CHIP_CYPRESS,
216 HW_CHIP_HEMLOCK,
217 HW_CHIP_PALM,
218 HW_CHIP_SUMO,
219 HW_CHIP_SUMO2,
220 HW_CHIP_BARTS,
221 HW_CHIP_TURKS,
222 HW_CHIP_CAICOS,
223 HW_CHIP_CAYMAN,
224 HW_CHIP_ARUBA
225 };
226
227 enum sb_hw_class
228 {
229 HW_CLASS_UNKNOWN,
230 HW_CLASS_R600,
231 HW_CLASS_R700,
232 HW_CLASS_EVERGREEN,
233 HW_CLASS_CAYMAN
234 };
235
236 enum alu_slots {
237 SLOT_X = 0,
238 SLOT_Y = 1,
239 SLOT_Z = 2,
240 SLOT_W = 3,
241 SLOT_TRANS = 4
242 };
243
244 enum misc_consts {
245 MAX_ALU_LITERALS = 4,
246 MAX_ALU_SLOTS = 128,
247 MAX_GPR = 128,
248 MAX_CHAN = 4
249
250 };
251
252 enum alu_src_sel {
253
254 ALU_SRC_LDS_OQ_A = 219,
255 ALU_SRC_LDS_OQ_B = 220,
256 ALU_SRC_LDS_OQ_A_POP = 221,
257 ALU_SRC_LDS_OQ_B_POP = 222,
258 ALU_SRC_LDS_DIRECT_A = 223,
259 ALU_SRC_LDS_DIRECT_B = 224,
260 ALU_SRC_TIME_HI = 227,
261 ALU_SRC_TIME_LO = 228,
262 ALU_SRC_MASK_HI = 229,
263 ALU_SRC_MASK_LO = 230,
264 ALU_SRC_HW_WAVE_ID = 231,
265 ALU_SRC_SIMD_ID = 232,
266 ALU_SRC_SE_ID = 233,
267 ALU_SRC_HW_THREADGRP_ID = 234,
268 ALU_SRC_WAVE_ID_IN_GRP = 235,
269 ALU_SRC_NUM_THREADGRP_WAVES = 236,
270 ALU_SRC_HW_ALU_ODD = 237,
271 ALU_SRC_LOOP_IDX = 238,
272 ALU_SRC_PARAM_BASE_ADDR = 240,
273 ALU_SRC_NEW_PRIM_MASK = 241,
274 ALU_SRC_PRIM_MASK_HI = 242,
275 ALU_SRC_PRIM_MASK_LO = 243,
276 ALU_SRC_1_DBL_L = 244,
277 ALU_SRC_1_DBL_M = 245,
278 ALU_SRC_0_5_DBL_L = 246,
279 ALU_SRC_0_5_DBL_M = 247,
280 ALU_SRC_0 = 248,
281 ALU_SRC_1 = 249,
282 ALU_SRC_1_INT = 250,
283 ALU_SRC_M_1_INT = 251,
284 ALU_SRC_0_5 = 252,
285 ALU_SRC_LITERAL = 253,
286 ALU_SRC_PV = 254,
287 ALU_SRC_PS = 255,
288
289 ALU_SRC_PARAM_OFFSET = 448
290 };
291
292 enum alu_predicate_select
293 {
294 PRED_SEL_OFF = 0,
295 // RESERVED = 1,
296 PRED_SEL_0 = 2,
297 PRED_SEL_1 = 3
298 };
299
300
301 enum alu_omod {
302 OMOD_OFF = 0,
303 OMOD_M2 = 1,
304 OMOD_M4 = 2,
305 OMOD_D2 = 3
306 };
307
308 enum alu_index_mode {
309 INDEX_AR_X = 0,
310 INDEX_AR_Y_R600 = 1,
311 INDEX_AR_Z_R600 = 2,
312 INDEX_AR_W_R600 = 3,
313
314 INDEX_LOOP = 4,
315 INDEX_GLOBAL = 5,
316 INDEX_GLOBAL_AR_X = 6
317 };
318
319 enum alu_cayman_mova_dst {
320 CM_MOVADST_AR_X,
321 CM_MOVADST_PC,
322 CM_MOVADST_IDX0,
323 CM_MOVADST_IDX1,
324 CM_MOVADST_CG0, // clause-global byte 0
325 CM_MOVADST_CG1,
326 CM_MOVADST_CG2,
327 CM_MOVADST_CG3
328 };
329
330 enum alu_cayman_exec_mask_op {
331 CM_EMO_DEACTIVATE,
332 CM_EMO_BREAK,
333 CM_EMO_CONTINUE,
334 CM_EMO_KILL
335 };
336
337
338 enum cf_exp_type {
339 EXP_PIXEL,
340 EXP_POS,
341 EXP_PARAM,
342
343 EXP_TYPE_COUNT
344 };
345
346 enum cf_mem_type {
347 MEM_WRITE,
348 MEM_WRITE_IND,
349 MEM_WRITE_ACK,
350 MEM_WRITE_IND_ACK
351 };
352
353
354 enum alu_kcache_mode {
355 KC_LOCK_NONE,
356 KC_LOCK_1,
357 KC_LOCK_2,
358 KC_LOCK_LOOP
359 };
360
361 enum alu_kcache_index_mode {
362 KC_INDEX_NONE,
363 KC_INDEX_0,
364 KC_INDEX_1,
365 KC_INDEX_INVALID
366 };
367
368 enum chan_select {
369 SEL_X = 0,
370 SEL_Y = 1,
371 SEL_Z = 2,
372 SEL_W = 3,
373 SEL_0 = 4,
374 SEL_1 = 5,
375 // RESERVED = 6,
376 SEL_MASK = 7
377 };
378
379 enum bank_swizzle {
380 VEC_012 = 0,
381 VEC_021 = 1,
382 VEC_120 = 2,
383 VEC_102 = 3,
384 VEC_201 = 4,
385 VEC_210 = 5,
386
387 VEC_NUM = 6,
388
389 SCL_210 = 0,
390 SCL_122 = 1,
391 SCL_212 = 2,
392 SCL_221 = 3,
393
394 SCL_NUM = 4
395
396 };
397
398 enum sched_queue_id {
399 SQ_CF,
400 SQ_ALU,
401 SQ_TEX,
402 SQ_VTX,
403
404 SQ_NUM
405 };
406
407 struct literal {
408 union {
409 int32_t i;
410 uint32_t u;
411 float f;
412 };
413
414 literal(int32_t i = 0) : i(i) {}
415 literal(uint32_t u) : u(u) {}
416 literal(float f) : f(f) {}
417 literal(double f) : f(f) {}
418 operator uint32_t() const { return u; }
419 bool operator ==(literal l) { return u == l.u; }
420 bool operator ==(int v_int) { return i == v_int; }
421 bool operator ==(unsigned v_uns) { return u == v_uns; }
422 };
423
424 struct bc_kcache {
425 unsigned mode;
426 unsigned bank;
427 unsigned addr;
428 unsigned index_mode;
429 } ;
430
431 // TODO optimize bc structures
432
433 struct bc_cf {
434
435 bc_kcache kc[4];
436
437 unsigned id;
438
439
440 const cf_op_info * op_ptr;
441 unsigned op;
442
443 unsigned addr:32;
444
445 unsigned alt_const:1;
446 unsigned uses_waterfall:1;
447
448 unsigned barrier:1;
449 unsigned count:7;
450 unsigned pop_count:3;
451 unsigned call_count:6;
452 unsigned whole_quad_mode:1;
453 unsigned valid_pixel_mode:1;
454
455 unsigned jumptable_sel:3;
456 unsigned cf_const:5;
457 unsigned cond:2;
458 unsigned end_of_program:1;
459
460 unsigned array_base:13;
461 unsigned elem_size:2;
462 unsigned index_gpr:7;
463 unsigned rw_gpr:7;
464 unsigned rw_rel:1;
465 unsigned type:2;
466
467 unsigned burst_count:4;
468 unsigned mark:1;
469 unsigned sel[4];
470
471 unsigned array_size:12;
472 unsigned comp_mask:4;
473
474 unsigned rat_id:4;
475 unsigned rat_inst:6;
476 unsigned rat_index_mode:2;
477
478 void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_cf(op); }
479
480 bool is_alu_extended() {
481 assert(op_ptr->flags & CF_ALU);
482 return kc[2].mode != KC_LOCK_NONE || kc[3].mode != KC_LOCK_NONE;
483 }
484
485 };
486
487 struct bc_alu_src {
488 unsigned sel:9;
489 unsigned chan:2;
490 unsigned neg:1;
491 unsigned abs:1;
492 unsigned rel:1;
493 literal value;
494 };
495
496 struct bc_alu {
497 const alu_op_info * op_ptr;
498 unsigned op;
499
500 bc_alu_src src[3];
501
502 unsigned dst_gpr:7;
503 unsigned dst_chan:2;
504 unsigned dst_rel:1;
505 unsigned clamp:1;
506 unsigned omod:2;
507 unsigned bank_swizzle:3;
508
509 unsigned index_mode:3;
510 unsigned last:1;
511 unsigned pred_sel:2;
512
513 unsigned fog_merge:1;
514 unsigned write_mask:1;
515 unsigned update_exec_mask:1;
516 unsigned update_pred:1;
517
518 unsigned slot:3;
519
520 alu_op_flags slot_flags;
521
522 void set_op(unsigned op) {
523 this->op = op;
524 op_ptr = r600_isa_alu(op);
525 }
526 };
527
528 struct bc_fetch {
529 const fetch_op_info * op_ptr;
530 unsigned op;
531
532 unsigned bc_frac_mode:1;
533 unsigned fetch_whole_quad:1;
534 unsigned resource_id:8;
535
536 unsigned src_gpr:7;
537 unsigned src_rel:1;
538 unsigned src_sel[4];
539
540 unsigned dst_gpr:7;
541 unsigned dst_rel:1;
542 unsigned dst_sel[4];
543
544 unsigned alt_const:1;
545
546 unsigned inst_mod:2;
547 unsigned resource_index_mode:2;
548 unsigned sampler_index_mode:2;
549
550 unsigned coord_type[4];
551 unsigned lod_bias:7;
552
553 unsigned offset[3];
554
555 unsigned sampler_id:5;
556
557
558 unsigned fetch_type:2;
559 unsigned mega_fetch_count:6;
560 unsigned coalesced_read:1;
561 unsigned structured_read:2;
562 unsigned lds_req:1;
563
564 unsigned data_format:6;
565 unsigned format_comp_all:1;
566 unsigned num_format_all:2;
567 unsigned semantic_id:8;
568 unsigned srf_mode_all:1;
569 unsigned use_const_fields:1;
570
571 unsigned const_buf_no_stride:1;
572 unsigned endian_swap:2;
573 unsigned mega_fetch:1;
574
575 void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_fetch(op); }
576 };
577
578 struct shader_stats {
579 unsigned ndw;
580 unsigned ngpr;
581 unsigned nstack;
582
583 unsigned cf; // clause instructions not included
584 unsigned alu;
585 unsigned alu_clauses;
586 unsigned fetch_clauses;
587 unsigned fetch;
588 unsigned alu_groups;
589
590 unsigned shaders; // number of shaders (for accumulated stats)
591
592 shader_stats() : ndw(), ngpr(), nstack(), cf(), alu(), alu_clauses(),
593 fetch_clauses(), fetch(), alu_groups(), shaders() {}
594
595 void collect(node *n);
596 void accumulate(shader_stats &s);
597 void dump();
598 void dump_diff(shader_stats &s);
599 };
600
601 class sb_context {
602
603 public:
604
605 shader_stats src_stats, opt_stats;
606
607 r600_isa *isa;
608
609 sb_hw_chip hw_chip;
610 sb_hw_class hw_class;
611
612 unsigned alu_temp_gprs;
613 unsigned max_fetch;
614 bool has_trans;
615 unsigned vtx_src_num;
616 unsigned num_slots;
617 bool uses_mova_gpr;
618
619 bool stack_workaround_8xx;
620 bool stack_workaround_9xx;
621
622 unsigned wavefront_size;
623 unsigned stack_entry_size;
624
625 static unsigned dump_pass;
626 static unsigned dump_stat;
627
628 static unsigned dry_run;
629 static unsigned no_fallback;
630 static unsigned safe_math;
631
632 static unsigned dskip_start;
633 static unsigned dskip_end;
634 static unsigned dskip_mode;
635
636 sb_context() : src_stats(), opt_stats(), isa(0),
637 hw_chip(HW_CHIP_UNKNOWN), hw_class(HW_CLASS_UNKNOWN) {}
638
639 int init(r600_isa *isa, sb_hw_chip chip, sb_hw_class cclass);
640
641 bool is_r600() {return hw_class == HW_CLASS_R600;}
642 bool is_r700() {return hw_class == HW_CLASS_R700;}
643 bool is_evergreen() {return hw_class == HW_CLASS_EVERGREEN;}
644 bool is_cayman() {return hw_class == HW_CLASS_CAYMAN;}
645 bool is_egcm() {return hw_class >= HW_CLASS_EVERGREEN;}
646
647 bool needs_8xx_stack_workaround() {
648 if (!is_evergreen())
649 return false;
650
651 switch (hw_chip) {
652 case HW_CHIP_CYPRESS:
653 case HW_CHIP_JUNIPER:
654 return false;
655 default:
656 return true;
657 }
658 }
659
660 bool needs_9xx_stack_workaround() {
661 return is_cayman();
662 }
663
664 sb_hw_class_bits hw_class_bit() {
665 switch (hw_class) {
666 case HW_CLASS_R600:return HB_R6;
667 case HW_CLASS_R700:return HB_R7;
668 case HW_CLASS_EVERGREEN:return HB_EG;
669 case HW_CLASS_CAYMAN:return HB_CM;
670 default: assert(!"unknown hw class"); return (sb_hw_class_bits)0;
671
672 }
673 }
674
675 unsigned cf_opcode(unsigned op) {
676 return r600_isa_cf_opcode(isa->hw_class, op);
677 }
678
679 unsigned alu_opcode(unsigned op) {
680 return r600_isa_alu_opcode(isa->hw_class, op);
681 }
682
683 unsigned alu_slots(unsigned op) {
684 return r600_isa_alu_slots(isa->hw_class, op);
685 }
686
687 unsigned alu_slots(const alu_op_info * op_ptr) {
688 return op_ptr->slots[isa->hw_class];
689 }
690
691 unsigned alu_slots_mask(const alu_op_info * op_ptr) {
692 unsigned mask = 0;
693 unsigned slot_flags = alu_slots(op_ptr);
694 if (slot_flags & AF_V)
695 mask = 0x0F;
696 if (!is_cayman() && (slot_flags & AF_S))
697 mask |= 0x10;
698 return mask;
699 }
700
701 unsigned fetch_opcode(unsigned op) {
702 return r600_isa_fetch_opcode(isa->hw_class, op);
703 }
704
705 bool is_kcache_sel(unsigned sel) {
706 return ((sel >= 128 && sel < 192) || (sel >= 256 && sel < 320));
707 }
708
709 const char * get_hw_class_name();
710 const char * get_hw_chip_name();
711
712 };
713
714 #define SB_DUMP_STAT(a) do { if (sb_context::dump_stat) { a } } while (0)
715 #define SB_DUMP_PASS(a) do { if (sb_context::dump_pass) { a } } while (0)
716
717 class bc_decoder {
718
719 sb_context &ctx;
720
721 uint32_t* dw;
722 unsigned ndw;
723
724 public:
725
726 bc_decoder(sb_context &sctx, uint32_t *data, unsigned size)
727 : ctx(sctx), dw(data), ndw(size) {}
728
729 int decode_cf(unsigned &i, bc_cf &bc);
730 int decode_alu(unsigned &i, bc_alu &bc);
731 int decode_fetch(unsigned &i, bc_fetch &bc);
732
733 private:
734 int decode_cf_alu(unsigned &i, bc_cf &bc);
735 int decode_cf_exp(unsigned &i, bc_cf &bc);
736 int decode_cf_mem(unsigned &i, bc_cf &bc);
737
738 int decode_fetch_vtx(unsigned &i, bc_fetch &bc);
739 };
740
741 // bytecode format definition
742
743 class hw_encoding_format {
744 const sb_hw_class_bits hw_target; //FIXME: debug - remove after testing
745 hw_encoding_format();
746 protected:
747 uint32_t value;
748 public:
749 hw_encoding_format(sb_hw_class_bits hw)
750 : hw_target(hw), value(0) {}
751 hw_encoding_format(uint32_t v, sb_hw_class_bits hw)
752 : hw_target(hw), value(v) {}
753 uint32_t get_value(sb_hw_class_bits hw) const {
754 assert((hw & hw_target) == hw);
755 return value;
756 }
757 };
758
759 #define BC_FORMAT_BEGIN_HW(fmt, hwset) \
760 class fmt##_##hwset : public hw_encoding_format {\
761 typedef fmt##_##hwset thistype; \
762 public: \
763 fmt##_##hwset() : hw_encoding_format(HB_##hwset) {}; \
764 fmt##_##hwset(uint32_t v) : hw_encoding_format(v, HB_##hwset) {};
765
766 #define BC_FORMAT_BEGIN(fmt) BC_FORMAT_BEGIN_HW(fmt, ALL)
767
768 #define BC_FORMAT_END(fmt) };
769
770 // bytecode format field definition
771
772 #define BC_FIELD(fmt, name, shortname, last_bit, first_bit) \
773 thistype & name(unsigned v) { \
774 value |= ((v&((1ull<<((last_bit)-(first_bit)+1))-1))<<(first_bit)); \
775 return *this; \
776 } \
777 unsigned get_##name() const { \
778 return (value>>(first_bit))&((1ull<<((last_bit)-(first_bit)+1))-1); \
779 } \
780
781 #define BC_RSRVD(fmt, last_bit, first_bit)
782
783 // CLAMP macro defined elsewhere interferes with bytecode field name
784 #undef CLAMP
785
786 #include "sb_bc_fmt_def.inc"
787
788 #undef BC_FORMAT_BEGIN
789 #undef BC_FORMAT_END
790 #undef BC_FIELD
791 #undef BC_RSRVD
792
793 class bc_parser {
794 sb_context & ctx;
795
796 bc_decoder *dec;
797
798 r600_bytecode *bc;
799 r600_shader *pshader;
800
801 uint32_t *dw;
802 unsigned bc_ndw;
803
804 unsigned max_cf;
805
806 shader *sh;
807
808 int error;
809
810 alu_node *slots[2][5];
811 unsigned cgroup;
812
813 typedef std::vector<cf_node*> id_cf_map;
814 id_cf_map cf_map;
815
816 typedef std::stack<region_node*> region_stack;
817 region_stack loop_stack;
818
819 bool gpr_reladdr;
820
821 public:
822
823 bc_parser(sb_context &sctx, r600_bytecode *bc, r600_shader* pshader) :
824 ctx(sctx), dec(), bc(bc), pshader(pshader),
825 dw(), bc_ndw(), max_cf(),
826 sh(), error(), slots(), cgroup(),
827 cf_map(), loop_stack(), gpr_reladdr() { }
828
829 int decode();
830 int prepare();
831
832 shader* get_shader() { assert(!error); return sh; }
833
834 private:
835
836 int decode_shader();
837
838 int parse_decls();
839
840 int decode_cf(unsigned &i, bool &eop);
841
842 int decode_alu_clause(cf_node *cf);
843 int decode_alu_group(cf_node* cf, unsigned &i, unsigned &gcnt);
844
845 int decode_fetch_clause(cf_node *cf);
846
847 int prepare_ir();
848 int prepare_alu_clause(cf_node *cf);
849 int prepare_alu_group(cf_node* cf, alu_group_node *g);
850 int prepare_fetch_clause(cf_node *cf);
851
852 int prepare_loop(cf_node *c);
853 int prepare_if(cf_node *c);
854
855 };
856
857
858
859
860 class bytecode {
861 typedef std::vector<uint32_t> bc_vector;
862 sb_hw_class_bits hw_class_bit;
863
864 bc_vector bc;
865
866 unsigned pos;
867
868 public:
869
870 bytecode(sb_hw_class_bits hw, unsigned rdw = 256)
871 : hw_class_bit(hw), pos(0) { bc.reserve(rdw); }
872
873 unsigned ndw() { return bc.size(); }
874
875 void write_data(uint32_t* dst) {
876 std::copy(bc.begin(), bc.end(), dst);
877 }
878
879 void align(unsigned a) {
880 unsigned size = bc.size();
881 size = (size + a - 1) & ~(a-1);
882 bc.resize(size);
883 }
884
885 void set_size(unsigned sz) {
886 assert(sz >= bc.size());
887 bc.resize(sz);
888 }
889
890 void seek(unsigned p) {
891 if (p != pos) {
892 if (p > bc.size()) {
893 bc.resize(p);
894 }
895 pos = p;
896 }
897 }
898
899 unsigned get_pos() { return pos; }
900 uint32_t *data() { return &bc[0]; }
901
902 bytecode & operator <<(uint32_t v) {
903 if (pos == ndw()) {
904 bc.push_back(v);
905 } else
906 bc.at(pos) = v;
907 ++pos;
908 return *this;
909 }
910
911 bytecode & operator <<(const hw_encoding_format &e) {
912 *this << e.get_value(hw_class_bit);
913 return *this;
914 }
915
916 bytecode & operator <<(const bytecode &b) {
917 bc.insert(bc.end(), b.bc.begin(), b.bc.end());
918 return *this;
919 }
920
921 uint32_t at(unsigned dw_id) { return bc.at(dw_id); }
922 };
923
924
925 class bc_builder {
926 shader &sh;
927 sb_context &ctx;
928 bytecode bb;
929 int error;
930
931 public:
932
933 bc_builder(shader &s);
934 int build();
935 bytecode& get_bytecode() { assert(!error); return bb; }
936
937 private:
938
939 int build_cf(cf_node *n);
940
941 int build_cf_alu(cf_node *n);
942 int build_cf_mem(cf_node *n);
943 int build_cf_exp(cf_node *n);
944
945 int build_alu_clause(cf_node *n);
946 int build_alu_group(alu_group_node *n);
947 int build_alu(alu_node *n);
948
949 int build_fetch_clause(cf_node *n);
950 int build_fetch_tex(fetch_node *n);
951 int build_fetch_vtx(fetch_node *n);
952 };
953
954 } // namespace r600_sb
955
956 #endif /* SB_BC_H_ */