Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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_PS,
  173.         TARGET_GS,
  174.         TARGET_COMPUTE,
  175.         TARGET_FETCH,
  176.  
  177.         TARGET_NUM
  178. };
  179.  
  180. enum sb_hw_class_bits
  181. {
  182.         HB_R6   = (1<<0),
  183.         HB_R7   = (1<<1),
  184.         HB_EG   = (1<<2),
  185.         HB_CM   = (1<<3),
  186.  
  187.         HB_R6R7 = (HB_R6 | HB_R7),
  188.         HB_EGCM = (HB_EG | HB_CM),
  189.         HB_R6R7EG = (HB_R6 | HB_R7 | HB_EG),
  190.         HB_R7EGCM = (HB_R7 | HB_EG | HB_CM),
  191.  
  192.         HB_ALL = (HB_R6 | HB_R7 | HB_EG | HB_CM)
  193. };
  194.  
  195. enum sb_hw_chip
  196. {
  197.         HW_CHIP_UNKNOWN,
  198.         HW_CHIP_R600,
  199.         HW_CHIP_RV610,
  200.         HW_CHIP_RV630,
  201.         HW_CHIP_RV670,
  202.         HW_CHIP_RV620,
  203.         HW_CHIP_RV635,
  204.         HW_CHIP_RS780,
  205.         HW_CHIP_RS880,
  206.         HW_CHIP_RV770,
  207.         HW_CHIP_RV730,
  208.         HW_CHIP_RV710,
  209.         HW_CHIP_RV740,
  210.         HW_CHIP_CEDAR,
  211.         HW_CHIP_REDWOOD,
  212.         HW_CHIP_JUNIPER,
  213.         HW_CHIP_CYPRESS,
  214.         HW_CHIP_HEMLOCK,
  215.         HW_CHIP_PALM,
  216.         HW_CHIP_SUMO,
  217.         HW_CHIP_SUMO2,
  218.         HW_CHIP_BARTS,
  219.         HW_CHIP_TURKS,
  220.         HW_CHIP_CAICOS,
  221.         HW_CHIP_CAYMAN,
  222.         HW_CHIP_ARUBA
  223. };
  224.  
  225. enum sb_hw_class
  226. {
  227.         HW_CLASS_UNKNOWN,
  228.         HW_CLASS_R600,
  229.         HW_CLASS_R700,
  230.         HW_CLASS_EVERGREEN,
  231.         HW_CLASS_CAYMAN
  232. };
  233.  
  234. enum alu_slots {
  235.         SLOT_X = 0,
  236.         SLOT_Y = 1,
  237.         SLOT_Z = 2,
  238.         SLOT_W = 3,
  239.         SLOT_TRANS = 4
  240. };
  241.  
  242. enum misc_consts {
  243.         MAX_ALU_LITERALS = 4,
  244.         MAX_ALU_SLOTS = 128,
  245.         MAX_GPR = 128,
  246.         MAX_CHAN = 4
  247.  
  248. };
  249.  
  250. enum alu_src_sel {
  251.  
  252.         ALU_SRC_LDS_OQ_A = 219,
  253.         ALU_SRC_LDS_OQ_B = 220,
  254.         ALU_SRC_LDS_OQ_A_POP = 221,
  255.         ALU_SRC_LDS_OQ_B_POP = 222,
  256.         ALU_SRC_LDS_DIRECT_A = 223,
  257.         ALU_SRC_LDS_DIRECT_B = 224,
  258.         ALU_SRC_TIME_HI = 227,
  259.         ALU_SRC_TIME_LO = 228,
  260.         ALU_SRC_MASK_HI = 229,
  261.         ALU_SRC_MASK_LO = 230,
  262.         ALU_SRC_HW_WAVE_ID = 231,
  263.         ALU_SRC_SIMD_ID = 232,
  264.         ALU_SRC_SE_ID = 233,
  265.         ALU_SRC_HW_THREADGRP_ID = 234,
  266.         ALU_SRC_WAVE_ID_IN_GRP = 235,
  267.         ALU_SRC_NUM_THREADGRP_WAVES = 236,
  268.         ALU_SRC_HW_ALU_ODD = 237,
  269.         ALU_SRC_LOOP_IDX = 238,
  270.         ALU_SRC_PARAM_BASE_ADDR = 240,
  271.         ALU_SRC_NEW_PRIM_MASK = 241,
  272.         ALU_SRC_PRIM_MASK_HI = 242,
  273.         ALU_SRC_PRIM_MASK_LO = 243,
  274.         ALU_SRC_1_DBL_L = 244,
  275.         ALU_SRC_1_DBL_M = 245,
  276.         ALU_SRC_0_5_DBL_L = 246,
  277.         ALU_SRC_0_5_DBL_M = 247,
  278.         ALU_SRC_0 = 248,
  279.         ALU_SRC_1 = 249,
  280.         ALU_SRC_1_INT = 250,
  281.         ALU_SRC_M_1_INT = 251,
  282.         ALU_SRC_0_5 = 252,
  283.         ALU_SRC_LITERAL = 253,
  284.         ALU_SRC_PV = 254,
  285.         ALU_SRC_PS = 255,
  286.  
  287.         ALU_SRC_PARAM_OFFSET = 448
  288. };
  289.  
  290. enum alu_predicate_select
  291. {
  292.         PRED_SEL_OFF    = 0,
  293. //      RESERVED                = 1,
  294.         PRED_SEL_0              = 2,
  295.         PRED_SEL_1              = 3
  296. };
  297.  
  298.  
  299. enum alu_omod {
  300.         OMOD_OFF  = 0,
  301.         OMOD_M2   = 1,
  302.         OMOD_M4   = 2,
  303.         OMOD_D2   = 3
  304. };
  305.  
  306. enum alu_index_mode {
  307.         INDEX_AR_X        = 0,
  308.         INDEX_AR_Y_R600   = 1,
  309.         INDEX_AR_Z_R600   = 2,
  310.         INDEX_AR_W_R600   = 3,
  311.  
  312.         INDEX_LOOP        = 4,
  313.         INDEX_GLOBAL      = 5,
  314.         INDEX_GLOBAL_AR_X = 6
  315. };
  316.  
  317. enum alu_cayman_mova_dst {
  318.         CM_MOVADST_AR_X,
  319.         CM_MOVADST_PC,
  320.         CM_MOVADST_IDX0,
  321.         CM_MOVADST_IDX1,
  322.         CM_MOVADST_CG0,         // clause-global byte 0
  323.         CM_MOVADST_CG1,
  324.         CM_MOVADST_CG2,
  325.         CM_MOVADST_CG3
  326. };
  327.  
  328. enum alu_cayman_exec_mask_op {
  329.         CM_EMO_DEACTIVATE,
  330.         CM_EMO_BREAK,
  331.         CM_EMO_CONTINUE,
  332.         CM_EMO_KILL
  333. };
  334.  
  335.  
  336. enum cf_exp_type {
  337.         EXP_PIXEL,
  338.         EXP_POS,
  339.         EXP_PARAM,
  340.  
  341.         EXP_TYPE_COUNT
  342. };
  343.  
  344. enum cf_mem_type {
  345.         MEM_WRITE,
  346.         MEM_WRITE_IND,
  347.         MEM_WRITE_ACK,
  348.         MEM_WRITE_IND_ACK
  349. };
  350.  
  351.  
  352. enum alu_kcache_mode {
  353.         KC_LOCK_NONE,
  354.         KC_LOCK_1,
  355.         KC_LOCK_2,
  356.         KC_LOCK_LOOP
  357. };
  358.  
  359. enum alu_kcache_index_mode {
  360.         KC_INDEX_NONE,
  361.         KC_INDEX_0,
  362.         KC_INDEX_1,
  363.         KC_INDEX_INVALID
  364. };
  365.  
  366. enum chan_select {
  367.         SEL_X   = 0,
  368.         SEL_Y   = 1,
  369.         SEL_Z   = 2,
  370.         SEL_W   = 3,
  371.         SEL_0   = 4,
  372.         SEL_1   = 5,
  373. //      RESERVED = 6,
  374.         SEL_MASK = 7
  375. };
  376.  
  377. enum bank_swizzle {
  378.         VEC_012 = 0,
  379.         VEC_021 = 1,
  380.         VEC_120 = 2,
  381.         VEC_102 = 3,
  382.         VEC_201 = 4,
  383.         VEC_210 = 5,
  384.  
  385.         VEC_NUM = 6,
  386.  
  387.         SCL_210 = 0,
  388.         SCL_122 = 1,
  389.         SCL_212 = 2,
  390.         SCL_221 = 3,
  391.  
  392.         SCL_NUM = 4
  393.  
  394. };
  395.  
  396. enum sched_queue_id {
  397.         SQ_CF,
  398.         SQ_ALU,
  399.         SQ_TEX,
  400.         SQ_VTX,
  401.  
  402.         SQ_NUM
  403. };
  404.  
  405. struct literal {
  406.         union {
  407.                 int32_t i;
  408.                 uint32_t u;
  409.                 float f;
  410.         };
  411.  
  412.         literal(int32_t i = 0) : i(i) {}
  413.         literal(uint32_t u) : u(u) {}
  414.         literal(float f) : f(f) {}
  415.         literal(double f) : f(f) {}
  416.         operator uint32_t() const { return u; }
  417.         bool operator ==(literal l) { return u == l.u; }
  418.         bool operator ==(int v_int) { return i == v_int; }
  419.         bool operator ==(unsigned v_uns) { return u == v_uns; }
  420. };
  421.  
  422. struct bc_kcache {
  423.         unsigned mode;
  424.         unsigned bank;
  425.         unsigned addr;
  426.         unsigned index_mode;
  427. } ;
  428.  
  429. // TODO optimize bc structures
  430.  
  431. struct bc_cf {
  432.  
  433.         bc_kcache kc[4];
  434.  
  435.         unsigned id;
  436.  
  437.  
  438.         const cf_op_info * op_ptr;
  439.         unsigned op;
  440.  
  441.         unsigned addr:32;
  442.  
  443.         unsigned alt_const:1;
  444.         unsigned uses_waterfall:1;
  445.  
  446.         unsigned barrier:1;
  447.         unsigned count:7;
  448.         unsigned pop_count:3;
  449.         unsigned call_count:6;
  450.         unsigned whole_quad_mode:1;
  451.         unsigned valid_pixel_mode:1;
  452.  
  453.         unsigned jumptable_sel:3;
  454.         unsigned cf_const:5;
  455.         unsigned cond:2;
  456.         unsigned end_of_program:1;
  457.  
  458.         unsigned array_base:13;
  459.         unsigned elem_size:2;
  460.         unsigned index_gpr:7;
  461.         unsigned rw_gpr:7;
  462.         unsigned rw_rel:1;
  463.         unsigned type:2;
  464.  
  465.         unsigned burst_count:4;
  466.         unsigned mark:1;
  467.         unsigned sel[4];
  468.  
  469.         unsigned array_size:12;
  470.         unsigned comp_mask:4;
  471.  
  472.         unsigned rat_id:4;
  473.         unsigned rat_inst:6;
  474.         unsigned rat_index_mode:2;
  475.  
  476.         void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_cf(op); }
  477.  
  478.         bool is_alu_extended() {
  479.                 assert(op_ptr->flags & CF_ALU);
  480.                 return kc[2].mode != KC_LOCK_NONE || kc[3].mode != KC_LOCK_NONE;
  481.         }
  482.  
  483. };
  484.  
  485. struct bc_alu_src {
  486.         unsigned sel:9;
  487.         unsigned chan:2;
  488.         unsigned neg:1;
  489.         unsigned abs:1;
  490.         unsigned rel:1;
  491.         literal value;
  492. };
  493.  
  494. struct bc_alu {
  495.         const alu_op_info * op_ptr;
  496.         unsigned op;
  497.  
  498.         bc_alu_src src[3];
  499.  
  500.         unsigned dst_gpr:7;
  501.         unsigned dst_chan:2;
  502.         unsigned dst_rel:1;
  503.         unsigned clamp:1;
  504.         unsigned omod:2;
  505.         unsigned bank_swizzle:3;
  506.  
  507.         unsigned index_mode:3;
  508.         unsigned last:1;
  509.         unsigned pred_sel:2;
  510.  
  511.         unsigned fog_merge:1;
  512.         unsigned write_mask:1;
  513.         unsigned update_exec_mask:1;
  514.         unsigned update_pred:1;
  515.  
  516.         unsigned slot:3;
  517.  
  518.         alu_op_flags slot_flags;
  519.  
  520.         void set_op(unsigned op) {
  521.                 this->op = op;
  522.                 op_ptr = r600_isa_alu(op);
  523.         }
  524. };
  525.  
  526. struct bc_fetch {
  527.         const fetch_op_info * op_ptr;
  528.         unsigned op;
  529.  
  530.         unsigned bc_frac_mode:1;
  531.         unsigned fetch_whole_quad:1;
  532.         unsigned resource_id:8;
  533.  
  534.         unsigned src_gpr:7;
  535.         unsigned src_rel:1;
  536.         unsigned src_sel[4];
  537.  
  538.         unsigned dst_gpr:7;
  539.         unsigned dst_rel:1;
  540.         unsigned dst_sel[4];
  541.  
  542.         unsigned alt_const:1;
  543.  
  544.         unsigned inst_mod:2;
  545.         unsigned resource_index_mode:2;
  546.         unsigned sampler_index_mode:2;
  547.  
  548.         unsigned coord_type[4];
  549.         unsigned lod_bias:7;
  550.  
  551.         unsigned offset[3];
  552.  
  553.         unsigned sampler_id:5;
  554.  
  555.  
  556.         unsigned fetch_type:2;
  557.         unsigned mega_fetch_count:6;
  558.         unsigned coalesced_read:1;
  559.         unsigned structured_read:2;
  560.         unsigned lds_req:1;
  561.  
  562.         unsigned data_format:6;
  563.         unsigned format_comp_all:1;
  564.         unsigned num_format_all:2;
  565.         unsigned semantic_id:8;
  566.         unsigned srf_mode_all:1;
  567.         unsigned use_const_fields:1;
  568.  
  569.         unsigned const_buf_no_stride:1;
  570.         unsigned endian_swap:2;
  571.         unsigned mega_fetch:1;
  572.  
  573.         void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_fetch(op); }
  574. };
  575.  
  576. struct shader_stats {
  577.         unsigned        ndw;
  578.         unsigned        ngpr;
  579.         unsigned        nstack;
  580.  
  581.         unsigned        cf; // clause instructions not included
  582.         unsigned        alu;
  583.         unsigned        alu_clauses;
  584.         unsigned        fetch_clauses;
  585.         unsigned        fetch;
  586.         unsigned        alu_groups;
  587.  
  588.         unsigned        shaders;                // number of shaders (for accumulated stats)
  589.  
  590.         shader_stats() : ndw(), ngpr(), nstack(), cf(), alu(), alu_clauses(),
  591.                         fetch_clauses(), fetch(), alu_groups(), shaders() {}
  592.  
  593.         void collect(node *n);
  594.         void accumulate(shader_stats &s);
  595.         void dump();
  596.         void dump_diff(shader_stats &s);
  597. };
  598.  
  599. class sb_context {
  600.  
  601. public:
  602.  
  603.         shader_stats src_stats, opt_stats;
  604.  
  605.         r600_isa *isa;
  606.  
  607.         sb_hw_chip hw_chip;
  608.         sb_hw_class hw_class;
  609.  
  610.         unsigned alu_temp_gprs;
  611.         unsigned max_fetch;
  612.         bool has_trans;
  613.         unsigned vtx_src_num;
  614.         unsigned num_slots;
  615.         bool uses_mova_gpr;
  616.  
  617.         unsigned stack_entry_size;
  618.  
  619.         static unsigned dump_pass;
  620.         static unsigned dump_stat;
  621.  
  622.         static unsigned dry_run;
  623.         static unsigned no_fallback;
  624.         static unsigned safe_math;
  625.  
  626.         static unsigned dskip_start;
  627.         static unsigned dskip_end;
  628.         static unsigned dskip_mode;
  629.  
  630.         sb_context() : src_stats(), opt_stats(), isa(0),
  631.                         hw_chip(HW_CHIP_UNKNOWN), hw_class(HW_CLASS_UNKNOWN) {}
  632.  
  633.         int init(r600_isa *isa, sb_hw_chip chip, sb_hw_class cclass);
  634.  
  635.         bool is_r600() {return hw_class == HW_CLASS_R600;}
  636.         bool is_r700() {return hw_class == HW_CLASS_R700;}
  637.         bool is_evergreen() {return hw_class == HW_CLASS_EVERGREEN;}
  638.         bool is_cayman() {return hw_class == HW_CLASS_CAYMAN;}
  639.         bool is_egcm() {return hw_class >= HW_CLASS_EVERGREEN;}
  640.  
  641.         sb_hw_class_bits hw_class_bit() {
  642.                 switch (hw_class) {
  643.                 case HW_CLASS_R600:return HB_R6;
  644.                 case HW_CLASS_R700:return HB_R7;
  645.                 case HW_CLASS_EVERGREEN:return HB_EG;
  646.                 case HW_CLASS_CAYMAN:return HB_CM;
  647.                 default: assert(!"unknown hw class"); return (sb_hw_class_bits)0;
  648.  
  649.                 }
  650.         }
  651.  
  652.         unsigned cf_opcode(unsigned op) {
  653.                 return r600_isa_cf_opcode(isa->hw_class, op);
  654.         }
  655.  
  656.         unsigned alu_opcode(unsigned op) {
  657.                 return r600_isa_alu_opcode(isa->hw_class, op);
  658.         }
  659.  
  660.         unsigned alu_slots(unsigned op) {
  661.                 return r600_isa_alu_slots(isa->hw_class, op);
  662.         }
  663.  
  664.         unsigned alu_slots(const alu_op_info * op_ptr) {
  665.                 return op_ptr->slots[isa->hw_class];
  666.         }
  667.  
  668.         unsigned alu_slots_mask(const alu_op_info * op_ptr) {
  669.                 unsigned mask = 0;
  670.                 unsigned slot_flags = alu_slots(op_ptr);
  671.                 if (slot_flags & AF_V)
  672.                         mask = 0x0F;
  673.                 if (!is_cayman() && (slot_flags & AF_S))
  674.                         mask |= 0x10;
  675.                 return mask;
  676.         }
  677.  
  678.         unsigned fetch_opcode(unsigned op) {
  679.                 return r600_isa_fetch_opcode(isa->hw_class, op);
  680.         }
  681.  
  682.         bool is_kcache_sel(unsigned sel) {
  683.                 return ((sel >= 128 && sel < 192) || (sel >= 256 && sel < 320));
  684.         }
  685.  
  686.         const char * get_hw_class_name();
  687.         const char * get_hw_chip_name();
  688.  
  689. };
  690.  
  691. #define SB_DUMP_STAT(a) do { if (sb_context::dump_stat) { a } } while (0)
  692. #define SB_DUMP_PASS(a) do { if (sb_context::dump_pass) { a } } while (0)
  693.  
  694. class bc_decoder {
  695.  
  696.         sb_context &ctx;
  697.  
  698.         uint32_t* dw;
  699.         unsigned ndw;
  700.  
  701. public:
  702.  
  703.         bc_decoder(sb_context &sctx, uint32_t *data, unsigned size)
  704.                 : ctx(sctx), dw(data), ndw(size) {}
  705.  
  706.         int decode_cf(unsigned &i, bc_cf &bc);
  707.         int decode_alu(unsigned &i, bc_alu &bc);
  708.         int decode_fetch(unsigned &i, bc_fetch &bc);
  709.  
  710. private:
  711.         int decode_cf_alu(unsigned &i, bc_cf &bc);
  712.         int decode_cf_exp(unsigned &i, bc_cf &bc);
  713.         int decode_cf_mem(unsigned &i, bc_cf &bc);
  714.  
  715.         int decode_fetch_vtx(unsigned &i, bc_fetch &bc);
  716. };
  717.  
  718. // bytecode format definition
  719.  
  720. class hw_encoding_format {
  721.         const sb_hw_class_bits hw_target; //FIXME: debug - remove after testing
  722.         hw_encoding_format();
  723. protected:
  724.         uint32_t value;
  725. public:
  726.         hw_encoding_format(sb_hw_class_bits hw)
  727.                 : hw_target(hw), value(0) {}
  728.         hw_encoding_format(uint32_t v, sb_hw_class_bits hw)
  729.                 : hw_target(hw), value(v) {}
  730.         uint32_t get_value(sb_hw_class_bits hw) const {
  731.                 assert((hw & hw_target) == hw);
  732.                 return value;
  733.         }
  734. };
  735.  
  736. #define BC_FORMAT_BEGIN_HW(fmt, hwset) \
  737. class fmt##_##hwset : public hw_encoding_format {\
  738.         typedef fmt##_##hwset thistype; \
  739. public: \
  740.         fmt##_##hwset() : hw_encoding_format(HB_##hwset) {}; \
  741.         fmt##_##hwset(uint32_t v) : hw_encoding_format(v, HB_##hwset) {};
  742.  
  743. #define BC_FORMAT_BEGIN(fmt) BC_FORMAT_BEGIN_HW(fmt, ALL)
  744.  
  745. #define BC_FORMAT_END(fmt) };
  746.  
  747. // bytecode format field definition
  748.  
  749. #define BC_FIELD(fmt, name, shortname, last_bit, first_bit) \
  750.         thistype & name(unsigned v) { \
  751.                 value |= ((v&((1ull<<((last_bit)-(first_bit)+1))-1))<<(first_bit)); \
  752.                 return *this; \
  753.         } \
  754.         unsigned get_##name() const { \
  755.                 return (value>>(first_bit))&((1ull<<((last_bit)-(first_bit)+1))-1); \
  756.         } \
  757.  
  758. #define BC_RSRVD(fmt, last_bit, first_bit)
  759.  
  760. // CLAMP macro defined elsewhere interferes with bytecode field name
  761. #undef CLAMP
  762.  
  763. #include "sb_bc_fmt_def.inc"
  764.  
  765. #undef BC_FORMAT_BEGIN
  766. #undef BC_FORMAT_END
  767. #undef BC_FIELD
  768. #undef BC_RSRVD
  769.  
  770. class bc_parser {
  771.         sb_context & ctx;
  772.  
  773.         bc_decoder *dec;
  774.  
  775.         r600_bytecode *bc;
  776.         r600_shader *pshader;
  777.  
  778.         uint32_t *dw;
  779.         unsigned bc_ndw;
  780.  
  781.         unsigned max_cf;
  782.  
  783.         shader *sh;
  784.  
  785.         int error;
  786.  
  787.         alu_node *slots[2][5];
  788.         unsigned cgroup;
  789.  
  790.         typedef std::vector<cf_node*> id_cf_map;
  791.         id_cf_map cf_map;
  792.  
  793.         typedef std::stack<region_node*> region_stack;
  794.         region_stack loop_stack;
  795.  
  796.         bool gpr_reladdr;
  797.  
  798. public:
  799.  
  800.         bc_parser(sb_context &sctx, r600_bytecode *bc, r600_shader* pshader) :
  801.                 ctx(sctx), dec(), bc(bc), pshader(pshader),
  802.                 dw(), bc_ndw(), max_cf(),
  803.                 sh(), error(), slots(), cgroup(),
  804.                 cf_map(), loop_stack(), gpr_reladdr() { }
  805.  
  806.         int decode();
  807.         int prepare();
  808.  
  809.         shader* get_shader() { assert(!error); return sh; }
  810.  
  811. private:
  812.  
  813.         int decode_shader();
  814.  
  815.         int parse_decls();
  816.  
  817.         int decode_cf(unsigned &i, bool &eop);
  818.  
  819.         int decode_alu_clause(cf_node *cf);
  820.         int decode_alu_group(cf_node* cf, unsigned &i, unsigned &gcnt);
  821.  
  822.         int decode_fetch_clause(cf_node *cf);
  823.  
  824.         int prepare_ir();
  825.         int prepare_alu_clause(cf_node *cf);
  826.         int prepare_alu_group(cf_node* cf, alu_group_node *g);
  827.         int prepare_fetch_clause(cf_node *cf);
  828.  
  829.         int prepare_loop(cf_node *c);
  830.         int prepare_if(cf_node *c);
  831.  
  832. };
  833.  
  834.  
  835.  
  836.  
  837. class bytecode {
  838.         typedef std::vector<uint32_t> bc_vector;
  839.         sb_hw_class_bits hw_class_bit;
  840.  
  841.         bc_vector bc;
  842.  
  843.         unsigned pos;
  844.  
  845. public:
  846.  
  847.         bytecode(sb_hw_class_bits hw, unsigned rdw = 256)
  848.                 : hw_class_bit(hw), pos(0) { bc.reserve(rdw); }
  849.  
  850.         unsigned ndw() { return bc.size(); }
  851.  
  852.         void write_data(uint32_t* dst) {
  853.                 std::copy(bc.begin(), bc.end(), dst);
  854.         }
  855.  
  856.         void align(unsigned a) {
  857.                 unsigned size = bc.size();
  858.                 size = (size + a - 1) & ~(a-1);
  859.                 bc.resize(size);
  860.         }
  861.  
  862.         void set_size(unsigned sz) {
  863.                 assert(sz >= bc.size());
  864.                 bc.resize(sz);
  865.         }
  866.  
  867.         void seek(unsigned p) {
  868.                 if (p != pos) {
  869.                         if (p > bc.size()) {
  870.                                 bc.resize(p);
  871.                         }
  872.                         pos = p;
  873.                 }
  874.         }
  875.  
  876.         unsigned get_pos() { return pos; }
  877.         uint32_t *data() { return &bc[0]; }
  878.  
  879.         bytecode & operator <<(uint32_t v) {
  880.                 if (pos == ndw()) {
  881.                         bc.push_back(v);
  882.                 } else
  883.                         bc.at(pos) = v;
  884.                 ++pos;
  885.                 return *this;
  886.         }
  887.  
  888.         bytecode & operator <<(const hw_encoding_format &e) {
  889.                 *this << e.get_value(hw_class_bit);
  890.                 return *this;
  891.         }
  892.  
  893.         bytecode & operator <<(const bytecode &b) {
  894.                 bc.insert(bc.end(), b.bc.begin(), b.bc.end());
  895.                 return *this;
  896.         }
  897.  
  898.         uint32_t at(unsigned dw_id) { return bc.at(dw_id); }
  899. };
  900.  
  901.  
  902. class bc_builder {
  903.         shader &sh;
  904.         sb_context &ctx;
  905.         bytecode bb;
  906.         int error;
  907.  
  908. public:
  909.  
  910.         bc_builder(shader &s);
  911.         int build();
  912.         bytecode& get_bytecode() { assert(!error); return bb; }
  913.  
  914. private:
  915.  
  916.         int build_cf(cf_node *n);
  917.  
  918.         int build_cf_alu(cf_node *n);
  919.         int build_cf_mem(cf_node *n);
  920.         int build_cf_exp(cf_node *n);
  921.  
  922.         int build_alu_clause(cf_node *n);
  923.         int build_alu_group(alu_group_node *n);
  924.         int build_alu(alu_node *n);
  925.  
  926.         int build_fetch_clause(cf_node *n);
  927.         int build_fetch_tex(fetch_node *n);
  928.         int build_fetch_vtx(fetch_node *n);
  929. };
  930.  
  931. } // namespace r600_sb
  932.  
  933. #endif /* SB_BC_H_ */
  934.