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. #include "toy_compiler.h"
  29.  
  30. /**
  31.  * Dump an operand.
  32.  */
  33. static void
  34. tc_dump_operand(struct toy_compiler *tc,
  35.                 enum toy_file file, enum toy_type type, enum toy_rect rect,
  36.                 bool indirect, unsigned indirect_subreg, uint32_t val32,
  37.                 bool is_dst)
  38. {
  39.    static const char *toy_file_names[TOY_FILE_COUNT] = {
  40.       [TOY_FILE_VRF]        = "v",
  41.       [TOY_FILE_ARF]        = "NOT USED",
  42.       [TOY_FILE_GRF]        = "r",
  43.       [TOY_FILE_MRF]        = "m",
  44.       [TOY_FILE_IMM]        = "NOT USED",
  45.    };
  46.    const char *name = toy_file_names[file];
  47.    int reg, subreg;
  48.  
  49.    if (file != TOY_FILE_IMM) {
  50.       reg = val32 / TOY_REG_WIDTH;
  51.       subreg = (val32 % TOY_REG_WIDTH) / toy_type_size(type);
  52.    }
  53.  
  54.    switch (file) {
  55.    case TOY_FILE_GRF:
  56.       if (indirect) {
  57.          const int addr_subreg = indirect_subreg / toy_type_size(TOY_TYPE_UW);
  58.  
  59.          ilo_printf("%s[a0.%d", name, addr_subreg);
  60.          if (val32)
  61.             ilo_printf("%+d", (int) val32);
  62.          ilo_printf("]");
  63.          break;
  64.       }
  65.       /* fall through */
  66.    case TOY_FILE_VRF:
  67.    case TOY_FILE_MRF:
  68.       ilo_printf("%s%d", name, reg);
  69.       if (subreg)
  70.          ilo_printf(".%d", subreg);
  71.       break;
  72.    case TOY_FILE_ARF:
  73.       switch (reg) {
  74.       case BRW_ARF_NULL:
  75.          ilo_printf("null");
  76.          break;
  77.       case BRW_ARF_ADDRESS:
  78.          ilo_printf("a0.%d", subreg);
  79.          break;
  80.       case BRW_ARF_ACCUMULATOR:
  81.       case BRW_ARF_ACCUMULATOR + 1:
  82.          ilo_printf("acc%d.%d", (reg & 1), subreg);
  83.          break;
  84.       case BRW_ARF_FLAG:
  85.          ilo_printf("f0.%d", subreg);
  86.          break;
  87.       case BRW_ARF_STATE:
  88.          ilo_printf("sr0.%d", subreg);
  89.          break;
  90.       case BRW_ARF_CONTROL:
  91.          ilo_printf("cr0.%d", subreg);
  92.          break;
  93.       case BRW_ARF_NOTIFICATION_COUNT:
  94.       case BRW_ARF_NOTIFICATION_COUNT + 1:
  95.          ilo_printf("n%d.%d", (reg & 1), subreg);
  96.          break;
  97.       case BRW_ARF_IP:
  98.          ilo_printf("ip");
  99.          break;
  100.       }
  101.       break;
  102.    case TOY_FILE_IMM:
  103.       switch (type) {
  104.       case TOY_TYPE_F:
  105.          {
  106.             union fi fi = { .ui = val32 };
  107.             ilo_printf("%f", fi.f);
  108.          }
  109.          break;
  110.       case TOY_TYPE_D:
  111.          ilo_printf("%d", (int32_t) val32);
  112.          break;
  113.       case TOY_TYPE_UD:
  114.          ilo_printf("%u", val32);
  115.          break;
  116.       case TOY_TYPE_W:
  117.          ilo_printf("%d", (int16_t) (val32 & 0xffff));
  118.          break;
  119.       case TOY_TYPE_UW:
  120.          ilo_printf("%u", val32 & 0xffff);
  121.          break;
  122.       case TOY_TYPE_V:
  123.          ilo_printf("0x%08x", val32);
  124.          break;
  125.       default:
  126.          assert(!"unknown imm type");
  127.          break;
  128.       }
  129.       break;
  130.    default:
  131.       assert(!"unexpected file");
  132.       break;
  133.    }
  134.  
  135.    /* dump the region parameter */
  136.    if (file != TOY_FILE_IMM) {
  137.       int vert_stride, width, horz_stride;
  138.  
  139.       switch (rect) {
  140.       case TOY_RECT_LINEAR:
  141.          vert_stride = tc->rect_linear_width;
  142.          width = tc->rect_linear_width;
  143.          horz_stride = 1;
  144.          break;
  145.       case TOY_RECT_041:
  146.          vert_stride = 0;
  147.          width = 4;
  148.          horz_stride = 1;
  149.          break;
  150.       case TOY_RECT_010:
  151.          vert_stride = 0;
  152.          width = 1;
  153.          horz_stride = 0;
  154.          break;
  155.       case TOY_RECT_220:
  156.          vert_stride = 2;
  157.          width = 2;
  158.          horz_stride = 0;
  159.          break;
  160.       case TOY_RECT_440:
  161.          vert_stride = 4;
  162.          width = 4;
  163.          horz_stride = 0;
  164.          break;
  165.       case TOY_RECT_240:
  166.          vert_stride = 2;
  167.          width = 4;
  168.          horz_stride = 0;
  169.          break;
  170.       default:
  171.          assert(!"unknown rect parameter");
  172.          vert_stride = 0;
  173.          width = 0;
  174.          horz_stride = 0;
  175.          break;
  176.       }
  177.  
  178.       if (is_dst)
  179.          ilo_printf("<%d>", horz_stride);
  180.       else
  181.          ilo_printf("<%d;%d,%d>", vert_stride, width, horz_stride);
  182.    }
  183.  
  184.    switch (type) {
  185.    case TOY_TYPE_F:
  186.       ilo_printf(":f");
  187.       break;
  188.    case TOY_TYPE_D:
  189.       ilo_printf(":d");
  190.       break;
  191.    case TOY_TYPE_UD:
  192.       ilo_printf(":ud");
  193.       break;
  194.    case TOY_TYPE_W:
  195.       ilo_printf(":w");
  196.       break;
  197.    case TOY_TYPE_UW:
  198.       ilo_printf(":uw");
  199.       break;
  200.    case TOY_TYPE_V:
  201.       ilo_printf(":v");
  202.       break;
  203.    default:
  204.       assert(!"unexpected type");
  205.       break;
  206.    }
  207. }
  208.  
  209. /**
  210.  * Dump a source operand.
  211.  */
  212. static void
  213. tc_dump_src(struct toy_compiler *tc, struct toy_src src)
  214. {
  215.    if (src.negate)
  216.       ilo_printf("-");
  217.    if (src.absolute)
  218.       ilo_printf("|");
  219.  
  220.    tc_dump_operand(tc, src.file, src.type, src.rect,
  221.          src.indirect, src.indirect_subreg, src.val32, false);
  222.  
  223.    if (tsrc_is_swizzled(src)) {
  224.       const char xyzw[] = "xyzw";
  225.       ilo_printf(".%c%c%c%c",
  226.             xyzw[src.swizzle_x],
  227.             xyzw[src.swizzle_y],
  228.             xyzw[src.swizzle_z],
  229.             xyzw[src.swizzle_w]);
  230.    }
  231.  
  232.    if (src.absolute)
  233.       ilo_printf("|");
  234. }
  235.  
  236. /**
  237.  * Dump a destination operand.
  238.  */
  239. static void
  240. tc_dump_dst(struct toy_compiler *tc, struct toy_dst dst)
  241. {
  242.    tc_dump_operand(tc, dst.file, dst.type, dst.rect,
  243.          dst.indirect, dst.indirect_subreg, dst.val32, true);
  244.  
  245.    if (dst.writemask != TOY_WRITEMASK_XYZW) {
  246.       ilo_printf(".");
  247.       if (dst.writemask & TOY_WRITEMASK_X)
  248.          ilo_printf("x");
  249.       if (dst.writemask & TOY_WRITEMASK_Y)
  250.          ilo_printf("y");
  251.       if (dst.writemask & TOY_WRITEMASK_Z)
  252.          ilo_printf("z");
  253.       if (dst.writemask & TOY_WRITEMASK_W)
  254.          ilo_printf("w");
  255.    }
  256. }
  257.  
  258. static const char *
  259. get_opcode_name(unsigned opcode)
  260. {
  261.    switch (opcode) {
  262.    case BRW_OPCODE_MOV:                   return "mov";
  263.    case BRW_OPCODE_SEL:                   return "sel";
  264.    case BRW_OPCODE_NOT:                   return "not";
  265.    case BRW_OPCODE_AND:                   return "and";
  266.    case BRW_OPCODE_OR:                    return "or";
  267.    case BRW_OPCODE_XOR:                   return "xor";
  268.    case BRW_OPCODE_SHR:                   return "shr";
  269.    case BRW_OPCODE_SHL:                   return "shl";
  270.    case BRW_OPCODE_RSR:                   return "rsr";
  271.    case BRW_OPCODE_RSL:                   return "rsl";
  272.    case BRW_OPCODE_ASR:                   return "asr";
  273.    case BRW_OPCODE_CMP:                   return "cmp";
  274.    case BRW_OPCODE_CMPN:                  return "cmpn";
  275.    case BRW_OPCODE_JMPI:                  return "jmpi";
  276.    case BRW_OPCODE_IF:                    return "if";
  277.    case BRW_OPCODE_IFF:                   return "iff";
  278.    case BRW_OPCODE_ELSE:                  return "else";
  279.    case BRW_OPCODE_ENDIF:                 return "endif";
  280.    case BRW_OPCODE_DO:                    return "do";
  281.    case BRW_OPCODE_WHILE:                 return "while";
  282.    case BRW_OPCODE_BREAK:                 return "break";
  283.    case BRW_OPCODE_CONTINUE:              return "continue";
  284.    case BRW_OPCODE_HALT:                  return "halt";
  285.    case BRW_OPCODE_MSAVE:                 return "msave";
  286.    case BRW_OPCODE_MRESTORE:              return "mrestore";
  287.    case BRW_OPCODE_PUSH:                  return "push";
  288.    case BRW_OPCODE_POP:                   return "pop";
  289.    case BRW_OPCODE_WAIT:                  return "wait";
  290.    case BRW_OPCODE_SEND:                  return "send";
  291.    case BRW_OPCODE_SENDC:                 return "sendc";
  292.    case BRW_OPCODE_MATH:                  return "math";
  293.    case BRW_OPCODE_ADD:                   return "add";
  294.    case BRW_OPCODE_MUL:                   return "mul";
  295.    case BRW_OPCODE_AVG:                   return "avg";
  296.    case BRW_OPCODE_FRC:                   return "frc";
  297.    case BRW_OPCODE_RNDU:                  return "rndu";
  298.    case BRW_OPCODE_RNDD:                  return "rndd";
  299.    case BRW_OPCODE_RNDE:                  return "rnde";
  300.    case BRW_OPCODE_RNDZ:                  return "rndz";
  301.    case BRW_OPCODE_MAC:                   return "mac";
  302.    case BRW_OPCODE_MACH:                  return "mach";
  303.    case BRW_OPCODE_LZD:                   return "lzd";
  304.    case BRW_OPCODE_SAD2:                  return "sad2";
  305.    case BRW_OPCODE_SADA2:                 return "sada2";
  306.    case BRW_OPCODE_DP4:                   return "dp4";
  307.    case BRW_OPCODE_DPH:                   return "dph";
  308.    case BRW_OPCODE_DP3:                   return "dp3";
  309.    case BRW_OPCODE_DP2:                   return "dp2";
  310.    case BRW_OPCODE_DPA2:                  return "dpa2";
  311.    case BRW_OPCODE_LINE:                  return "line";
  312.    case BRW_OPCODE_PLN:                   return "pln";
  313.    case BRW_OPCODE_MAD:                   return "mad";
  314.    case BRW_OPCODE_NOP:                   return "nop";
  315.    /* TGSI */
  316.    case TOY_OPCODE_TGSI_IN:               return "tgsi.in";
  317.    case TOY_OPCODE_TGSI_CONST:            return "tgsi.const";
  318.    case TOY_OPCODE_TGSI_SV:               return "tgsi.sv";
  319.    case TOY_OPCODE_TGSI_IMM:              return "tgsi.imm";
  320.    case TOY_OPCODE_TGSI_INDIRECT_FETCH:   return "tgsi.indirect_fetch";
  321.    case TOY_OPCODE_TGSI_INDIRECT_STORE:   return "tgsi.indirect_store";
  322.    case TOY_OPCODE_TGSI_TEX:              return "tgsi.tex";
  323.    case TOY_OPCODE_TGSI_TXB:              return "tgsi.txb";
  324.    case TOY_OPCODE_TGSI_TXD:              return "tgsi.txd";
  325.    case TOY_OPCODE_TGSI_TXL:              return "tgsi.txl";
  326.    case TOY_OPCODE_TGSI_TXP:              return "tgsi.txp";
  327.    case TOY_OPCODE_TGSI_TXF:              return "tgsi.txf";
  328.    case TOY_OPCODE_TGSI_TXQ:              return "tgsi.txq";
  329.    case TOY_OPCODE_TGSI_TXQ_LZ:           return "tgsi.txq_lz";
  330.    case TOY_OPCODE_TGSI_TEX2:             return "tgsi.tex2";
  331.    case TOY_OPCODE_TGSI_TXB2:             return "tgsi.txb2";
  332.    case TOY_OPCODE_TGSI_TXL2:             return "tgsi.txl2";
  333.    case TOY_OPCODE_TGSI_SAMPLE:           return "tgsi.sample";
  334.    case TOY_OPCODE_TGSI_SAMPLE_I:         return "tgsi.sample_i";
  335.    case TOY_OPCODE_TGSI_SAMPLE_I_MS:      return "tgsi.sample_i_ms";
  336.    case TOY_OPCODE_TGSI_SAMPLE_B:         return "tgsi.sample_b";
  337.    case TOY_OPCODE_TGSI_SAMPLE_C:         return "tgsi.sample_c";
  338.    case TOY_OPCODE_TGSI_SAMPLE_C_LZ:      return "tgsi.sample_c_lz";
  339.    case TOY_OPCODE_TGSI_SAMPLE_D:         return "tgsi.sample_d";
  340.    case TOY_OPCODE_TGSI_SAMPLE_L:         return "tgsi.sample_l";
  341.    case TOY_OPCODE_TGSI_GATHER4:          return "tgsi.gather4";
  342.    case TOY_OPCODE_TGSI_SVIEWINFO:        return "tgsi.sviewinfo";
  343.    case TOY_OPCODE_TGSI_SAMPLE_POS:       return "tgsi.sample_pos";
  344.    case TOY_OPCODE_TGSI_SAMPLE_INFO:      return "tgsi.sample_info";
  345.    /* math */
  346.    case TOY_OPCODE_INV:                   return "math.inv";
  347.    case TOY_OPCODE_LOG:                   return "math.log";
  348.    case TOY_OPCODE_EXP:                   return "math.exp";
  349.    case TOY_OPCODE_SQRT:                  return "math.sqrt";
  350.    case TOY_OPCODE_RSQ:                   return "math.rsq";
  351.    case TOY_OPCODE_SIN:                   return "math.sin";
  352.    case TOY_OPCODE_COS:                   return "math.cos";
  353.    case TOY_OPCODE_FDIV:                  return "math.fdiv";
  354.    case TOY_OPCODE_POW:                   return "math.pow";
  355.    case TOY_OPCODE_INT_DIV_QUOTIENT:      return "math.int_div_quotient";
  356.    case TOY_OPCODE_INT_DIV_REMAINDER:     return "math.int_div_remainer";
  357.    /* urb */
  358.    case TOY_OPCODE_URB_WRITE:             return "urb.urb_write";
  359.    /* gs */
  360.    case TOY_OPCODE_EMIT:                  return "gs.emit";
  361.    case TOY_OPCODE_ENDPRIM:               return "gs.endprim";
  362.    /* fs */
  363.    case TOY_OPCODE_DDX:                   return "fs.ddx";
  364.    case TOY_OPCODE_DDY:                   return "fs.ddy";
  365.    case TOY_OPCODE_FB_WRITE:              return "fs.fb_write";
  366.    case TOY_OPCODE_KIL:                   return "fs.kil";
  367.    default:                               return "unk";
  368.    }
  369. }
  370.  
  371. static const char *
  372. get_cond_modifier_name(unsigned opcode, unsigned cond_modifier)
  373. {
  374.    switch (opcode) {
  375.    case BRW_OPCODE_SEND:
  376.    case BRW_OPCODE_SENDC:
  377.       /* SFID */
  378.       switch (cond_modifier) {
  379.       case BRW_SFID_NULL:                       return "Null";
  380.       case BRW_SFID_SAMPLER:                    return "Sampling Engine";
  381.       case BRW_SFID_MESSAGE_GATEWAY:            return "Message Gateway";
  382.       case GEN6_SFID_DATAPORT_SAMPLER_CACHE:    return "Data Port Sampler Cache";
  383.       case GEN6_SFID_DATAPORT_RENDER_CACHE:     return "Data Port Render Cache";
  384.       case BRW_SFID_URB:                        return "URB";
  385.       case BRW_SFID_THREAD_SPAWNER:             return "Thread Spawner";
  386.       case GEN6_SFID_DATAPORT_CONSTANT_CACHE:   return "Constant Cache";
  387.       default:                                  return "Unknown";
  388.       }
  389.       break;
  390.    case BRW_OPCODE_MATH:
  391.       /* FC */
  392.       switch (cond_modifier) {
  393.       case BRW_MATH_FUNCTION_INV:               return "INV";
  394.       case BRW_MATH_FUNCTION_LOG:               return "LOG";
  395.       case BRW_MATH_FUNCTION_EXP:               return "EXP";
  396.       case BRW_MATH_FUNCTION_SQRT:              return "SQRT";
  397.       case BRW_MATH_FUNCTION_RSQ:               return "RSQ";
  398.       case BRW_MATH_FUNCTION_SIN:               return "SIN";
  399.       case BRW_MATH_FUNCTION_COS:               return "COS";
  400.       case BRW_MATH_FUNCTION_FDIV:              return "FDIV";
  401.       case BRW_MATH_FUNCTION_POW:               return "POW";
  402.       case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT:  return "INT DIV (quotient)";
  403.       case BRW_MATH_FUNCTION_INT_DIV_REMAINDER: return "INT DIV (remainder)";
  404.       default:                                  return "UNK";
  405.       }
  406.       break;
  407.    default:
  408.       switch (cond_modifier) {
  409.       case BRW_CONDITIONAL_NONE:                return NULL;
  410.       case BRW_CONDITIONAL_Z:                   return "z";
  411.       case BRW_CONDITIONAL_NZ:                  return "nz";
  412.       case BRW_CONDITIONAL_G:                   return "g";
  413.       case BRW_CONDITIONAL_GE:                  return "ge";
  414.       case BRW_CONDITIONAL_L:                   return "l";
  415.       case BRW_CONDITIONAL_LE:                  return "le";
  416.       default:                                  return "unk";
  417.       }
  418.       break;
  419.    }
  420. }
  421.  
  422. /**
  423.  * Dump an instruction.
  424.  */
  425. static void
  426. tc_dump_inst(struct toy_compiler *tc, const struct toy_inst *inst)
  427. {
  428.    const char *name;
  429.    int i;
  430.  
  431.    name = get_opcode_name(inst->opcode);
  432.  
  433.    ilo_printf("  %s", name);
  434.  
  435.    if (inst->opcode == BRW_OPCODE_NOP) {
  436.       ilo_printf("\n");
  437.       return;
  438.    }
  439.  
  440.    if (inst->saturate)
  441.       ilo_printf(".sat");
  442.  
  443.    name = get_cond_modifier_name(inst->opcode, inst->cond_modifier);
  444.    if (name)
  445.       ilo_printf(".%s", name);
  446.  
  447.    ilo_printf(" ");
  448.  
  449.    tc_dump_dst(tc, inst->dst);
  450.  
  451.    for (i = 0; i < Elements(inst->src); i++) {
  452.       if (tsrc_is_null(inst->src[i]))
  453.          break;
  454.  
  455.       ilo_printf(", ");
  456.       tc_dump_src(tc, inst->src[i]);
  457.    }
  458.  
  459.    ilo_printf("\n");
  460. }
  461.  
  462. /**
  463.  * Dump the instructions added to the compiler.
  464.  */
  465. void
  466. toy_compiler_dump(struct toy_compiler *tc)
  467. {
  468.    struct toy_inst *inst;
  469.    int pc;
  470.  
  471.    pc = 0;
  472.    tc_head(tc);
  473.    while ((inst = tc_next_no_skip(tc)) != NULL) {
  474.       /* we do not generate code for markers */
  475.       if (inst->marker)
  476.          ilo_printf("marker:");
  477.       else
  478.          ilo_printf("%6d:", pc++);
  479.  
  480.       tc_dump_inst(tc, inst);
  481.    }
  482. }
  483.  
  484. /**
  485.  * Clean up the toy compiler.
  486.  */
  487. void
  488. toy_compiler_cleanup(struct toy_compiler *tc)
  489. {
  490.    struct toy_inst *inst, *next;
  491.  
  492.    LIST_FOR_EACH_ENTRY_SAFE(inst, next, &tc->instructions, list)
  493.       util_slab_free(&tc->mempool, inst);
  494.  
  495.    util_slab_destroy(&tc->mempool);
  496. }
  497.  
  498. /**
  499.  * Initialize the instruction template, from which tc_add() initializes the
  500.  * newly added instructions.
  501.  */
  502. static void
  503. tc_init_inst_templ(struct toy_compiler *tc)
  504. {
  505.    struct toy_inst *templ = &tc->templ;
  506.    int i;
  507.  
  508.    templ->opcode = BRW_OPCODE_NOP;
  509.    templ->access_mode = BRW_ALIGN_1;
  510.    templ->mask_ctrl = BRW_MASK_ENABLE;
  511.    templ->dep_ctrl = BRW_DEPENDENCY_NORMAL;
  512.    templ->qtr_ctrl = GEN6_COMPRESSION_1Q;
  513.    templ->thread_ctrl = BRW_THREAD_NORMAL;
  514.    templ->pred_ctrl = BRW_PREDICATE_NONE;
  515.    templ->pred_inv = false;
  516.    templ->exec_size = BRW_EXECUTE_1;
  517.    templ->cond_modifier = BRW_CONDITIONAL_NONE;
  518.    templ->acc_wr_ctrl = false;
  519.    templ->saturate = false;
  520.  
  521.    templ->marker = false;
  522.  
  523.    templ->dst = tdst_null();
  524.    for (i = 0; i < Elements(templ->src); i++)
  525.       templ->src[i] = tsrc_null();
  526.  
  527.    for (i = 0; i < Elements(templ->tex.offsets); i++)
  528.       templ->tex.offsets[i] = tsrc_null();
  529.  
  530.    list_inithead(&templ->list);
  531. }
  532.  
  533. /**
  534.  * Initialize the toy compiler.
  535.  */
  536. void
  537. toy_compiler_init(struct toy_compiler *tc, const struct ilo_dev_info *dev)
  538. {
  539.    memset(tc, 0, sizeof(*tc));
  540.  
  541.    tc->dev = dev;
  542.  
  543.    tc_init_inst_templ(tc);
  544.  
  545.    util_slab_create(&tc->mempool, sizeof(struct toy_inst),
  546.          64, UTIL_SLAB_SINGLETHREADED);
  547.  
  548.    list_inithead(&tc->instructions);
  549.    /* instructions are added to the tail */
  550.    tc_tail(tc);
  551.  
  552.    tc->rect_linear_width = 1;
  553.  
  554.    /* skip 0 so that util_hash_table_get() never returns NULL */
  555.    tc->next_vrf = 1;
  556. }
  557.