Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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 "util/u_slab.h"
  32. #include "brw_defines.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 BRW_OPCODE_x */
  42.    TOY_OPCODE_LAST_HW = 127,
  43.  
  44.    /* TGSI register functions */
  45.    TOY_OPCODE_TGSI_IN,
  46.    TOY_OPCODE_TGSI_CONST,
  47.    TOY_OPCODE_TGSI_SV,
  48.    TOY_OPCODE_TGSI_IMM,
  49.    TOY_OPCODE_TGSI_INDIRECT_FETCH,
  50.    TOY_OPCODE_TGSI_INDIRECT_STORE,
  51.  
  52.    /* TGSI sampling functions */
  53.    TOY_OPCODE_TGSI_TEX,
  54.    TOY_OPCODE_TGSI_TXB,
  55.    TOY_OPCODE_TGSI_TXD,
  56.    TOY_OPCODE_TGSI_TXL,
  57.    TOY_OPCODE_TGSI_TXP,
  58.    TOY_OPCODE_TGSI_TXF,
  59.    TOY_OPCODE_TGSI_TXQ,
  60.    TOY_OPCODE_TGSI_TXQ_LZ,
  61.    TOY_OPCODE_TGSI_TEX2,
  62.    TOY_OPCODE_TGSI_TXB2,
  63.    TOY_OPCODE_TGSI_TXL2,
  64.    TOY_OPCODE_TGSI_SAMPLE,
  65.    TOY_OPCODE_TGSI_SAMPLE_I,
  66.    TOY_OPCODE_TGSI_SAMPLE_I_MS,
  67.    TOY_OPCODE_TGSI_SAMPLE_B,
  68.    TOY_OPCODE_TGSI_SAMPLE_C,
  69.    TOY_OPCODE_TGSI_SAMPLE_C_LZ,
  70.    TOY_OPCODE_TGSI_SAMPLE_D,
  71.    TOY_OPCODE_TGSI_SAMPLE_L,
  72.    TOY_OPCODE_TGSI_GATHER4,
  73.    TOY_OPCODE_TGSI_SVIEWINFO,
  74.    TOY_OPCODE_TGSI_SAMPLE_POS,
  75.    TOY_OPCODE_TGSI_SAMPLE_INFO,
  76.  
  77.    /* math functions */
  78.    TOY_OPCODE_INV,
  79.    TOY_OPCODE_LOG,
  80.    TOY_OPCODE_EXP,
  81.    TOY_OPCODE_SQRT,
  82.    TOY_OPCODE_RSQ,
  83.    TOY_OPCODE_SIN,
  84.    TOY_OPCODE_COS,
  85.    TOY_OPCODE_FDIV,
  86.    TOY_OPCODE_POW,
  87.    TOY_OPCODE_INT_DIV_QUOTIENT,
  88.    TOY_OPCODE_INT_DIV_REMAINDER,
  89.  
  90.    /* URB functions */
  91.    TOY_OPCODE_URB_WRITE,
  92.  
  93.    /* GS-specific functions */
  94.    TOY_OPCODE_EMIT,
  95.    TOY_OPCODE_ENDPRIM,
  96.  
  97.    /* FS-specific functions */
  98.    TOY_OPCODE_DDX,
  99.    TOY_OPCODE_DDY,
  100.    TOY_OPCODE_FB_WRITE,
  101.    TOY_OPCODE_KIL,
  102. };
  103.  
  104. /**
  105.  * Toy instruction.
  106.  */
  107. struct toy_inst {
  108.    unsigned opcode:8;            /* enum toy_opcode      */
  109.    unsigned access_mode:1;       /* BRW_ALIGN_x          */
  110.    unsigned mask_ctrl:1;         /* BRW_MASK_x           */
  111.    unsigned dep_ctrl:2;          /* BRW_DEPENDENCY_x     */
  112.    unsigned qtr_ctrl:2;          /* GEN6_COMPRESSION_x   */
  113.    unsigned thread_ctrl:2;       /* BRW_THREAD_x         */
  114.    unsigned pred_ctrl:4;         /* BRW_PREDICATE_x      */
  115.    unsigned pred_inv:1;          /* true or false        */
  116.    unsigned exec_size:3;         /* BRW_EXECUTE_x        */
  117.    unsigned cond_modifier:4;     /* BRW_CONDITIONAL_x    */
  118.    unsigned acc_wr_ctrl:1;       /* true or false        */
  119.    unsigned saturate:1;          /* true or false        */
  120.  
  121.    /* true if the instruction should be ignored for instruction iteration */
  122.    unsigned marker:1;
  123.  
  124.    unsigned pad:1;
  125.  
  126.    struct toy_dst dst;
  127.    struct toy_src src[5];        /* match TGSI_FULL_MAX_SRC_REGISTERS */
  128.  
  129.    struct {
  130.       int target;                /* TGSI_TEXTURE_x */
  131.       struct toy_src offsets[1]; /* need to be 4 when GATHER4 is supported */
  132.    } tex;
  133.  
  134.    struct list_head list;
  135. };
  136.  
  137. /**
  138.  * Toy compiler.
  139.  */
  140. struct toy_compiler {
  141.    const struct ilo_dev_info *dev;
  142.  
  143.    struct toy_inst templ;
  144.    struct util_slab_mempool mempool;
  145.    struct list_head instructions;
  146.    struct list_head *iter, *iter_next;
  147.  
  148.    /* this is not set until toy_compiler_legalize_for_asm() */
  149.    int num_instructions;
  150.  
  151.    int rect_linear_width;
  152.    int next_vrf;
  153.  
  154.    bool fail;
  155.    const char *reason;
  156. };
  157.  
  158. /**
  159.  * Allocate the given number of VRF registers.
  160.  */
  161. static inline int
  162. tc_alloc_vrf(struct toy_compiler *tc, int count)
  163. {
  164.    const int vrf = tc->next_vrf;
  165.  
  166.    tc->next_vrf += count;
  167.  
  168.    return vrf;
  169. }
  170.  
  171. /**
  172.  * Allocate a temporary register.
  173.  */
  174. static inline struct toy_dst
  175. tc_alloc_tmp(struct toy_compiler *tc)
  176. {
  177.    return tdst(TOY_FILE_VRF, tc_alloc_vrf(tc, 1), 0);
  178. }
  179.  
  180. /**
  181.  * Allocate four temporary registers.
  182.  */
  183. static inline void
  184. tc_alloc_tmp4(struct toy_compiler *tc, struct toy_dst *tmp)
  185. {
  186.    tmp[0] = tc_alloc_tmp(tc);
  187.    tmp[1] = tc_alloc_tmp(tc);
  188.    tmp[2] = tc_alloc_tmp(tc);
  189.    tmp[3] = tc_alloc_tmp(tc);
  190. }
  191.  
  192. /**
  193.  * Duplicate an instruction at the current location.
  194.  */
  195. static inline struct toy_inst *
  196. tc_duplicate_inst(struct toy_compiler *tc, const struct toy_inst *inst)
  197. {
  198.    struct toy_inst *new_inst;
  199.  
  200.    new_inst = util_slab_alloc(&tc->mempool);
  201.    if (!new_inst)
  202.       return NULL;
  203.  
  204.    *new_inst = *inst;
  205.    list_addtail(&new_inst->list, tc->iter_next);
  206.  
  207.    return new_inst;
  208. }
  209.  
  210. /**
  211.  * Move an instruction to the current location.
  212.  */
  213. static inline void
  214. tc_move_inst(struct toy_compiler *tc, struct toy_inst *inst)
  215. {
  216.    list_del(&inst->list);
  217.    list_addtail(&inst->list, tc->iter_next);
  218. }
  219.  
  220. /**
  221.  * Discard an instruction.
  222.  */
  223. static inline void
  224. tc_discard_inst(struct toy_compiler *tc, struct toy_inst *inst)
  225. {
  226.    list_del(&inst->list);
  227.    util_slab_free(&tc->mempool, inst);
  228. }
  229.  
  230. /**
  231.  * Add a new instruction at the current location, using tc->templ as the
  232.  * template.
  233.  */
  234. static inline struct toy_inst *
  235. tc_add(struct toy_compiler *tc)
  236. {
  237.    return tc_duplicate_inst(tc, &tc->templ);
  238. }
  239.  
  240. /**
  241.  * A convenient version of tc_add() for instructions with 3 source operands.
  242.  */
  243. static inline struct toy_inst *
  244. tc_add3(struct toy_compiler *tc, unsigned opcode,
  245.         struct toy_dst dst,
  246.         struct toy_src src0,
  247.         struct toy_src src1,
  248.         struct toy_src src2)
  249. {
  250.    struct toy_inst *inst;
  251.  
  252.    inst = tc_add(tc);
  253.    if (!inst)
  254.       return NULL;
  255.  
  256.    inst->opcode = opcode;
  257.    inst->dst = dst;
  258.    inst->src[0] = src0;
  259.    inst->src[1] = src1;
  260.    inst->src[2] = src2;
  261.  
  262.    return inst;
  263. }
  264.  
  265. /**
  266.  * A convenient version of tc_add() for instructions with 2 source operands.
  267.  */
  268. static inline struct toy_inst *
  269. tc_add2(struct toy_compiler *tc, int opcode,
  270.             struct toy_dst dst,
  271.             struct toy_src src0,
  272.             struct toy_src src1)
  273. {
  274.    return tc_add3(tc, opcode, dst, src0, src1, tsrc_null());
  275. }
  276.  
  277. /**
  278.  * A convenient version of tc_add() for instructions with 1 source operand.
  279.  */
  280. static inline struct toy_inst *
  281. tc_add1(struct toy_compiler *tc, unsigned opcode,
  282.         struct toy_dst dst,
  283.         struct toy_src src0)
  284. {
  285.    return tc_add2(tc, opcode, dst, src0, tsrc_null());
  286. }
  287.  
  288. /**
  289.  * A convenient version of tc_add() for instructions without source or
  290.  * destination operands.
  291.  */
  292. static inline struct toy_inst *
  293. tc_add0(struct toy_compiler *tc, unsigned opcode)
  294. {
  295.    return tc_add1(tc, opcode, tdst_null(), tsrc_null());
  296. }
  297.  
  298. #define TC_ALU0(func, opcode)             \
  299. static inline struct toy_inst *           \
  300. func(struct toy_compiler *tc)             \
  301. {                                         \
  302.    return tc_add0(tc, opcode);            \
  303. }
  304.  
  305. #define TC_ALU1(func, opcode)             \
  306. static inline struct toy_inst *           \
  307. func(struct toy_compiler *tc,             \
  308.      struct toy_dst dst,                  \
  309.      struct toy_src src)                  \
  310. {                                         \
  311.    return tc_add1(tc, opcode, dst, src);  \
  312. }
  313.  
  314. #define TC_ALU2(func, opcode)             \
  315. static inline struct toy_inst *           \
  316. func(struct toy_compiler *tc,             \
  317.      struct toy_dst dst,                  \
  318.      struct toy_src src0,                 \
  319.      struct toy_src src1)                 \
  320. {                                         \
  321.    return tc_add2(tc, opcode,             \
  322.          dst, src0, src1);                \
  323. }
  324.  
  325. #define TC_ALU3(func, opcode)             \
  326. static inline struct toy_inst *           \
  327. func(struct toy_compiler *tc,             \
  328.      struct toy_dst dst,                  \
  329.      struct toy_src src0,                 \
  330.      struct toy_src src1,                 \
  331.      struct toy_src src2)                 \
  332. {                                         \
  333.    return tc_add3(tc, opcode,             \
  334.          dst, src0, src1, src2);          \
  335. }
  336.  
  337. #define TC_CND2(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.      unsigned cond_modifier)              \
  344. {                                         \
  345.    struct toy_inst *inst;                 \
  346.    inst = tc_add2(tc, opcode,             \
  347.          dst, src0, src1);                \
  348.    inst->cond_modifier = cond_modifier;   \
  349.    return inst;                           \
  350. }
  351.  
  352. TC_ALU0(tc_NOP, BRW_OPCODE_NOP)
  353. TC_ALU0(tc_ELSE, BRW_OPCODE_ELSE)
  354. TC_ALU0(tc_ENDIF, BRW_OPCODE_ENDIF)
  355. TC_ALU1(tc_MOV, BRW_OPCODE_MOV)
  356. TC_ALU1(tc_RNDD, BRW_OPCODE_RNDD)
  357. TC_ALU1(tc_INV, TOY_OPCODE_INV)
  358. TC_ALU1(tc_FRC, BRW_OPCODE_FRC)
  359. TC_ALU1(tc_EXP, TOY_OPCODE_EXP)
  360. TC_ALU1(tc_LOG, TOY_OPCODE_LOG)
  361. TC_ALU2(tc_ADD, BRW_OPCODE_ADD)
  362. TC_ALU2(tc_MUL, BRW_OPCODE_MUL)
  363. TC_ALU2(tc_AND, BRW_OPCODE_AND)
  364. TC_ALU2(tc_OR, BRW_OPCODE_OR)
  365. TC_ALU2(tc_DP2, BRW_OPCODE_DP2)
  366. TC_ALU2(tc_DP3, BRW_OPCODE_DP3)
  367. TC_ALU2(tc_DP4, BRW_OPCODE_DP4)
  368. TC_ALU2(tc_SHL, BRW_OPCODE_SHL)
  369. TC_ALU2(tc_SHR, BRW_OPCODE_SHR)
  370. TC_ALU2(tc_POW, TOY_OPCODE_POW)
  371. TC_ALU3(tc_MAC, BRW_OPCODE_MAC)
  372. TC_CND2(tc_SEL, BRW_OPCODE_SEL)
  373. TC_CND2(tc_CMP, BRW_OPCODE_CMP)
  374. TC_CND2(tc_IF, BRW_OPCODE_IF)
  375. TC_CND2(tc_SEND, BRW_OPCODE_SEND)
  376.  
  377. /**
  378.  * Upcast a list_head to an instruction.
  379.  */
  380. static inline struct toy_inst *
  381. tc_list_to_inst(struct toy_compiler *tc, struct list_head *item)
  382. {
  383.    return container_of(item, (struct toy_inst *) NULL, list);
  384. }
  385.  
  386. /**
  387.  * Return the instruction at the current location.
  388.  */
  389. static inline struct toy_inst *
  390. tc_current(struct toy_compiler *tc)
  391. {
  392.    return (tc->iter != &tc->instructions) ?
  393.       tc_list_to_inst(tc, tc->iter) : NULL;
  394. }
  395.  
  396. /**
  397.  * Set the current location to the head.
  398.  */
  399. static inline void
  400. tc_head(struct toy_compiler *tc)
  401. {
  402.    tc->iter = &tc->instructions;
  403.    tc->iter_next = tc->iter->next;
  404. }
  405.  
  406. /**
  407.  * Set the current location to the tail.
  408.  */
  409. static inline void
  410. tc_tail(struct toy_compiler *tc)
  411. {
  412.    tc->iter = &tc->instructions;
  413.    tc->iter_next = tc->iter;
  414. }
  415.  
  416. /**
  417.  * Advance the current location.
  418.  */
  419. static inline struct toy_inst *
  420. tc_next_no_skip(struct toy_compiler *tc)
  421. {
  422.    /* stay at the tail so that new instructions are added there */
  423.    if (tc->iter_next == &tc->instructions) {
  424.       tc_tail(tc);
  425.       return NULL;
  426.    }
  427.  
  428.    tc->iter = tc->iter_next;
  429.    tc->iter_next = tc->iter_next->next;
  430.  
  431.    return tc_list_to_inst(tc, tc->iter);
  432. }
  433.  
  434. /**
  435.  * Advance the current location, skipping markers.
  436.  */
  437. static inline struct toy_inst *
  438. tc_next(struct toy_compiler *tc)
  439. {
  440.    struct toy_inst *inst;
  441.  
  442.    do {
  443.       inst = tc_next_no_skip(tc);
  444.    } while (inst && inst->marker);
  445.  
  446.    return inst;
  447. }
  448.  
  449. static inline void
  450. tc_fail(struct toy_compiler *tc, const char *reason)
  451. {
  452.    if (!tc->fail) {
  453.       tc->fail = true;
  454.       tc->reason = reason;
  455.    }
  456. }
  457.  
  458. void
  459. toy_compiler_init(struct toy_compiler *tc, const struct ilo_dev_info *dev);
  460.  
  461. void
  462. toy_compiler_cleanup(struct toy_compiler *tc);
  463.  
  464. void
  465. toy_compiler_dump(struct toy_compiler *tc);
  466.  
  467. void *
  468. toy_compiler_assemble(struct toy_compiler *tc, int *size);
  469.  
  470. void
  471. toy_compiler_disassemble(struct toy_compiler *tc, const void *kernel, int size);
  472.  
  473. #endif /* TOY_COMPILER_H */
  474.