Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "util/u_debug.h"
  29. #include "util/u_memory.h"
  30. #include "util/u_prim.h"
  31. #include "pipe/p_defines.h"
  32. #include "util/u_inlines.h"
  33. #include "tgsi_text.h"
  34. #include "tgsi_build.h"
  35. #include "tgsi_info.h"
  36. #include "tgsi_parse.h"
  37. #include "tgsi_sanity.h"
  38. #include "tgsi_strings.h"
  39. #include "tgsi_util.h"
  40. #include "tgsi_dump.h"
  41.  
  42. static boolean is_alpha_underscore( const char *cur )
  43. {
  44.    return
  45.       (*cur >= 'a' && *cur <= 'z') ||
  46.       (*cur >= 'A' && *cur <= 'Z') ||
  47.       *cur == '_';
  48. }
  49.  
  50. static boolean is_digit( const char *cur )
  51. {
  52.    return *cur >= '0' && *cur <= '9';
  53. }
  54.  
  55. static boolean is_digit_alpha_underscore( const char *cur )
  56. {
  57.    return is_digit( cur ) || is_alpha_underscore( cur );
  58. }
  59.  
  60. static char uprcase( char c )
  61. {
  62.    if (c >= 'a' && c <= 'z')
  63.       return c + 'A' - 'a';
  64.    return c;
  65. }
  66.  
  67. /*
  68.  * Ignore case of str1 and assume str1 is already uppercase.
  69.  * Return TRUE iff str1 and str2 are equal.
  70.  */
  71. static int
  72. streq_nocase_uprcase(const char *str1,
  73.                      const char *str2)
  74. {
  75.    while (*str1 && *str2) {
  76.       if (*str1 != uprcase(*str2))
  77.          return FALSE;
  78.       str1++;
  79.       str2++;
  80.    }
  81.    return *str1 == 0 && *str2 == 0;
  82. }
  83.  
  84. /* Return TRUE if both strings match.
  85.  * The second string is terminated by zero.
  86.  * The pointer to the first string is moved at end of the read word
  87.  * on success.
  88.  */
  89. static boolean str_match_no_case( const char **pcur, const char *str )
  90. {
  91.    const char *cur = *pcur;
  92.  
  93.    while (*str != '\0' && *str == uprcase( *cur )) {
  94.       str++;
  95.       cur++;
  96.    }
  97.    if (*str == '\0') {
  98.       *pcur = cur;
  99.       return TRUE;
  100.    }
  101.    return FALSE;
  102. }
  103.  
  104. /* Return TRUE if both strings match.
  105.  * The first string is be terminated by a non-digit non-letter non-underscore
  106.  * character, the second string is terminated by zero.
  107.  * The pointer to the first string is moved at end of the read word
  108.  * on success.
  109.  */
  110. static boolean str_match_nocase_whole( const char **pcur, const char *str )
  111. {
  112.    const char *cur = *pcur;
  113.  
  114.    if (str_match_no_case(&cur, str) &&
  115.        !is_digit_alpha_underscore(cur)) {
  116.       *pcur = cur;
  117.       return TRUE;
  118.    }
  119.    return FALSE;
  120. }
  121.  
  122. /* Eat zero or more whitespaces.
  123.  */
  124. static void eat_opt_white( const char **pcur )
  125. {
  126.    while (**pcur == ' ' || **pcur == '\t' || **pcur == '\n')
  127.       (*pcur)++;
  128. }
  129.  
  130. /* Eat one or more whitespaces.
  131.  * Return TRUE if at least one whitespace eaten.
  132.  */
  133. static boolean eat_white( const char **pcur )
  134. {
  135.    const char *cur = *pcur;
  136.  
  137.    eat_opt_white( pcur );
  138.    return *pcur > cur;
  139. }
  140.  
  141. /* Parse unsigned integer.
  142.  * No checks for overflow.
  143.  */
  144. static boolean parse_uint( const char **pcur, uint *val )
  145. {
  146.    const char *cur = *pcur;
  147.  
  148.    if (is_digit( cur )) {
  149.       *val = *cur++ - '0';
  150.       while (is_digit( cur ))
  151.          *val = *val * 10 + *cur++ - '0';
  152.       *pcur = cur;
  153.       return TRUE;
  154.    }
  155.    return FALSE;
  156. }
  157.  
  158. static boolean parse_int( const char **pcur, int *val )
  159. {
  160.    const char *cur = *pcur;
  161.    int sign = (*cur == '-' ? -1 : 1);
  162.  
  163.    if (*cur == '+' || *cur == '-')
  164.       cur++;
  165.  
  166.    if (parse_uint(&cur, (uint *)val)) {
  167.       *val *= sign;
  168.       *pcur = cur;
  169.       return TRUE;
  170.    }
  171.  
  172.    return FALSE;
  173. }
  174.  
  175. static boolean parse_identifier( const char **pcur, char *ret )
  176. {
  177.    const char *cur = *pcur;
  178.    int i = 0;
  179.    if (is_alpha_underscore( cur )) {
  180.       ret[i++] = *cur++;
  181.       while (is_alpha_underscore( cur ) || is_digit( cur ))
  182.          ret[i++] = *cur++;
  183.       ret[i++] = '\0';
  184.       *pcur = cur;
  185.       return TRUE;
  186.    }
  187.    return FALSE;
  188. }
  189.  
  190. /* Parse floating point.
  191.  */
  192. static boolean parse_float( const char **pcur, float *val )
  193. {
  194.    const char *cur = *pcur;
  195.    boolean integral_part = FALSE;
  196.    boolean fractional_part = FALSE;
  197.  
  198.    *val = (float) atof( cur );
  199.  
  200.    if (*cur == '-' || *cur == '+')
  201.       cur++;
  202.    if (is_digit( cur )) {
  203.       cur++;
  204.       integral_part = TRUE;
  205.       while (is_digit( cur ))
  206.          cur++;
  207.    }
  208.    if (*cur == '.') {
  209.       cur++;
  210.       if (is_digit( cur )) {
  211.          cur++;
  212.          fractional_part = TRUE;
  213.          while (is_digit( cur ))
  214.             cur++;
  215.       }
  216.    }
  217.    if (!integral_part && !fractional_part)
  218.       return FALSE;
  219.    if (uprcase( *cur ) == 'E') {
  220.       cur++;
  221.       if (*cur == '-' || *cur == '+')
  222.          cur++;
  223.       if (is_digit( cur )) {
  224.          cur++;
  225.          while (is_digit( cur ))
  226.             cur++;
  227.       }
  228.       else
  229.          return FALSE;
  230.    }
  231.    *pcur = cur;
  232.    return TRUE;
  233. }
  234.  
  235. struct translate_ctx
  236. {
  237.    const char *text;
  238.    const char *cur;
  239.    struct tgsi_token *tokens;
  240.    struct tgsi_token *tokens_cur;
  241.    struct tgsi_token *tokens_end;
  242.    struct tgsi_header *header;
  243.    unsigned processor : 4;
  244.    int implied_array_size : 5;
  245.    unsigned num_immediates;
  246. };
  247.  
  248. static void report_error( struct translate_ctx *ctx, const char *msg )
  249. {
  250.    int line = 1;
  251.    int column = 1;
  252.    const char *itr = ctx->text;
  253.  
  254.    while (itr != ctx->cur) {
  255.       if (*itr == '\n') {
  256.          column = 1;
  257.          ++line;
  258.       }
  259.       ++column;
  260.       ++itr;
  261.    }
  262.  
  263.    debug_printf( "\nTGSI asm error: %s [%d : %d] \n", msg, line, column );
  264. }
  265.  
  266. /* Parse shader header.
  267.  * Return TRUE for one of the following headers.
  268.  *    FRAG
  269.  *    GEOM
  270.  *    VERT
  271.  */
  272. static boolean parse_header( struct translate_ctx *ctx )
  273. {
  274.    uint processor;
  275.  
  276.    if (str_match_nocase_whole( &ctx->cur, "FRAG" ))
  277.       processor = TGSI_PROCESSOR_FRAGMENT;
  278.    else if (str_match_nocase_whole( &ctx->cur, "VERT" ))
  279.       processor = TGSI_PROCESSOR_VERTEX;
  280.    else if (str_match_nocase_whole( &ctx->cur, "GEOM" ))
  281.       processor = TGSI_PROCESSOR_GEOMETRY;
  282.    else if (str_match_nocase_whole( &ctx->cur, "COMP" ))
  283.       processor = TGSI_PROCESSOR_COMPUTE;
  284.    else {
  285.       report_error( ctx, "Unknown header" );
  286.       return FALSE;
  287.    }
  288.  
  289.    if (ctx->tokens_cur >= ctx->tokens_end)
  290.       return FALSE;
  291.    ctx->header = (struct tgsi_header *) ctx->tokens_cur++;
  292.    *ctx->header = tgsi_build_header();
  293.  
  294.    if (ctx->tokens_cur >= ctx->tokens_end)
  295.       return FALSE;
  296.    *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header );
  297.    ctx->processor = processor;
  298.  
  299.    return TRUE;
  300. }
  301.  
  302. static boolean parse_label( struct translate_ctx *ctx, uint *val )
  303. {
  304.    const char *cur = ctx->cur;
  305.  
  306.    if (parse_uint( &cur, val )) {
  307.       eat_opt_white( &cur );
  308.       if (*cur == ':') {
  309.          cur++;
  310.          ctx->cur = cur;
  311.          return TRUE;
  312.       }
  313.    }
  314.    return FALSE;
  315. }
  316.  
  317. static boolean
  318. parse_file( const char **pcur, uint *file )
  319. {
  320.    uint i;
  321.  
  322.    for (i = 0; i < TGSI_FILE_COUNT; i++) {
  323.       const char *cur = *pcur;
  324.  
  325.       if (str_match_nocase_whole( &cur, tgsi_file_name(i) )) {
  326.          *pcur = cur;
  327.          *file = i;
  328.          return TRUE;
  329.       }
  330.    }
  331.    return FALSE;
  332. }
  333.  
  334. static boolean
  335. parse_opt_writemask(
  336.    struct translate_ctx *ctx,
  337.    uint *writemask )
  338. {
  339.    const char *cur;
  340.  
  341.    cur = ctx->cur;
  342.    eat_opt_white( &cur );
  343.    if (*cur == '.') {
  344.       cur++;
  345.       *writemask = TGSI_WRITEMASK_NONE;
  346.       eat_opt_white( &cur );
  347.       if (uprcase( *cur ) == 'X') {
  348.          cur++;
  349.          *writemask |= TGSI_WRITEMASK_X;
  350.       }
  351.       if (uprcase( *cur ) == 'Y') {
  352.          cur++;
  353.          *writemask |= TGSI_WRITEMASK_Y;
  354.       }
  355.       if (uprcase( *cur ) == 'Z') {
  356.          cur++;
  357.          *writemask |= TGSI_WRITEMASK_Z;
  358.       }
  359.       if (uprcase( *cur ) == 'W') {
  360.          cur++;
  361.          *writemask |= TGSI_WRITEMASK_W;
  362.       }
  363.  
  364.       if (*writemask == TGSI_WRITEMASK_NONE) {
  365.          report_error( ctx, "Writemask expected" );
  366.          return FALSE;
  367.       }
  368.  
  369.       ctx->cur = cur;
  370.    }
  371.    else {
  372.       *writemask = TGSI_WRITEMASK_XYZW;
  373.    }
  374.    return TRUE;
  375. }
  376.  
  377.  
  378. /* <register_file_bracket> ::= <file> `['
  379.  */
  380. static boolean
  381. parse_register_file_bracket(
  382.    struct translate_ctx *ctx,
  383.    uint *file )
  384. {
  385.    if (!parse_file( &ctx->cur, file )) {
  386.       report_error( ctx, "Unknown register file" );
  387.       return FALSE;
  388.    }
  389.    eat_opt_white( &ctx->cur );
  390.    if (*ctx->cur != '[') {
  391.       report_error( ctx, "Expected `['" );
  392.       return FALSE;
  393.    }
  394.    ctx->cur++;
  395.    return TRUE;
  396. }
  397.  
  398. /* <register_file_bracket_index> ::= <register_file_bracket> <uint>
  399.  */
  400. static boolean
  401. parse_register_file_bracket_index(
  402.    struct translate_ctx *ctx,
  403.    uint *file,
  404.    int *index )
  405. {
  406.    uint uindex;
  407.  
  408.    if (!parse_register_file_bracket( ctx, file ))
  409.       return FALSE;
  410.    eat_opt_white( &ctx->cur );
  411.    if (!parse_uint( &ctx->cur, &uindex )) {
  412.       report_error( ctx, "Expected literal unsigned integer" );
  413.       return FALSE;
  414.    }
  415.    *index = (int) uindex;
  416.    return TRUE;
  417. }
  418.  
  419. /* Parse simple 1d register operand.
  420.  *    <register_dst> ::= <register_file_bracket_index> `]'
  421.  */
  422. static boolean
  423. parse_register_1d(struct translate_ctx *ctx,
  424.                   uint *file,
  425.                   int *index )
  426. {
  427.    if (!parse_register_file_bracket_index( ctx, file, index ))
  428.       return FALSE;
  429.    eat_opt_white( &ctx->cur );
  430.    if (*ctx->cur != ']') {
  431.       report_error( ctx, "Expected `]'" );
  432.       return FALSE;
  433.    }
  434.    ctx->cur++;
  435.    return TRUE;
  436. }
  437.  
  438. struct parsed_bracket {
  439.    int index;
  440.  
  441.    uint ind_file;
  442.    int ind_index;
  443.    uint ind_comp;
  444.    uint ind_array;
  445. };
  446.  
  447.  
  448. static boolean
  449. parse_register_bracket(
  450.    struct translate_ctx *ctx,
  451.    struct parsed_bracket *brackets)
  452. {
  453.    const char *cur;
  454.    uint uindex;
  455.  
  456.    memset(brackets, 0, sizeof(struct parsed_bracket));
  457.  
  458.    eat_opt_white( &ctx->cur );
  459.  
  460.    cur = ctx->cur;
  461.    if (parse_file( &cur, &brackets->ind_file )) {
  462.       if (!parse_register_1d( ctx, &brackets->ind_file,
  463.                               &brackets->ind_index ))
  464.          return FALSE;
  465.       eat_opt_white( &ctx->cur );
  466.  
  467.       if (*ctx->cur == '.') {
  468.          ctx->cur++;
  469.          eat_opt_white(&ctx->cur);
  470.  
  471.          switch (uprcase(*ctx->cur)) {
  472.          case 'X':
  473.             brackets->ind_comp = TGSI_SWIZZLE_X;
  474.             break;
  475.          case 'Y':
  476.             brackets->ind_comp = TGSI_SWIZZLE_Y;
  477.             break;
  478.          case 'Z':
  479.             brackets->ind_comp = TGSI_SWIZZLE_Z;
  480.             break;
  481.          case 'W':
  482.             brackets->ind_comp = TGSI_SWIZZLE_W;
  483.             break;
  484.          default:
  485.             report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'");
  486.             return FALSE;
  487.          }
  488.          ctx->cur++;
  489.          eat_opt_white(&ctx->cur);
  490.       }
  491.  
  492.       if (*ctx->cur == '+' || *ctx->cur == '-')
  493.          parse_int( &ctx->cur, &brackets->index );
  494.       else
  495.          brackets->index = 0;
  496.    }
  497.    else {
  498.       if (!parse_uint( &ctx->cur, &uindex )) {
  499.          report_error( ctx, "Expected literal unsigned integer" );
  500.          return FALSE;
  501.       }
  502.       brackets->index = (int) uindex;
  503.       brackets->ind_file = TGSI_FILE_NULL;
  504.       brackets->ind_index = 0;
  505.    }
  506.    eat_opt_white( &ctx->cur );
  507.    if (*ctx->cur != ']') {
  508.       report_error( ctx, "Expected `]'" );
  509.       return FALSE;
  510.    }
  511.    ctx->cur++;
  512.    if (*ctx->cur == '(') {
  513.       ctx->cur++;
  514.       eat_opt_white( &ctx->cur );
  515.       if (!parse_uint( &ctx->cur, &brackets->ind_array )) {
  516.          report_error( ctx, "Expected literal unsigned integer" );
  517.          return FALSE;
  518.       }
  519.       eat_opt_white( &ctx->cur );
  520.       if (*ctx->cur != ')') {
  521.          report_error( ctx, "Expected `)'" );
  522.          return FALSE;
  523.       }
  524.       ctx->cur++;
  525.    }
  526.    return TRUE;
  527. }
  528.  
  529. static boolean
  530. parse_opt_register_src_bracket(
  531.    struct translate_ctx *ctx,
  532.    struct parsed_bracket *brackets,
  533.    int *parsed_brackets)
  534. {
  535.    const char *cur = ctx->cur;
  536.  
  537.    *parsed_brackets = 0;
  538.  
  539.    eat_opt_white( &cur );
  540.    if (cur[0] == '[') {
  541.       ++cur;
  542.       ctx->cur = cur;
  543.  
  544.       if (!parse_register_bracket(ctx, brackets))
  545.          return FALSE;
  546.  
  547.       *parsed_brackets = 1;
  548.    }
  549.  
  550.    return TRUE;
  551. }
  552.  
  553.  
  554. /* Parse source register operand.
  555.  *    <register_src> ::= <register_file_bracket_index> `]' |
  556.  *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
  557.  *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
  558.  *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
  559.  */
  560. static boolean
  561. parse_register_src(
  562.    struct translate_ctx *ctx,
  563.    uint *file,
  564.    struct parsed_bracket *brackets)
  565. {
  566.    brackets->ind_comp = TGSI_SWIZZLE_X;
  567.    if (!parse_register_file_bracket( ctx, file ))
  568.       return FALSE;
  569.    if (!parse_register_bracket( ctx, brackets ))
  570.        return FALSE;
  571.  
  572.    return TRUE;
  573. }
  574.  
  575. struct parsed_dcl_bracket {
  576.    uint first;
  577.    uint last;
  578. };
  579.  
  580. static boolean
  581. parse_register_dcl_bracket(
  582.    struct translate_ctx *ctx,
  583.    struct parsed_dcl_bracket *bracket)
  584. {
  585.    uint uindex;
  586.    memset(bracket, 0, sizeof(struct parsed_dcl_bracket));
  587.  
  588.    eat_opt_white( &ctx->cur );
  589.  
  590.    if (!parse_uint( &ctx->cur, &uindex )) {
  591.       /* it can be an empty bracket [] which means its range
  592.        * is from 0 to some implied size */
  593.       if (ctx->cur[0] == ']' && ctx->implied_array_size != 0) {
  594.          bracket->first = 0;
  595.          bracket->last = ctx->implied_array_size - 1;
  596.          goto cleanup;
  597.       }
  598.       report_error( ctx, "Expected literal unsigned integer" );
  599.       return FALSE;
  600.    }
  601.    bracket->first = uindex;
  602.  
  603.    eat_opt_white( &ctx->cur );
  604.  
  605.    if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
  606.       uint uindex;
  607.  
  608.       ctx->cur += 2;
  609.       eat_opt_white( &ctx->cur );
  610.       if (!parse_uint( &ctx->cur, &uindex )) {
  611.          report_error( ctx, "Expected literal integer" );
  612.          return FALSE;
  613.       }
  614.       bracket->last = (int) uindex;
  615.       eat_opt_white( &ctx->cur );
  616.    }
  617.    else {
  618.       bracket->last = bracket->first;
  619.    }
  620.  
  621. cleanup:
  622.    if (*ctx->cur != ']') {
  623.       report_error( ctx, "Expected `]' or `..'" );
  624.       return FALSE;
  625.    }
  626.    ctx->cur++;
  627.    return TRUE;
  628. }
  629.  
  630. /* Parse register declaration.
  631.  *    <register_dcl> ::= <register_file_bracket_index> `]' |
  632.  *                       <register_file_bracket_index> `..' <index> `]'
  633.  */
  634. static boolean
  635. parse_register_dcl(
  636.    struct translate_ctx *ctx,
  637.    uint *file,
  638.    struct parsed_dcl_bracket *brackets,
  639.    int *num_brackets)
  640. {
  641.    const char *cur;
  642.  
  643.    *num_brackets = 0;
  644.  
  645.    if (!parse_register_file_bracket( ctx, file ))
  646.       return FALSE;
  647.    if (!parse_register_dcl_bracket( ctx, &brackets[0] ))
  648.       return FALSE;
  649.  
  650.    *num_brackets = 1;
  651.  
  652.    cur = ctx->cur;
  653.    eat_opt_white( &cur );
  654.  
  655.    if (cur[0] == '[') {
  656.       ++cur;
  657.       ctx->cur = cur;
  658.       if (!parse_register_dcl_bracket( ctx, &brackets[1] ))
  659.          return FALSE;
  660.       /* for geometry shader we don't really care about
  661.        * the first brackets it's always the size of the
  662.        * input primitive. so we want to declare just
  663.        * the index relevant to the semantics which is in
  664.        * the second bracket */
  665.       if (ctx->processor == TGSI_PROCESSOR_GEOMETRY && *file == TGSI_FILE_INPUT) {
  666.          brackets[0] = brackets[1];
  667.          *num_brackets = 1;
  668.       } else {
  669.          *num_brackets = 2;
  670.       }
  671.    }
  672.  
  673.    return TRUE;
  674. }
  675.  
  676.  
  677. /* Parse destination register operand.*/
  678. static boolean
  679. parse_register_dst(
  680.    struct translate_ctx *ctx,
  681.    uint *file,
  682.    struct parsed_bracket *brackets)
  683. {
  684.    brackets->ind_comp = TGSI_SWIZZLE_X;
  685.    if (!parse_register_file_bracket( ctx, file ))
  686.       return FALSE;
  687.    if (!parse_register_bracket( ctx, brackets ))
  688.        return FALSE;
  689.  
  690.    return TRUE;
  691. }
  692.  
  693. static boolean
  694. parse_dst_operand(
  695.    struct translate_ctx *ctx,
  696.    struct tgsi_full_dst_register *dst )
  697. {
  698.    uint file;
  699.    uint writemask;
  700.    const char *cur;
  701.    struct parsed_bracket bracket[2];
  702.    int parsed_opt_brackets;
  703.  
  704.    if (!parse_register_dst( ctx, &file, &bracket[0] ))
  705.       return FALSE;
  706.    if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
  707.       return FALSE;
  708.  
  709.    cur = ctx->cur;
  710.    eat_opt_white( &cur );
  711.  
  712.    if (!parse_opt_writemask( ctx, &writemask ))
  713.       return FALSE;
  714.  
  715.    dst->Register.File = file;
  716.    if (parsed_opt_brackets) {
  717.       dst->Register.Dimension = 1;
  718.       dst->Dimension.Indirect = 0;
  719.       dst->Dimension.Dimension = 0;
  720.       dst->Dimension.Index = bracket[0].index;
  721.       bracket[0] = bracket[1];
  722.    }
  723.    dst->Register.Index = bracket[0].index;
  724.    dst->Register.WriteMask = writemask;
  725.    if (bracket[0].ind_file != TGSI_FILE_NULL) {
  726.       dst->Register.Indirect = 1;
  727.       dst->Indirect.File = bracket[0].ind_file;
  728.       dst->Indirect.Index = bracket[0].ind_index;
  729.       dst->Indirect.Swizzle = bracket[0].ind_comp;
  730.       dst->Indirect.ArrayID = bracket[0].ind_array;
  731.    }
  732.    return TRUE;
  733. }
  734.  
  735. static boolean
  736. parse_optional_swizzle(
  737.    struct translate_ctx *ctx,
  738.    uint swizzle[4],
  739.    boolean *parsed_swizzle )
  740. {
  741.    const char *cur = ctx->cur;
  742.  
  743.    *parsed_swizzle = FALSE;
  744.  
  745.    eat_opt_white( &cur );
  746.    if (*cur == '.') {
  747.       uint i;
  748.  
  749.       cur++;
  750.       eat_opt_white( &cur );
  751.       for (i = 0; i < 4; i++) {
  752.          if (uprcase( *cur ) == 'X')
  753.             swizzle[i] = TGSI_SWIZZLE_X;
  754.          else if (uprcase( *cur ) == 'Y')
  755.             swizzle[i] = TGSI_SWIZZLE_Y;
  756.          else if (uprcase( *cur ) == 'Z')
  757.             swizzle[i] = TGSI_SWIZZLE_Z;
  758.          else if (uprcase( *cur ) == 'W')
  759.             swizzle[i] = TGSI_SWIZZLE_W;
  760.          else {
  761.             report_error( ctx, "Expected register swizzle component `x', `y', `z' or `w'" );
  762.             return FALSE;
  763.          }
  764.          cur++;
  765.       }
  766.       *parsed_swizzle = TRUE;
  767.       ctx->cur = cur;
  768.    }
  769.    return TRUE;
  770. }
  771.  
  772. static boolean
  773. parse_src_operand(
  774.    struct translate_ctx *ctx,
  775.    struct tgsi_full_src_register *src )
  776. {
  777.    uint file;
  778.    uint swizzle[4];
  779.    boolean parsed_swizzle;
  780.    struct parsed_bracket bracket[2];
  781.    int parsed_opt_brackets;
  782.  
  783.    if (*ctx->cur == '-') {
  784.       ctx->cur++;
  785.       eat_opt_white( &ctx->cur );
  786.       src->Register.Negate = 1;
  787.    }
  788.  
  789.    if (*ctx->cur == '|') {
  790.       ctx->cur++;
  791.       eat_opt_white( &ctx->cur );
  792.       src->Register.Absolute = 1;
  793.    }
  794.  
  795.    if (!parse_register_src(ctx, &file, &bracket[0]))
  796.       return FALSE;
  797.    if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
  798.       return FALSE;
  799.  
  800.    src->Register.File = file;
  801.    if (parsed_opt_brackets) {
  802.       src->Register.Dimension = 1;
  803.       src->Dimension.Indirect = 0;
  804.       src->Dimension.Dimension = 0;
  805.       src->Dimension.Index = bracket[0].index;
  806.       bracket[0] = bracket[1];
  807.    }
  808.    src->Register.Index = bracket[0].index;
  809.    if (bracket[0].ind_file != TGSI_FILE_NULL) {
  810.       src->Register.Indirect = 1;
  811.       src->Indirect.File = bracket[0].ind_file;
  812.       src->Indirect.Index = bracket[0].ind_index;
  813.       src->Indirect.Swizzle = bracket[0].ind_comp;
  814.       src->Indirect.ArrayID = bracket[0].ind_array;
  815.    }
  816.  
  817.    /* Parse optional swizzle.
  818.     */
  819.    if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
  820.       if (parsed_swizzle) {
  821.          src->Register.SwizzleX = swizzle[0];
  822.          src->Register.SwizzleY = swizzle[1];
  823.          src->Register.SwizzleZ = swizzle[2];
  824.          src->Register.SwizzleW = swizzle[3];
  825.       }
  826.    }
  827.  
  828.    if (src->Register.Absolute) {
  829.       eat_opt_white( &ctx->cur );
  830.       if (*ctx->cur != '|') {
  831.          report_error( ctx, "Expected `|'" );
  832.          return FALSE;
  833.       }
  834.       ctx->cur++;
  835.    }
  836.  
  837.  
  838.    return TRUE;
  839. }
  840.  
  841. static boolean
  842. match_inst(const char **pcur,
  843.            unsigned *saturate,
  844.            const struct tgsi_opcode_info *info)
  845. {
  846.    const char *cur = *pcur;
  847.  
  848.    /* simple case: the whole string matches the instruction name */
  849.    if (str_match_nocase_whole(&cur, info->mnemonic)) {
  850.       *pcur = cur;
  851.       *saturate = TGSI_SAT_NONE;
  852.       return TRUE;
  853.    }
  854.  
  855.    if (str_match_no_case(&cur, info->mnemonic)) {
  856.       /* the instruction has a suffix, figure it out */
  857.       if (str_match_nocase_whole(&cur, "_SAT")) {
  858.          *pcur = cur;
  859.          *saturate = TGSI_SAT_ZERO_ONE;
  860.          return TRUE;
  861.       }
  862.  
  863.       if (str_match_nocase_whole(&cur, "_SATNV")) {
  864.          *pcur = cur;
  865.          *saturate = TGSI_SAT_MINUS_PLUS_ONE;
  866.          return TRUE;
  867.       }
  868.    }
  869.  
  870.    return FALSE;
  871. }
  872.  
  873. static boolean
  874. parse_instruction(
  875.    struct translate_ctx *ctx,
  876.    boolean has_label )
  877. {
  878.    uint i;
  879.    uint saturate = TGSI_SAT_NONE;
  880.    const struct tgsi_opcode_info *info;
  881.    struct tgsi_full_instruction inst;
  882.    const char *cur;
  883.    uint advance;
  884.  
  885.    inst = tgsi_default_full_instruction();
  886.  
  887.    /* Parse predicate.
  888.     */
  889.    eat_opt_white( &ctx->cur );
  890.    if (*ctx->cur == '(') {
  891.       uint file;
  892.       int index;
  893.       uint swizzle[4];
  894.       boolean parsed_swizzle;
  895.  
  896.       inst.Instruction.Predicate = 1;
  897.  
  898.       ctx->cur++;
  899.       if (*ctx->cur == '!') {
  900.          ctx->cur++;
  901.          inst.Predicate.Negate = 1;
  902.       }
  903.  
  904.       if (!parse_register_1d( ctx, &file, &index ))
  905.          return FALSE;
  906.  
  907.       if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
  908.          if (parsed_swizzle) {
  909.             inst.Predicate.SwizzleX = swizzle[0];
  910.             inst.Predicate.SwizzleY = swizzle[1];
  911.             inst.Predicate.SwizzleZ = swizzle[2];
  912.             inst.Predicate.SwizzleW = swizzle[3];
  913.          }
  914.       }
  915.  
  916.       if (*ctx->cur != ')') {
  917.          report_error( ctx, "Expected `)'" );
  918.          return FALSE;
  919.       }
  920.  
  921.       ctx->cur++;
  922.    }
  923.  
  924.    /* Parse instruction name.
  925.     */
  926.    eat_opt_white( &ctx->cur );
  927.    for (i = 0; i < TGSI_OPCODE_LAST; i++) {
  928.       cur = ctx->cur;
  929.  
  930.       info = tgsi_get_opcode_info( i );
  931.       if (match_inst(&cur, &saturate, info)) {
  932.          if (info->num_dst + info->num_src + info->is_tex == 0) {
  933.             ctx->cur = cur;
  934.             break;
  935.          }
  936.          else if (*cur == '\0' || eat_white( &cur )) {
  937.             ctx->cur = cur;
  938.             break;
  939.          }
  940.       }
  941.    }
  942.    if (i == TGSI_OPCODE_LAST) {
  943.       if (has_label)
  944.          report_error( ctx, "Unknown opcode" );
  945.       else
  946.          report_error( ctx, "Expected `DCL', `IMM' or a label" );
  947.       return FALSE;
  948.    }
  949.  
  950.    inst.Instruction.Opcode = i;
  951.    inst.Instruction.Saturate = saturate;
  952.    inst.Instruction.NumDstRegs = info->num_dst;
  953.    inst.Instruction.NumSrcRegs = info->num_src;
  954.  
  955.    if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
  956.       /*
  957.        * These are not considered tex opcodes here (no additional
  958.        * target argument) however we're required to set the Texture
  959.        * bit so we can set the number of tex offsets (offsets aren't
  960.        * actually handled here yet in any case).
  961.        */
  962.       inst.Instruction.Texture = 1;
  963.       inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
  964.    }
  965.  
  966.    /* Parse instruction operands.
  967.     */
  968.    for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
  969.       if (i > 0) {
  970.          eat_opt_white( &ctx->cur );
  971.          if (*ctx->cur != ',') {
  972.             report_error( ctx, "Expected `,'" );
  973.             return FALSE;
  974.          }
  975.          ctx->cur++;
  976.          eat_opt_white( &ctx->cur );
  977.       }
  978.  
  979.       if (i < info->num_dst) {
  980.          if (!parse_dst_operand( ctx, &inst.Dst[i] ))
  981.             return FALSE;
  982.       }
  983.       else if (i < info->num_dst + info->num_src) {
  984.          if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
  985.             return FALSE;
  986.       }
  987.       else {
  988.          uint j;
  989.  
  990.          for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
  991.             if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
  992.                inst.Instruction.Texture = 1;
  993.                inst.Texture.Texture = j;
  994.                break;
  995.             }
  996.          }
  997.          if (j == TGSI_TEXTURE_COUNT) {
  998.             report_error( ctx, "Expected texture target" );
  999.             return FALSE;
  1000.          }
  1001.       }
  1002.    }
  1003.  
  1004.    cur = ctx->cur;
  1005.    eat_opt_white( &cur );
  1006.    if (info->is_branch && *cur == ':') {
  1007.       uint target;
  1008.  
  1009.       cur++;
  1010.       eat_opt_white( &cur );
  1011.       if (!parse_uint( &cur, &target )) {
  1012.          report_error( ctx, "Expected a label" );
  1013.          return FALSE;
  1014.       }
  1015.       inst.Instruction.Label = 1;
  1016.       inst.Label.Label = target;
  1017.       ctx->cur = cur;
  1018.    }
  1019.  
  1020.    advance = tgsi_build_full_instruction(
  1021.       &inst,
  1022.       ctx->tokens_cur,
  1023.       ctx->header,
  1024.       (uint) (ctx->tokens_end - ctx->tokens_cur) );
  1025.    if (advance == 0)
  1026.       return FALSE;
  1027.    ctx->tokens_cur += advance;
  1028.  
  1029.    return TRUE;
  1030. }
  1031.  
  1032. /* parses a 4-touple of the form {x, y, z, w}
  1033.  * where x, y, z, w are numbers */
  1034. static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type,
  1035.                                     union tgsi_immediate_data *values)
  1036. {
  1037.    unsigned i;
  1038.    int ret;
  1039.  
  1040.    eat_opt_white( &ctx->cur );
  1041.    if (*ctx->cur != '{') {
  1042.       report_error( ctx, "Expected `{'" );
  1043.       return FALSE;
  1044.    }
  1045.    ctx->cur++;
  1046.    for (i = 0; i < 4; i++) {
  1047.       eat_opt_white( &ctx->cur );
  1048.       if (i > 0) {
  1049.          if (*ctx->cur != ',') {
  1050.             report_error( ctx, "Expected `,'" );
  1051.             return FALSE;
  1052.          }
  1053.          ctx->cur++;
  1054.          eat_opt_white( &ctx->cur );
  1055.       }
  1056.  
  1057.       switch (type) {
  1058.       case TGSI_IMM_FLOAT32:
  1059.          ret = parse_float(&ctx->cur, &values[i].Float);
  1060.          break;
  1061.       case TGSI_IMM_UINT32:
  1062.          ret = parse_uint(&ctx->cur, &values[i].Uint);
  1063.          break;
  1064.       case TGSI_IMM_INT32:
  1065.          ret = parse_int(&ctx->cur, &values[i].Int);
  1066.          break;
  1067.       default:
  1068.          assert(0);
  1069.          ret = FALSE;
  1070.          break;
  1071.       }
  1072.  
  1073.       if (!ret) {
  1074.          report_error( ctx, "Expected immediate constant" );
  1075.          return FALSE;
  1076.       }
  1077.    }
  1078.    eat_opt_white( &ctx->cur );
  1079.    if (*ctx->cur != '}') {
  1080.       report_error( ctx, "Expected `}'" );
  1081.       return FALSE;
  1082.    }
  1083.    ctx->cur++;
  1084.  
  1085.    return TRUE;
  1086. }
  1087.  
  1088. static boolean parse_declaration( struct translate_ctx *ctx )
  1089. {
  1090.    struct tgsi_full_declaration decl;
  1091.    uint file;
  1092.    struct parsed_dcl_bracket brackets[2];
  1093.    int num_brackets;
  1094.    uint writemask;
  1095.    const char *cur, *cur2;
  1096.    uint advance;
  1097.    boolean is_vs_input;
  1098.  
  1099.    if (!eat_white( &ctx->cur )) {
  1100.       report_error( ctx, "Syntax error" );
  1101.       return FALSE;
  1102.    }
  1103.    if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
  1104.       return FALSE;
  1105.    if (!parse_opt_writemask( ctx, &writemask ))
  1106.       return FALSE;
  1107.  
  1108.    decl = tgsi_default_full_declaration();
  1109.    decl.Declaration.File = file;
  1110.    decl.Declaration.UsageMask = writemask;
  1111.  
  1112.    if (num_brackets == 1) {
  1113.       decl.Range.First = brackets[0].first;
  1114.       decl.Range.Last = brackets[0].last;
  1115.    } else {
  1116.       decl.Range.First = brackets[1].first;
  1117.       decl.Range.Last = brackets[1].last;
  1118.  
  1119.       decl.Declaration.Dimension = 1;
  1120.       decl.Dim.Index2D = brackets[0].first;
  1121.    }
  1122.  
  1123.    is_vs_input = (file == TGSI_FILE_INPUT &&
  1124.                   ctx->processor == TGSI_PROCESSOR_VERTEX);
  1125.  
  1126.    cur = ctx->cur;
  1127.    eat_opt_white( &cur );
  1128.    if (*cur == ',') {
  1129.       cur2 = cur;
  1130.       cur2++;
  1131.       eat_opt_white( &cur2 );
  1132.       if (str_match_nocase_whole( &cur2, "ARRAY" )) {
  1133.          int arrayid;
  1134.          if (*cur2 != '(') {
  1135.             report_error( ctx, "Expected `('" );
  1136.             return FALSE;
  1137.          }
  1138.          cur2++;
  1139.          eat_opt_white( &cur2 );
  1140.          if (!parse_int( &cur2, &arrayid )) {
  1141.             report_error( ctx, "Expected `,'" );
  1142.             return FALSE;
  1143.          }
  1144.          eat_opt_white( &cur2 );
  1145.          if (*cur2 != ')') {
  1146.             report_error( ctx, "Expected `)'" );
  1147.             return FALSE;
  1148.          }
  1149.          cur2++;
  1150.          decl.Declaration.Array = 1;
  1151.          decl.Array.ArrayID = arrayid;
  1152.          ctx->cur = cur = cur2;
  1153.       }
  1154.    }
  1155.  
  1156.    if (*cur == ',' && !is_vs_input) {
  1157.       uint i, j;
  1158.  
  1159.       cur++;
  1160.       eat_opt_white( &cur );
  1161.       if (file == TGSI_FILE_RESOURCE) {
  1162.          for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
  1163.             if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
  1164.                decl.Resource.Resource = i;
  1165.                break;
  1166.             }
  1167.          }
  1168.          if (i == TGSI_TEXTURE_COUNT) {
  1169.             report_error(ctx, "Expected texture target");
  1170.             return FALSE;
  1171.          }
  1172.  
  1173.          cur2 = cur;
  1174.          eat_opt_white(&cur2);
  1175.          while (*cur2 == ',') {
  1176.             cur2++;
  1177.             eat_opt_white(&cur2);
  1178.             if (str_match_nocase_whole(&cur2, "RAW")) {
  1179.                decl.Resource.Raw = 1;
  1180.  
  1181.             } else if (str_match_nocase_whole(&cur2, "WR")) {
  1182.                decl.Resource.Writable = 1;
  1183.  
  1184.             } else {
  1185.                break;
  1186.             }
  1187.             cur = cur2;
  1188.             eat_opt_white(&cur2);
  1189.          }
  1190.  
  1191.          ctx->cur = cur;
  1192.  
  1193.       } else if (file == TGSI_FILE_SAMPLER_VIEW) {
  1194.          for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
  1195.             if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
  1196.                decl.SamplerView.Resource = i;
  1197.                break;
  1198.             }
  1199.          }
  1200.          if (i == TGSI_TEXTURE_COUNT) {
  1201.             report_error(ctx, "Expected texture target");
  1202.             return FALSE;
  1203.          }
  1204.          eat_opt_white( &cur );
  1205.          if (*cur != ',') {
  1206.             report_error( ctx, "Expected `,'" );
  1207.             return FALSE;
  1208.          }
  1209.          ++cur;
  1210.          eat_opt_white( &cur );
  1211.          for (j = 0; j < 4; ++j) {
  1212.             for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
  1213.                if (str_match_nocase_whole(&cur, tgsi_type_names[i])) {
  1214.                   switch (j) {
  1215.                   case 0:
  1216.                      decl.SamplerView.ReturnTypeX = i;
  1217.                      break;
  1218.                   case 1:
  1219.                      decl.SamplerView.ReturnTypeY = i;
  1220.                      break;
  1221.                   case 2:
  1222.                      decl.SamplerView.ReturnTypeZ = i;
  1223.                      break;
  1224.                   case 3:
  1225.                      decl.SamplerView.ReturnTypeW = i;
  1226.                      break;
  1227.                   default:
  1228.                      assert(0);
  1229.                   }
  1230.                   break;
  1231.                }
  1232.             }
  1233.             if (i == PIPE_TYPE_COUNT) {
  1234.                if (j == 0 || j >  2) {
  1235.                   report_error(ctx, "Expected type name");
  1236.                   return FALSE;
  1237.                }
  1238.                break;
  1239.             } else {
  1240.                cur2 = cur;
  1241.                eat_opt_white( &cur2 );
  1242.                if (*cur2 == ',') {
  1243.                   cur2++;
  1244.                   eat_opt_white( &cur2 );
  1245.                   cur = cur2;
  1246.                   continue;
  1247.                } else
  1248.                   break;
  1249.             }
  1250.          }
  1251.          if (j < 4) {
  1252.             decl.SamplerView.ReturnTypeY =
  1253.                decl.SamplerView.ReturnTypeZ =
  1254.                decl.SamplerView.ReturnTypeW =
  1255.                decl.SamplerView.ReturnTypeX;
  1256.          }
  1257.          ctx->cur = cur;
  1258.       } else {
  1259.          if (str_match_nocase_whole(&cur, "LOCAL")) {
  1260.             decl.Declaration.Local = 1;
  1261.             ctx->cur = cur;
  1262.          }
  1263.  
  1264.          cur = ctx->cur;
  1265.          eat_opt_white( &cur );
  1266.          if (*cur == ',') {
  1267.             cur++;
  1268.             eat_opt_white( &cur );
  1269.  
  1270.             for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
  1271.                if (str_match_nocase_whole(&cur, tgsi_semantic_names[i])) {
  1272.                   uint index;
  1273.  
  1274.                   cur2 = cur;
  1275.                   eat_opt_white( &cur2 );
  1276.                   if (*cur2 == '[') {
  1277.                      cur2++;
  1278.                      eat_opt_white( &cur2 );
  1279.                      if (!parse_uint( &cur2, &index )) {
  1280.                         report_error( ctx, "Expected literal integer" );
  1281.                         return FALSE;
  1282.                      }
  1283.                      eat_opt_white( &cur2 );
  1284.                      if (*cur2 != ']') {
  1285.                         report_error( ctx, "Expected `]'" );
  1286.                         return FALSE;
  1287.                      }
  1288.                      cur2++;
  1289.  
  1290.                      decl.Semantic.Index = index;
  1291.  
  1292.                      cur = cur2;
  1293.                   }
  1294.  
  1295.                   decl.Declaration.Semantic = 1;
  1296.                   decl.Semantic.Name = i;
  1297.  
  1298.                   ctx->cur = cur;
  1299.                   break;
  1300.                }
  1301.             }
  1302.          }
  1303.       }
  1304.    }
  1305.  
  1306.    cur = ctx->cur;
  1307.    eat_opt_white( &cur );
  1308.    if (*cur == ',' && !is_vs_input) {
  1309.       uint i;
  1310.  
  1311.       cur++;
  1312.       eat_opt_white( &cur );
  1313.       for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) {
  1314.          if (str_match_nocase_whole( &cur, tgsi_interpolate_names[i] )) {
  1315.             decl.Declaration.Interpolate = 1;
  1316.             decl.Interp.Interpolate = i;
  1317.  
  1318.             ctx->cur = cur;
  1319.             break;
  1320.          }
  1321.       }
  1322.       if (i == TGSI_INTERPOLATE_COUNT) {
  1323.          report_error( ctx, "Expected semantic or interpolate attribute" );
  1324.          return FALSE;
  1325.       }
  1326.    }
  1327.  
  1328.    advance = tgsi_build_full_declaration(
  1329.       &decl,
  1330.       ctx->tokens_cur,
  1331.       ctx->header,
  1332.       (uint) (ctx->tokens_end - ctx->tokens_cur) );
  1333.  
  1334.    if (advance == 0)
  1335.       return FALSE;
  1336.    ctx->tokens_cur += advance;
  1337.  
  1338.    return TRUE;
  1339. }
  1340.  
  1341. static boolean parse_immediate( struct translate_ctx *ctx )
  1342. {
  1343.    struct tgsi_full_immediate imm;
  1344.    uint advance;
  1345.    int type;
  1346.  
  1347.    if (*ctx->cur == '[') {
  1348.       uint uindex;
  1349.  
  1350.       ++ctx->cur;
  1351.  
  1352.       eat_opt_white( &ctx->cur );
  1353.       if (!parse_uint( &ctx->cur, &uindex )) {
  1354.          report_error( ctx, "Expected literal unsigned integer" );
  1355.          return FALSE;
  1356.       }
  1357.  
  1358.       if (uindex != ctx->num_immediates) {
  1359.          report_error( ctx, "Immediates must be sorted" );
  1360.          return FALSE;
  1361.       }
  1362.  
  1363.       eat_opt_white( &ctx->cur );
  1364.       if (*ctx->cur != ']') {
  1365.          report_error( ctx, "Expected `]'" );
  1366.          return FALSE;
  1367.       }
  1368.  
  1369.       ctx->cur++;
  1370.    }
  1371.  
  1372.    if (!eat_white( &ctx->cur )) {
  1373.       report_error( ctx, "Syntax error" );
  1374.       return FALSE;
  1375.    }
  1376.    for (type = 0; type < Elements(tgsi_immediate_type_names); ++type) {
  1377.       if (str_match_nocase_whole(&ctx->cur, tgsi_immediate_type_names[type]))
  1378.          break;
  1379.    }
  1380.    if (type == Elements(tgsi_immediate_type_names)) {
  1381.       report_error( ctx, "Expected immediate type" );
  1382.       return FALSE;
  1383.    }
  1384.  
  1385.    imm = tgsi_default_full_immediate();
  1386.    imm.Immediate.NrTokens += 4;
  1387.    imm.Immediate.DataType = type;
  1388.    parse_immediate_data(ctx, type, imm.u);
  1389.  
  1390.    advance = tgsi_build_full_immediate(
  1391.       &imm,
  1392.       ctx->tokens_cur,
  1393.       ctx->header,
  1394.       (uint) (ctx->tokens_end - ctx->tokens_cur) );
  1395.    if (advance == 0)
  1396.       return FALSE;
  1397.    ctx->tokens_cur += advance;
  1398.  
  1399.    ctx->num_immediates++;
  1400.  
  1401.    return TRUE;
  1402. }
  1403.  
  1404. static boolean
  1405. parse_primitive( const char **pcur, uint *primitive )
  1406. {
  1407.    uint i;
  1408.  
  1409.    for (i = 0; i < PIPE_PRIM_MAX; i++) {
  1410.       const char *cur = *pcur;
  1411.  
  1412.       if (str_match_nocase_whole( &cur, tgsi_primitive_names[i])) {
  1413.          *primitive = i;
  1414.          *pcur = cur;
  1415.          return TRUE;
  1416.       }
  1417.    }
  1418.    return FALSE;
  1419. }
  1420.  
  1421. static boolean
  1422. parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin )
  1423. {
  1424.    uint i;
  1425.  
  1426.    for (i = 0; i < Elements(tgsi_fs_coord_origin_names); i++) {
  1427.       const char *cur = *pcur;
  1428.  
  1429.       if (str_match_nocase_whole( &cur, tgsi_fs_coord_origin_names[i])) {
  1430.          *fs_coord_origin = i;
  1431.          *pcur = cur;
  1432.          return TRUE;
  1433.       }
  1434.    }
  1435.    return FALSE;
  1436. }
  1437.  
  1438. static boolean
  1439. parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center )
  1440. {
  1441.    uint i;
  1442.  
  1443.    for (i = 0; i < Elements(tgsi_fs_coord_pixel_center_names); i++) {
  1444.       const char *cur = *pcur;
  1445.  
  1446.       if (str_match_nocase_whole( &cur, tgsi_fs_coord_pixel_center_names[i])) {
  1447.          *fs_coord_pixel_center = i;
  1448.          *pcur = cur;
  1449.          return TRUE;
  1450.       }
  1451.    }
  1452.    return FALSE;
  1453. }
  1454.  
  1455.  
  1456. static boolean parse_property( struct translate_ctx *ctx )
  1457. {
  1458.    struct tgsi_full_property prop;
  1459.    uint property_name;
  1460.    uint values[8];
  1461.    uint advance;
  1462.    char id[64];
  1463.  
  1464.    if (!eat_white( &ctx->cur )) {
  1465.       report_error( ctx, "Syntax error" );
  1466.       return FALSE;
  1467.    }
  1468.    if (!parse_identifier( &ctx->cur, id )) {
  1469.       report_error( ctx, "Syntax error" );
  1470.       return FALSE;
  1471.    }
  1472.    for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
  1473.         ++property_name) {
  1474.       if (streq_nocase_uprcase(tgsi_property_names[property_name], id)) {
  1475.          break;
  1476.       }
  1477.    }
  1478.    if (property_name >= TGSI_PROPERTY_COUNT) {
  1479.       debug_printf( "\nError: Unknown property : '%s'", id );
  1480.       return FALSE;
  1481.    }
  1482.  
  1483.    eat_opt_white( &ctx->cur );
  1484.    switch(property_name) {
  1485.    case TGSI_PROPERTY_GS_INPUT_PRIM:
  1486.    case TGSI_PROPERTY_GS_OUTPUT_PRIM:
  1487.       if (!parse_primitive(&ctx->cur, &values[0] )) {
  1488.          report_error( ctx, "Unknown primitive name as property!" );
  1489.          return FALSE;
  1490.       }
  1491.       if (property_name == TGSI_PROPERTY_GS_INPUT_PRIM &&
  1492.           ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
  1493.          ctx->implied_array_size = u_vertices_per_prim(values[0]);
  1494.       }
  1495.       break;
  1496.    case TGSI_PROPERTY_FS_COORD_ORIGIN:
  1497.       if (!parse_fs_coord_origin(&ctx->cur, &values[0] )) {
  1498.          report_error( ctx, "Unknown coord origin as property: must be UPPER_LEFT or LOWER_LEFT!" );
  1499.          return FALSE;
  1500.       }
  1501.       break;
  1502.    case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
  1503.       if (!parse_fs_coord_pixel_center(&ctx->cur, &values[0] )) {
  1504.          report_error( ctx, "Unknown coord pixel center as property: must be HALF_INTEGER or INTEGER!" );
  1505.          return FALSE;
  1506.       }
  1507.       break;
  1508.    case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
  1509.    default:
  1510.       if (!parse_uint(&ctx->cur, &values[0] )) {
  1511.          report_error( ctx, "Expected unsigned integer as property!" );
  1512.          return FALSE;
  1513.       }
  1514.    }
  1515.  
  1516.    prop = tgsi_default_full_property();
  1517.    prop.Property.PropertyName = property_name;
  1518.    prop.Property.NrTokens += 1;
  1519.    prop.u[0].Data = values[0];
  1520.  
  1521.    advance = tgsi_build_full_property(
  1522.       &prop,
  1523.       ctx->tokens_cur,
  1524.       ctx->header,
  1525.       (uint) (ctx->tokens_end - ctx->tokens_cur) );
  1526.    if (advance == 0)
  1527.       return FALSE;
  1528.    ctx->tokens_cur += advance;
  1529.  
  1530.    return TRUE;
  1531. }
  1532.  
  1533.  
  1534. static boolean translate( struct translate_ctx *ctx )
  1535. {
  1536.    eat_opt_white( &ctx->cur );
  1537.    if (!parse_header( ctx ))
  1538.       return FALSE;
  1539.  
  1540.    while (*ctx->cur != '\0') {
  1541.       uint label_val = 0;
  1542.       if (!eat_white( &ctx->cur )) {
  1543.          report_error( ctx, "Syntax error" );
  1544.          return FALSE;
  1545.       }
  1546.  
  1547.       if (*ctx->cur == '\0')
  1548.          break;
  1549.       if (parse_label( ctx, &label_val )) {
  1550.          if (!parse_instruction( ctx, TRUE ))
  1551.             return FALSE;
  1552.       }
  1553.       else if (str_match_nocase_whole( &ctx->cur, "DCL" )) {
  1554.          if (!parse_declaration( ctx ))
  1555.             return FALSE;
  1556.       }
  1557.       else if (str_match_nocase_whole( &ctx->cur, "IMM" )) {
  1558.          if (!parse_immediate( ctx ))
  1559.             return FALSE;
  1560.       }
  1561.       else if (str_match_nocase_whole( &ctx->cur, "PROPERTY" )) {
  1562.          if (!parse_property( ctx ))
  1563.             return FALSE;
  1564.       }
  1565.       else if (!parse_instruction( ctx, FALSE )) {
  1566.          return FALSE;
  1567.       }
  1568.    }
  1569.  
  1570.    return TRUE;
  1571. }
  1572.  
  1573. boolean
  1574. tgsi_text_translate(
  1575.    const char *text,
  1576.    struct tgsi_token *tokens,
  1577.    uint num_tokens )
  1578. {
  1579.    struct translate_ctx ctx = {0};
  1580.  
  1581.    ctx.text = text;
  1582.    ctx.cur = text;
  1583.    ctx.tokens = tokens;
  1584.    ctx.tokens_cur = tokens;
  1585.    ctx.tokens_end = tokens + num_tokens;
  1586.  
  1587.    if (!translate( &ctx ))
  1588.       return FALSE;
  1589.  
  1590.    return tgsi_sanity_check( tokens );
  1591. }
  1592.