Subversion Repositories Kolibri OS

Rev

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. #include <stdint.h>
  31. #include "r600_isa.h"
  32.  
  33. #include <cstdio>
  34. #include <string>
  35. #include <vector>
  36. #include <stack>
  37.  
  38. struct r600_bytecode;
  39. struct r600_shader;
  40.  
  41. namespace r600_sb {
  42.  
  43. class hw_encoding_format;
  44. class node;
  45. class alu_node;
  46. class cf_node;
  47. class fetch_node;
  48. class alu_group_node;
  49. class region_node;
  50. class shader;
  51.  
  52. class sb_ostream {
  53. public:
  54.         sb_ostream() {}
  55.  
  56.         virtual void write(const char *s) = 0;
  57.  
  58.         sb_ostream& operator <<(const char *s) {
  59.                 write(s);
  60.                 return *this;
  61.         }
  62.  
  63.         sb_ostream& operator <<(const std::string& s) {
  64.                 return *this << s.c_str();
  65.         }
  66.  
  67.         sb_ostream& operator <<(void *p) {
  68.                 char b[32];
  69.                 sprintf(b, "%p", p);
  70.                 return *this << b;
  71.         }
  72.  
  73.         sb_ostream& operator <<(char c) {
  74.                 char b[2];
  75.                 sprintf(b, "%c", c);
  76.                 return *this << b;
  77.         }
  78.  
  79.         sb_ostream& operator <<(int n) {
  80.                 char b[32];
  81.                 sprintf(b, "%d", n);
  82.                 return *this << b;
  83.         }
  84.  
  85.         sb_ostream& operator <<(unsigned n) {
  86.                 char b[32];
  87.                 sprintf(b, "%u", n);
  88.                 return *this << b;
  89.         }
  90.  
  91.         sb_ostream& operator <<(double d) {
  92.                 char b[32];
  93.                 snprintf(b, 32, "%g", d);
  94.                 return *this << b;
  95.         }
  96.  
  97.         // print as field of specified width, right aligned
  98.         void print_w(int n, int width) {
  99.                 char b[256],f[8];
  100.                 sprintf(f, "%%%dd", width);
  101.                 snprintf(b, 256, f, n);
  102.                 write(b);
  103.         }
  104.  
  105.         // print as field of specified width, left aligned
  106.         void print_wl(int n, int width) {
  107.                 char b[256],f[8];
  108.                 sprintf(f, "%%-%dd", width);
  109.                 snprintf(b, 256, f, n);
  110.                 write(b);
  111.         }
  112.  
  113.         // print as field of specified width, left aligned
  114.         void print_wl(const std::string &s, int width) {
  115.                 write(s.c_str());
  116.                 int l = s.length();
  117.                 while (l++ < width) {
  118.                         write(" ");
  119.                 }
  120.         }
  121.  
  122.         // print int as field of specified width, right aligned, zero-padded
  123.         void print_zw(int n, int width) {
  124.                 char b[256],f[8];
  125.                 sprintf(f, "%%0%dd", width);
  126.                 snprintf(b, 256, f, n);
  127.                 write(b);
  128.         }
  129.  
  130.         // print int as field of specified width, right aligned, zero-padded, hex
  131.         void print_zw_hex(int n, int width) {
  132.                 char b[256],f[8];
  133.                 sprintf(f, "%%0%dx", width);
  134.                 snprintf(b, 256, f, n);
  135.                 write(b);
  136.         }
  137. };
  138.  
  139. class sb_ostringstream : public sb_ostream {
  140.         std::string data;
  141. public:
  142.         sb_ostringstream() : data() {}
  143.  
  144.         virtual void write(const char *s) {
  145.                 data += s;
  146.         }
  147.  
  148.         void clear() { data.clear(); }
  149.  
  150.         const char* c_str() { return data.c_str(); }
  151.         std::string& str() { return data; }
  152. };
  153.  
  154. class sb_log : public sb_ostream {
  155.         FILE *o;
  156. public:
  157.         sb_log() : o(stderr) {}
  158.  
  159.         virtual void write(const char *s) {
  160.                 fputs(s, o);
  161.         }
  162. };
  163.  
  164. extern sb_log sblog;
  165.  
  166. enum shader_target
  167. {
  168.         TARGET_UNKNOWN,
  169.         TARGET_VS,
  170.         TARGET_ES,
  171.         TARGET_PS,
  172.         TARGET_GS,
  173.         TARGET_GS_COPY,
  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.         bool r6xx_gpr_index_workaround;
  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. #undef ARRAY_SIZE
  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_ */
  957.