Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2012-2013 LunarG, Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #ifndef TOY_COMPILER_H
  29. #define TOY_COMPILER_H
  30.  
  31. #include "genhw/genhw.h"
  32. #include "util/u_slab.h"
  33.  
  34. #include "ilo_common.h"
  35. #include "toy_compiler_reg.h"
  36.  
  37. /**
  38.  * Toy opcodes.
  39.  */
  40. enum toy_opcode {
  41.    /* 0..127 are reserved for GEN6_OPCODE_x */
  42.    TOY_OPCODE_LAST_HW = 127,
  43.  
  44.    TOY_OPCODE_DO,
  45.  
  46.    /* TGSI register functions */
  47.    TOY_OPCODE_TGSI_IN,
  48.    TOY_OPCODE_TGSI_CONST,
  49.    TOY_OPCODE_TGSI_SV,
  50.    TOY_OPCODE_TGSI_IMM,
  51.    TOY_OPCODE_TGSI_INDIRECT_FETCH,
  52.    TOY_OPCODE_TGSI_INDIRECT_STORE,
  53.  
  54.    /* TGSI sampling functions */
  55.    TOY_OPCODE_TGSI_TEX,
  56.    TOY_OPCODE_TGSI_TXB,
  57.    TOY_OPCODE_TGSI_TXD,
  58.    TOY_OPCODE_TGSI_TXL,
  59.    TOY_OPCODE_TGSI_TXP,
  60.    TOY_OPCODE_TGSI_TXF,
  61.    TOY_OPCODE_TGSI_TXQ,
  62.    TOY_OPCODE_TGSI_TXQ_LZ,
  63.    TOY_OPCODE_TGSI_TEX2,
  64.    TOY_OPCODE_TGSI_TXB2,
  65.    TOY_OPCODE_TGSI_TXL2,
  66.    TOY_OPCODE_TGSI_SAMPLE,
  67.    TOY_OPCODE_TGSI_SAMPLE_I,
  68.    TOY_OPCODE_TGSI_SAMPLE_I_MS,
  69.    TOY_OPCODE_TGSI_SAMPLE_B,
  70.    TOY_OPCODE_TGSI_SAMPLE_C,
  71.    TOY_OPCODE_TGSI_SAMPLE_C_LZ,
  72.    TOY_OPCODE_TGSI_SAMPLE_D,
  73.    TOY_OPCODE_TGSI_SAMPLE_L,
  74.    TOY_OPCODE_TGSI_GATHER4,
  75.    TOY_OPCODE_TGSI_SVIEWINFO,
  76.    TOY_OPCODE_TGSI_SAMPLE_POS,
  77.    TOY_OPCODE_TGSI_SAMPLE_INFO,
  78.  
  79.    /* math functions */
  80.    TOY_OPCODE_INV,
  81.    TOY_OPCODE_LOG,
  82.    TOY_OPCODE_EXP,
  83.    TOY_OPCODE_SQRT,
  84.    TOY_OPCODE_RSQ,
  85.    TOY_OPCODE_SIN,
  86.    TOY_OPCODE_COS,
  87.    TOY_OPCODE_FDIV,
  88.    TOY_OPCODE_POW,
  89.    TOY_OPCODE_INT_DIV_QUOTIENT,
  90.    TOY_OPCODE_INT_DIV_REMAINDER,
  91.  
  92.    /* URB functions */
  93.    TOY_OPCODE_URB_WRITE,
  94.  
  95.    /* GS-specific functions */
  96.    TOY_OPCODE_EMIT,
  97.    TOY_OPCODE_ENDPRIM,
  98.  
  99.    /* FS-specific functions */
  100.    TOY_OPCODE_DDX,
  101.    TOY_OPCODE_DDY,
  102.    TOY_OPCODE_FB_WRITE,
  103.    TOY_OPCODE_KIL,
  104. };
  105.  
  106. /**
  107.  * Toy instruction.
  108.  */
  109. struct toy_inst {
  110.    unsigned opcode:8;            /* enum toy_opcode      */
  111.    unsigned access_mode:1;       /* GEN6_ALIGN_x          */
  112.    unsigned mask_ctrl:1;         /* GEN6_MASKCTRL_x           */
  113.    unsigned dep_ctrl:2;          /* GEN6_DEPCTRL_x     */
  114.    unsigned qtr_ctrl:2;          /* GEN6_QTRCTRL_x   */
  115.    unsigned thread_ctrl:2;       /* GEN6_THREADCTRL_x         */
  116.    unsigned pred_ctrl:4;         /* GEN6_PREDCTRL_x      */
  117.    unsigned pred_inv:1;          /* true or false        */
  118.    unsigned exec_size:3;         /* GEN6_EXECSIZE_x        */
  119.    unsigned cond_modifier:4;     /* GEN6_COND_x    */
  120.    unsigned acc_wr_ctrl:1;       /* true or false        */
  121.    unsigned saturate:1;          /* true or false        */
  122.  
  123.    /* true if the instruction should be ignored for instruction iteration */
  124.    unsigned marker:1;
  125.  
  126.    unsigned pad:1;
  127.  
  128.    struct toy_dst dst;
  129.    struct toy_src src[5];        /* match TGSI_FULL_MAX_SRC_REGISTERS */
  130.  
  131.    struct {
  132.       int target;                /* TGSI_TEXTURE_x */
  133.       struct toy_src offsets[1]; /* need to be 4 when GATHER4 is supported */
  134.    } tex;
  135.  
  136.    struct list_head list;
  137. };
  138.  
  139. struct toy_compaction_table {
  140.    uint32_t control[32];
  141.    uint32_t datatype[32];
  142.    uint32_t subreg[32];
  143.    uint32_t src[32];
  144.  
  145.    uint32_t control_3src[4];
  146.    uint64_t source_3src[4];
  147. };
  148.  
  149. /**
  150.  * Toy compiler.
  151.  */
  152. struct toy_compiler {
  153.    const struct ilo_dev *dev;
  154.  
  155.    struct toy_inst templ;
  156.    struct util_slab_mempool mempool;
  157.    struct list_head instructions;
  158.    struct list_head *iter, *iter_next;
  159.  
  160.    /* this is not set until toy_compiler_legalize_for_asm() */
  161.    int num_instructions;
  162.  
  163.    int rect_linear_width;
  164.    int next_vrf;
  165.  
  166.    bool fail;
  167.    const char *reason;
  168. };
  169.  
  170. /**
  171.  * Allocate the given number of VRF registers.
  172.  */
  173. static inline int
  174. tc_alloc_vrf(struct toy_compiler *tc, int count)
  175. {
  176.    const int vrf = tc->next_vrf;
  177.  
  178.    tc->next_vrf += count;
  179.  
  180.    return vrf;
  181. }
  182.  
  183. /**
  184.  * Allocate a temporary register.
  185.  */
  186. static inline struct toy_dst
  187. tc_alloc_tmp(struct toy_compiler *tc)
  188. {
  189.    return tdst(TOY_FILE_VRF, tc_alloc_vrf(tc, 1), 0);
  190. }
  191.  
  192. /**
  193.  * Allocate four temporary registers.
  194.  */
  195. static inline void
  196. tc_alloc_tmp4(struct toy_compiler *tc, struct toy_dst *tmp)
  197. {
  198.    tmp[0] = tc_alloc_tmp(tc);
  199.    tmp[1] = tc_alloc_tmp(tc);
  200.    tmp[2] = tc_alloc_tmp(tc);
  201.    tmp[3] = tc_alloc_tmp(tc);
  202. }
  203.  
  204. /**
  205.  * Duplicate an instruction at the current location.
  206.  */
  207. static inline struct toy_inst *
  208. tc_duplicate_inst(struct toy_compiler *tc, const struct toy_inst *inst)
  209. {
  210.    struct toy_inst *new_inst;
  211.  
  212.    new_inst = util_slab_alloc(&tc->mempool);
  213.    if (!new_inst)
  214.       return NULL;
  215.  
  216.    *new_inst = *inst;
  217.    list_addtail(&new_inst->list, tc->iter_next);
  218.  
  219.    return new_inst;
  220. }
  221.  
  222. /**
  223.  * Move an instruction to the current location.
  224.  */
  225. static inline void
  226. tc_move_inst(struct toy_compiler *tc, struct toy_inst *inst)
  227. {
  228.    list_del(&inst->list);
  229.    list_addtail(&inst->list, tc->iter_next);
  230. }
  231.  
  232. /**
  233.  * Discard an instruction.
  234.  */
  235. static inline void
  236. tc_discard_inst(struct toy_compiler *tc, struct toy_inst *inst)
  237. {
  238.    list_del(&inst->list);
  239.    util_slab_free(&tc->mempool, inst);
  240. }
  241.  
  242. /**
  243.  * Add a new instruction at the current location, using tc->templ as the
  244.  * template.
  245.  */
  246. static inline struct toy_inst *
  247. tc_add(struct toy_compiler *tc)
  248. {
  249.    return tc_duplicate_inst(tc, &tc->templ);
  250. }
  251.  
  252. /**
  253.  * A convenient version of tc_add() for instructions with 3 source operands.
  254.  */
  255. static inline struct toy_inst *
  256. tc_add3(struct toy_compiler *tc, unsigned opcode,
  257.         struct toy_dst dst,
  258.         struct toy_src src0,
  259.         struct toy_src src1,
  260.         struct toy_src src2)
  261. {
  262.    struct toy_inst *inst;
  263.  
  264.    inst = tc_add(tc);
  265.    if (!inst)
  266.       return NULL;
  267.  
  268.    inst->opcode = opcode;
  269.    inst->dst = dst;
  270.    inst->src[0] = src0;
  271.    inst->src[1] = src1;
  272.    inst->src[2] = src2;
  273.  
  274.    return inst;
  275. }
  276.  
  277. /**
  278.  * A convenient version of tc_add() for instructions with 2 source operands.
  279.  */
  280. static inline struct toy_inst *
  281. tc_add2(struct toy_compiler *tc, int opcode,
  282.             struct toy_dst dst,
  283.             struct toy_src src0,
  284.             struct toy_src src1)
  285. {
  286.    return tc_add3(tc, opcode, dst, src0, src1, tsrc_null());
  287. }
  288.  
  289. /**
  290.  * A convenient version of tc_add() for instructions with 1 source operand.
  291.  */
  292. static inline struct toy_inst *
  293. tc_add1(struct toy_compiler *tc, unsigned opcode,
  294.         struct toy_dst dst,
  295.         struct toy_src src0)
  296. {
  297.    return tc_add2(tc, opcode, dst, src0, tsrc_null());
  298. }
  299.  
  300. /**
  301.  * A convenient version of tc_add() for instructions without source or
  302.  * destination operands.
  303.  */
  304. static inline struct toy_inst *
  305. tc_add0(struct toy_compiler *tc, unsigned opcode)
  306. {
  307.    return tc_add1(tc, opcode, tdst_null(), tsrc_null());
  308. }
  309.  
  310. #define TC_ALU0(func, opcode)             \
  311. static inline struct toy_inst *           \
  312. func(struct toy_compiler *tc)             \
  313. {                                         \
  314.    return tc_add0(tc, opcode);            \
  315. }
  316.  
  317. #define TC_ALU1(func, opcode)             \
  318. static inline struct toy_inst *           \
  319. func(struct toy_compiler *tc,             \
  320.      struct toy_dst dst,                  \
  321.      struct toy_src src)                  \
  322. {                                         \
  323.    return tc_add1(tc, opcode, dst, src);  \
  324. }
  325.  
  326. #define TC_ALU2(func, opcode)             \
  327. static inline struct toy_inst *           \
  328. func(struct toy_compiler *tc,             \
  329.      struct toy_dst dst,                  \
  330.      struct toy_src src0,                 \
  331.      struct toy_src src1)                 \
  332. {                                         \
  333.    return tc_add2(tc, opcode,             \
  334.          dst, src0, src1);                \
  335. }
  336.  
  337. #define TC_ALU3(func, opcode)             \
  338. static inline struct toy_inst *           \
  339. func(struct toy_compiler *tc,             \
  340.      struct toy_dst dst,                  \
  341.      struct toy_src src0,                 \
  342.      struct toy_src src1,                 \
  343.      struct toy_src src2)                 \
  344. {                                         \
  345.    return tc_add3(tc, opcode,             \
  346.          dst, src0, src1, src2);          \
  347. }
  348.  
  349. #define TC_CND2(func, opcode)             \
  350. static inline struct toy_inst *           \
  351. func(struct toy_compiler *tc,             \
  352.      struct toy_dst dst,                  \
  353.      struct toy_src src0,                 \
  354.      struct toy_src src1,                 \
  355.      unsigned cond_modifier)              \
  356. {                                         \
  357.    struct toy_inst *inst;                 \
  358.    inst = tc_add2(tc, opcode,             \
  359.          dst, src0, src1);                \
  360.    inst->cond_modifier = cond_modifier;   \
  361.    return inst;                           \
  362. }
  363.  
  364. TC_ALU0(tc_NOP, GEN6_OPCODE_NOP)
  365. TC_ALU0(tc_ELSE, GEN6_OPCODE_ELSE)
  366. TC_ALU0(tc_ENDIF, GEN6_OPCODE_ENDIF)
  367. TC_ALU1(tc_MOV, GEN6_OPCODE_MOV)
  368. TC_ALU1(tc_RNDD, GEN6_OPCODE_RNDD)
  369. TC_ALU1(tc_INV, TOY_OPCODE_INV)
  370. TC_ALU1(tc_FRC, GEN6_OPCODE_FRC)
  371. TC_ALU1(tc_EXP, TOY_OPCODE_EXP)
  372. TC_ALU1(tc_LOG, TOY_OPCODE_LOG)
  373. TC_ALU2(tc_ADD, GEN6_OPCODE_ADD)
  374. TC_ALU2(tc_MUL, GEN6_OPCODE_MUL)
  375. TC_ALU2(tc_AND, GEN6_OPCODE_AND)
  376. TC_ALU2(tc_OR, GEN6_OPCODE_OR)
  377. TC_ALU2(tc_DP2, GEN6_OPCODE_DP2)
  378. TC_ALU2(tc_DP3, GEN6_OPCODE_DP3)
  379. TC_ALU2(tc_DP4, GEN6_OPCODE_DP4)
  380. TC_ALU2(tc_SHL, GEN6_OPCODE_SHL)
  381. TC_ALU2(tc_SHR, GEN6_OPCODE_SHR)
  382. TC_ALU2(tc_POW, TOY_OPCODE_POW)
  383. TC_ALU3(tc_MAC, GEN6_OPCODE_MAC)
  384. TC_CND2(tc_SEL, GEN6_OPCODE_SEL)
  385. TC_CND2(tc_CMP, GEN6_OPCODE_CMP)
  386. TC_CND2(tc_IF, GEN6_OPCODE_IF)
  387. TC_CND2(tc_SEND, GEN6_OPCODE_SEND)
  388.  
  389. /**
  390.  * Upcast a list_head to an instruction.
  391.  */
  392. static inline struct toy_inst *
  393. tc_list_to_inst(struct toy_compiler *tc, struct list_head *item)
  394. {
  395.    return container_of(item, (struct toy_inst *) NULL, list);
  396. }
  397.  
  398. /**
  399.  * Return the instruction at the current location.
  400.  */
  401. static inline struct toy_inst *
  402. tc_current(struct toy_compiler *tc)
  403. {
  404.    return (tc->iter != &tc->instructions) ?
  405.       tc_list_to_inst(tc, tc->iter) : NULL;
  406. }
  407.  
  408. /**
  409.  * Set the current location to the head.
  410.  */
  411. static inline void
  412. tc_head(struct toy_compiler *tc)
  413. {
  414.    tc->iter = &tc->instructions;
  415.    tc->iter_next = tc->iter->next;
  416. }
  417.  
  418. /**
  419.  * Set the current location to the tail.
  420.  */
  421. static inline void
  422. tc_tail(struct toy_compiler *tc)
  423. {
  424.    tc->iter = &tc->instructions;
  425.    tc->iter_next = tc->iter;
  426. }
  427.  
  428. /**
  429.  * Advance the current location.
  430.  */
  431. static inline struct toy_inst *
  432. tc_next_no_skip(struct toy_compiler *tc)
  433. {
  434.    /* stay at the tail so that new instructions are added there */
  435.    if (tc->iter_next == &tc->instructions) {
  436.       tc_tail(tc);
  437.       return NULL;
  438.    }
  439.  
  440.    tc->iter = tc->iter_next;
  441.    tc->iter_next = tc->iter_next->next;
  442.  
  443.    return tc_list_to_inst(tc, tc->iter);
  444. }
  445.  
  446. /**
  447.  * Advance the current location, skipping markers.
  448.  */
  449. static inline struct toy_inst *
  450. tc_next(struct toy_compiler *tc)
  451. {
  452.    struct toy_inst *inst;
  453.  
  454.    do {
  455.       inst = tc_next_no_skip(tc);
  456.    } while (inst && inst->marker);
  457.  
  458.    return inst;
  459. }
  460.  
  461. static inline void
  462. tc_fail(struct toy_compiler *tc, const char *reason)
  463. {
  464.    if (!tc->fail) {
  465.       tc->fail = true;
  466.       tc->reason = reason;
  467.    }
  468. }
  469.  
  470. void
  471. toy_compiler_init(struct toy_compiler *tc, const struct ilo_dev *dev);
  472.  
  473. void
  474. toy_compiler_cleanup(struct toy_compiler *tc);
  475.  
  476. void
  477. toy_compiler_dump(struct toy_compiler *tc);
  478.  
  479. void *
  480. toy_compiler_assemble(struct toy_compiler *tc, int *size);
  481.  
  482. const struct toy_compaction_table *
  483. toy_compiler_get_compaction_table(const struct ilo_dev *dev);
  484.  
  485. void
  486. toy_compiler_disassemble(const struct ilo_dev *dev,
  487.                          const void *kernel, int size,
  488.                          bool dump_hex);
  489.  
  490. #endif /* TOY_COMPILER_H */
  491.