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