1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/u_debug.h"
29 #include "util/u_memory.h"
30 #include "tgsi_text.h"
31 #include "tgsi_build.h"
32 #include "tgsi_info.h"
33 #include "tgsi_parse.h"
34 #include "tgsi_sanity.h"
35 #include "tgsi_util.h"
37 static boolean
is_alpha_underscore( const char *cur
)
40 (*cur
>= 'a' && *cur
<= 'z') ||
41 (*cur
>= 'A' && *cur
<= 'Z') ||
45 static boolean
is_digit( const char *cur
)
47 return *cur
>= '0' && *cur
<= '9';
50 static boolean
is_digit_alpha_underscore( const char *cur
)
52 return is_digit( cur
) || is_alpha_underscore( cur
);
55 static boolean
uprcase( char c
)
57 if (c
>= 'a' && c
<= 'z')
58 return c
+= 'A' - 'a';
62 static boolean
str_match_no_case( const char **pcur
, const char *str
)
64 const char *cur
= *pcur
;
66 while (*str
!= '\0' && *str
== uprcase( *cur
)) {
77 /* Eat zero or more whitespaces.
79 static void eat_opt_white( const char **pcur
)
81 while (**pcur
== ' ' || **pcur
== '\t' || **pcur
== '\n')
85 /* Eat one or more whitespaces.
86 * Return TRUE if at least one whitespace eaten.
88 static boolean
eat_white( const char **pcur
)
90 const char *cur
= *pcur
;
92 eat_opt_white( pcur
);
96 /* Parse unsigned integer.
97 * No checks for overflow.
99 static boolean
parse_uint( const char **pcur
, uint
*val
)
101 const char *cur
= *pcur
;
103 if (is_digit( cur
)) {
105 while (is_digit( cur
))
106 *val
= *val
* 10 + *cur
++ - '0';
113 /* Parse floating point.
115 static boolean
parse_float( const char **pcur
, float *val
)
117 const char *cur
= *pcur
;
118 boolean integral_part
= FALSE
;
119 boolean fractional_part
= FALSE
;
121 *val
= (float) atof( cur
);
123 if (*cur
== '-' || *cur
== '+')
125 if (is_digit( cur
)) {
127 integral_part
= TRUE
;
128 while (is_digit( cur
))
133 if (is_digit( cur
)) {
135 fractional_part
= TRUE
;
136 while (is_digit( cur
))
140 if (!integral_part
&& !fractional_part
)
142 if (uprcase( *cur
) == 'E') {
144 if (*cur
== '-' || *cur
== '+')
146 if (is_digit( cur
)) {
148 while (is_digit( cur
))
162 struct tgsi_token
*tokens
;
163 struct tgsi_token
*tokens_cur
;
164 struct tgsi_token
*tokens_end
;
165 struct tgsi_header
*header
;
168 static void report_error( struct translate_ctx
*ctx
, const char *msg
)
170 debug_printf( "\nError: %s", msg
);
173 /* Parse shader header.
174 * Return TRUE for one of the following headers.
179 static boolean
parse_header( struct translate_ctx
*ctx
)
183 if (str_match_no_case( &ctx
->cur
, "FRAG1.1" ))
184 processor
= TGSI_PROCESSOR_FRAGMENT
;
185 else if (str_match_no_case( &ctx
->cur
, "VERT1.1" ))
186 processor
= TGSI_PROCESSOR_VERTEX
;
187 else if (str_match_no_case( &ctx
->cur
, "GEOM1.1" ))
188 processor
= TGSI_PROCESSOR_GEOMETRY
;
190 report_error( ctx
, "Unknown header" );
194 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
196 *(struct tgsi_version
*) ctx
->tokens_cur
++ = tgsi_build_version();
198 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
200 ctx
->header
= (struct tgsi_header
*) ctx
->tokens_cur
++;
201 *ctx
->header
= tgsi_build_header();
203 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
205 *(struct tgsi_processor
*) ctx
->tokens_cur
++ = tgsi_build_processor( processor
, ctx
->header
);
210 static boolean
parse_label( struct translate_ctx
*ctx
, uint
*val
)
212 const char *cur
= ctx
->cur
;
214 if (parse_uint( &cur
, val
)) {
215 eat_opt_white( &cur
);
225 static const char *file_names
[TGSI_FILE_COUNT
] =
238 parse_file( const char **pcur
, uint
*file
)
242 for (i
= 0; i
< TGSI_FILE_COUNT
; i
++) {
243 const char *cur
= *pcur
;
245 if (str_match_no_case( &cur
, file_names
[i
] )) {
246 if (!is_digit_alpha_underscore( cur
)) {
258 struct translate_ctx
*ctx
,
264 eat_opt_white( &cur
);
267 *writemask
= TGSI_WRITEMASK_NONE
;
268 eat_opt_white( &cur
);
269 if (uprcase( *cur
) == 'X') {
271 *writemask
|= TGSI_WRITEMASK_X
;
273 if (uprcase( *cur
) == 'Y') {
275 *writemask
|= TGSI_WRITEMASK_Y
;
277 if (uprcase( *cur
) == 'Z') {
279 *writemask
|= TGSI_WRITEMASK_Z
;
281 if (uprcase( *cur
) == 'W') {
283 *writemask
|= TGSI_WRITEMASK_W
;
286 if (*writemask
== TGSI_WRITEMASK_NONE
) {
287 report_error( ctx
, "Writemask expected" );
294 *writemask
= TGSI_WRITEMASK_XYZW
;
299 /* <register_file_bracket> ::= <file> `['
302 parse_register_file_bracket(
303 struct translate_ctx
*ctx
,
306 if (!parse_file( &ctx
->cur
, file
)) {
307 report_error( ctx
, "Unknown register file" );
310 eat_opt_white( &ctx
->cur
);
311 if (*ctx
->cur
!= '[') {
312 report_error( ctx
, "Expected `['" );
319 /* <register_file_bracket_index> ::= <register_file_bracket> <uint>
322 parse_register_file_bracket_index(
323 struct translate_ctx
*ctx
,
329 if (!parse_register_file_bracket( ctx
, file
))
331 eat_opt_white( &ctx
->cur
);
332 if (!parse_uint( &ctx
->cur
, &uindex
)) {
333 report_error( ctx
, "Expected literal unsigned integer" );
336 *index
= (int) uindex
;
340 /* Parse destination register operand.
341 * <register_dst> ::= <register_file_bracket_index> `]'
345 struct translate_ctx
*ctx
,
349 if (!parse_register_file_bracket_index( ctx
, file
, index
))
351 eat_opt_white( &ctx
->cur
);
352 if (*ctx
->cur
!= ']') {
353 report_error( ctx
, "Expected `]'" );
360 /* Parse source register operand.
361 * <register_src> ::= <register_file_bracket_index> `]' |
362 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
363 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
364 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
368 struct translate_ctx
*ctx
,
378 *ind_comp
= TGSI_SWIZZLE_X
;
379 if (!parse_register_file_bracket( ctx
, file
))
381 eat_opt_white( &ctx
->cur
);
383 if (parse_file( &cur
, ind_file
)) {
384 if (!parse_register_dst( ctx
, ind_file
, ind_index
))
386 eat_opt_white( &ctx
->cur
);
388 if (*ctx
->cur
== '.') {
390 eat_opt_white(&ctx
->cur
);
392 switch (uprcase(*ctx
->cur
)) {
394 *ind_comp
= TGSI_SWIZZLE_X
;
397 *ind_comp
= TGSI_SWIZZLE_Y
;
400 *ind_comp
= TGSI_SWIZZLE_Z
;
403 *ind_comp
= TGSI_SWIZZLE_W
;
406 report_error(ctx
, "Expected indirect register swizzle component `x', `y', `z' or `w'");
410 eat_opt_white(&ctx
->cur
);
413 if (*ctx
->cur
== '+' || *ctx
->cur
== '-') {
416 negate
= *ctx
->cur
== '-';
418 eat_opt_white( &ctx
->cur
);
419 if (!parse_uint( &ctx
->cur
, &uindex
)) {
420 report_error( ctx
, "Expected literal unsigned integer" );
424 *index
= -(int) uindex
;
426 *index
= (int) uindex
;
433 if (!parse_uint( &ctx
->cur
, &uindex
)) {
434 report_error( ctx
, "Expected literal unsigned integer" );
437 *index
= (int) uindex
;
438 *ind_file
= TGSI_FILE_NULL
;
441 eat_opt_white( &ctx
->cur
);
442 if (*ctx
->cur
!= ']') {
443 report_error( ctx
, "Expected `]'" );
450 /* Parse register declaration.
451 * <register_dcl> ::= <register_file_bracket_index> `]' |
452 * <register_file_bracket_index> `..' <index> `]'
456 struct translate_ctx
*ctx
,
461 if (!parse_register_file_bracket_index( ctx
, file
, first
))
463 eat_opt_white( &ctx
->cur
);
464 if (ctx
->cur
[0] == '.' && ctx
->cur
[1] == '.') {
468 eat_opt_white( &ctx
->cur
);
469 if (!parse_uint( &ctx
->cur
, &uindex
)) {
470 report_error( ctx
, "Expected literal integer" );
473 *last
= (int) uindex
;
474 eat_opt_white( &ctx
->cur
);
479 if (*ctx
->cur
!= ']') {
480 report_error( ctx
, "Expected `]' or `..'" );
487 static const char *modulate_names
[TGSI_MODULATE_COUNT
] =
500 struct translate_ctx
*ctx
,
501 struct tgsi_full_dst_register
*dst
)
508 if (!parse_register_dst( ctx
, &file
, &index
))
512 eat_opt_white( &cur
);
516 for (i
= 0; i
< TGSI_MODULATE_COUNT
; i
++) {
517 if (str_match_no_case( &cur
, modulate_names
[i
] )) {
518 if (!is_digit_alpha_underscore( cur
)) {
519 dst
->DstRegisterExtModulate
.Modulate
= i
;
527 if (!parse_opt_writemask( ctx
, &writemask
))
530 dst
->DstRegister
.File
= file
;
531 dst
->DstRegister
.Index
= index
;
532 dst
->DstRegister
.WriteMask
= writemask
;
537 parse_optional_swizzle(
538 struct translate_ctx
*ctx
,
540 boolean
*parsed_swizzle
,
541 boolean
*parsed_extswizzle
)
543 const char *cur
= ctx
->cur
;
545 *parsed_swizzle
= FALSE
;
546 *parsed_extswizzle
= FALSE
;
548 eat_opt_white( &cur
);
553 eat_opt_white( &cur
);
554 for (i
= 0; i
< 4; i
++) {
555 if (uprcase( *cur
) == 'X')
556 swizzle
[i
] = TGSI_SWIZZLE_X
;
557 else if (uprcase( *cur
) == 'Y')
558 swizzle
[i
] = TGSI_SWIZZLE_Y
;
559 else if (uprcase( *cur
) == 'Z')
560 swizzle
[i
] = TGSI_SWIZZLE_Z
;
561 else if (uprcase( *cur
) == 'W')
562 swizzle
[i
] = TGSI_SWIZZLE_W
;
565 swizzle
[i
] = TGSI_EXTSWIZZLE_ZERO
;
566 else if (*cur
== '1')
567 swizzle
[i
] = TGSI_EXTSWIZZLE_ONE
;
569 report_error( ctx
, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" );
572 *parsed_extswizzle
= TRUE
;
576 *parsed_swizzle
= TRUE
;
584 struct translate_ctx
*ctx
,
585 struct tgsi_full_src_register
*src
)
595 boolean parsed_ext_negate_paren
= FALSE
;
596 boolean parsed_swizzle
;
597 boolean parsed_extswizzle
;
599 if (*ctx
->cur
== '-') {
602 eat_opt_white( &cur
);
605 src
->SrcRegisterExtMod
.Negate
= 1;
606 eat_opt_white( &cur
);
608 parsed_ext_negate_paren
= TRUE
;
610 else if (*cur
== '|') {
612 src
->SrcRegisterExtMod
.Negate
= 1;
613 src
->SrcRegisterExtMod
.Absolute
= 1;
618 else if (*ctx
->cur
== '|') {
620 eat_opt_white( &ctx
->cur
);
621 src
->SrcRegisterExtMod
.Absolute
= 1;
624 if (*ctx
->cur
== '-') {
626 eat_opt_white( &ctx
->cur
);
627 src
->SrcRegister
.Negate
= 1;
631 if (parse_float( &cur
, &value
)) {
633 eat_opt_white( &cur
);
635 report_error( ctx
, "Expected `*'" );
640 report_error( ctx
, "Expected `('" );
644 src
->SrcRegisterExtMod
.Scale2X
= 1;
645 eat_opt_white( &cur
);
650 if (*ctx
->cur
== '(') {
652 eat_opt_white( &ctx
->cur
);
653 src
->SrcRegisterExtMod
.Bias
= 1;
657 if (parse_float( &cur
, &value
)) {
659 eat_opt_white( &cur
);
661 report_error( ctx
, "Expected `-'" );
666 report_error( ctx
, "Expected `('" );
670 src
->SrcRegisterExtMod
.Complement
= 1;
671 eat_opt_white( &cur
);
676 if (!parse_register_src(ctx
, &file
, &index
, &ind_file
, &ind_index
, &ind_comp
))
678 src
->SrcRegister
.File
= file
;
679 src
->SrcRegister
.Index
= index
;
680 if (ind_file
!= TGSI_FILE_NULL
) {
681 src
->SrcRegister
.Indirect
= 1;
682 src
->SrcRegisterInd
.File
= ind_file
;
683 src
->SrcRegisterInd
.Index
= ind_index
;
684 src
->SrcRegisterInd
.SwizzleX
= ind_comp
;
685 src
->SrcRegisterInd
.SwizzleY
= ind_comp
;
686 src
->SrcRegisterInd
.SwizzleZ
= ind_comp
;
687 src
->SrcRegisterInd
.SwizzleW
= ind_comp
;
690 /* Parse optional swizzle.
692 if (parse_optional_swizzle( ctx
, swizzle
, &parsed_swizzle
, &parsed_extswizzle
)) {
693 if (parsed_extswizzle
) {
694 assert( parsed_swizzle
);
696 src
->SrcRegisterExtSwz
.ExtSwizzleX
= swizzle
[0];
697 src
->SrcRegisterExtSwz
.ExtSwizzleY
= swizzle
[1];
698 src
->SrcRegisterExtSwz
.ExtSwizzleZ
= swizzle
[2];
699 src
->SrcRegisterExtSwz
.ExtSwizzleW
= swizzle
[3];
701 else if (parsed_swizzle
) {
702 src
->SrcRegister
.SwizzleX
= swizzle
[0];
703 src
->SrcRegister
.SwizzleY
= swizzle
[1];
704 src
->SrcRegister
.SwizzleZ
= swizzle
[2];
705 src
->SrcRegister
.SwizzleW
= swizzle
[3];
709 if (src
->SrcRegisterExtMod
.Complement
) {
710 eat_opt_white( &ctx
->cur
);
711 if (*ctx
->cur
!= ')') {
712 report_error( ctx
, "Expected `)'" );
718 if (src
->SrcRegisterExtMod
.Bias
) {
719 eat_opt_white( &ctx
->cur
);
720 if (*ctx
->cur
!= ')') {
721 report_error( ctx
, "Expected `)'" );
725 eat_opt_white( &ctx
->cur
);
726 if (*ctx
->cur
!= '-') {
727 report_error( ctx
, "Expected `-'" );
731 eat_opt_white( &ctx
->cur
);
732 if (!parse_float( &ctx
->cur
, &value
)) {
733 report_error( ctx
, "Expected literal floating point" );
737 report_error( ctx
, "Expected 0.5" );
742 if (src
->SrcRegisterExtMod
.Scale2X
) {
743 eat_opt_white( &ctx
->cur
);
744 if (*ctx
->cur
!= ')') {
745 report_error( ctx
, "Expected `)'" );
751 if (src
->SrcRegisterExtMod
.Absolute
) {
752 eat_opt_white( &ctx
->cur
);
753 if (*ctx
->cur
!= '|') {
754 report_error( ctx
, "Expected `|'" );
760 if (parsed_ext_negate_paren
) {
761 eat_opt_white( &ctx
->cur
);
762 if (*ctx
->cur
!= ')') {
763 report_error( ctx
, "Expected `)'" );
772 static const char *texture_names
[TGSI_TEXTURE_COUNT
] =
786 match_inst_mnemonic(const char **pcur
,
787 const struct tgsi_opcode_info
*info
)
789 if (str_match_no_case(pcur
, info
->mnemonic
)) {
797 struct translate_ctx
*ctx
,
801 uint saturate
= TGSI_SAT_NONE
;
802 const struct tgsi_opcode_info
*info
;
803 struct tgsi_full_instruction inst
;
806 /* Parse instruction name.
808 eat_opt_white( &ctx
->cur
);
809 for (i
= 0; i
< TGSI_OPCODE_LAST
; i
++) {
810 const char *cur
= ctx
->cur
;
812 info
= tgsi_get_opcode_info( i
);
813 if (match_inst_mnemonic(&cur
, info
)) {
814 if (str_match_no_case( &cur
, "_SATNV" ))
815 saturate
= TGSI_SAT_MINUS_PLUS_ONE
;
816 else if (str_match_no_case( &cur
, "_SAT" ))
817 saturate
= TGSI_SAT_ZERO_ONE
;
819 if (info
->num_dst
+ info
->num_src
+ info
->is_tex
== 0) {
820 if (!is_digit_alpha_underscore( cur
)) {
825 else if (*cur
== '\0' || eat_white( &cur
)) {
831 if (i
== TGSI_OPCODE_LAST
) {
833 report_error( ctx
, "Unknown opcode" );
835 report_error( ctx
, "Expected `DCL', `IMM' or a label" );
839 inst
= tgsi_default_full_instruction();
840 inst
.Instruction
.Opcode
= i
;
841 inst
.Instruction
.Saturate
= saturate
;
842 inst
.Instruction
.NumDstRegs
= info
->num_dst
;
843 inst
.Instruction
.NumSrcRegs
= info
->num_src
;
845 /* Parse instruction operands.
847 for (i
= 0; i
< info
->num_dst
+ info
->num_src
+ info
->is_tex
; i
++) {
849 eat_opt_white( &ctx
->cur
);
850 if (*ctx
->cur
!= ',') {
851 report_error( ctx
, "Expected `,'" );
855 eat_opt_white( &ctx
->cur
);
858 if (i
< info
->num_dst
) {
859 if (!parse_dst_operand( ctx
, &inst
.FullDstRegisters
[i
] ))
862 else if (i
< info
->num_dst
+ info
->num_src
) {
863 if (!parse_src_operand( ctx
, &inst
.FullSrcRegisters
[i
- info
->num_dst
] ))
869 for (j
= 0; j
< TGSI_TEXTURE_COUNT
; j
++) {
870 if (str_match_no_case( &ctx
->cur
, texture_names
[j
] )) {
871 if (!is_digit_alpha_underscore( ctx
->cur
)) {
872 inst
.InstructionExtTexture
.Texture
= j
;
877 if (j
== TGSI_TEXTURE_COUNT
) {
878 report_error( ctx
, "Expected texture target" );
884 if (info
->is_branch
) {
887 eat_opt_white( &ctx
->cur
);
888 if (*ctx
->cur
!= ':') {
889 report_error( ctx
, "Expected `:'" );
893 eat_opt_white( &ctx
->cur
);
894 if (!parse_uint( &ctx
->cur
, &target
)) {
895 report_error( ctx
, "Expected a label" );
898 inst
.InstructionExtLabel
.Label
= target
;
901 advance
= tgsi_build_full_instruction(
905 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
908 ctx
->tokens_cur
+= advance
;
913 static const char *semantic_names
[TGSI_SEMANTIC_COUNT
] =
925 static const char *interpolate_names
[TGSI_INTERPOLATE_COUNT
] =
932 static boolean
parse_declaration( struct translate_ctx
*ctx
)
934 struct tgsi_full_declaration decl
;
942 assert(Elements(semantic_names
) == TGSI_SEMANTIC_COUNT
);
943 assert(Elements(interpolate_names
) == TGSI_INTERPOLATE_COUNT
);
945 if (!eat_white( &ctx
->cur
)) {
946 report_error( ctx
, "Syntax error" );
949 if (!parse_register_dcl( ctx
, &file
, &first
, &last
))
951 if (!parse_opt_writemask( ctx
, &writemask
))
954 decl
= tgsi_default_full_declaration();
955 decl
.Declaration
.File
= file
;
956 decl
.Declaration
.UsageMask
= writemask
;
957 decl
.DeclarationRange
.First
= first
;
958 decl
.DeclarationRange
.Last
= last
;
961 eat_opt_white( &cur
);
966 eat_opt_white( &cur
);
967 for (i
= 0; i
< TGSI_SEMANTIC_COUNT
; i
++) {
968 if (str_match_no_case( &cur
, semantic_names
[i
] )) {
969 const char *cur2
= cur
;
972 if (is_digit_alpha_underscore( cur
))
974 eat_opt_white( &cur2
);
977 eat_opt_white( &cur2
);
978 if (!parse_uint( &cur2
, &index
)) {
979 report_error( ctx
, "Expected literal integer" );
982 eat_opt_white( &cur2
);
984 report_error( ctx
, "Expected `]'" );
989 decl
.Semantic
.SemanticIndex
= index
;
994 decl
.Declaration
.Semantic
= 1;
995 decl
.Semantic
.SemanticName
= i
;
1004 eat_opt_white( &cur
);
1009 eat_opt_white( &cur
);
1010 for (i
= 0; i
< TGSI_INTERPOLATE_COUNT
; i
++) {
1011 if (str_match_no_case( &cur
, interpolate_names
[i
] )) {
1012 if (is_digit_alpha_underscore( cur
))
1014 decl
.Declaration
.Interpolate
= i
;
1020 if (i
== TGSI_INTERPOLATE_COUNT
) {
1021 report_error( ctx
, "Expected semantic or interpolate attribute" );
1026 advance
= tgsi_build_full_declaration(
1030 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
1033 ctx
->tokens_cur
+= advance
;
1038 static boolean
parse_immediate( struct translate_ctx
*ctx
)
1040 struct tgsi_full_immediate imm
;
1045 if (!eat_white( &ctx
->cur
)) {
1046 report_error( ctx
, "Syntax error" );
1049 if (!str_match_no_case( &ctx
->cur
, "FLT32" ) || is_digit_alpha_underscore( ctx
->cur
)) {
1050 report_error( ctx
, "Expected `FLT32'" );
1053 eat_opt_white( &ctx
->cur
);
1054 if (*ctx
->cur
!= '{') {
1055 report_error( ctx
, "Expected `{'" );
1059 for (i
= 0; i
< 4; i
++) {
1060 eat_opt_white( &ctx
->cur
);
1062 if (*ctx
->cur
!= ',') {
1063 report_error( ctx
, "Expected `,'" );
1067 eat_opt_white( &ctx
->cur
);
1069 if (!parse_float( &ctx
->cur
, &values
[i
] )) {
1070 report_error( ctx
, "Expected literal floating point" );
1074 eat_opt_white( &ctx
->cur
);
1075 if (*ctx
->cur
!= '}') {
1076 report_error( ctx
, "Expected `}'" );
1081 imm
= tgsi_default_full_immediate();
1082 imm
.Immediate
.NrTokens
+= 4;
1083 imm
.Immediate
.DataType
= TGSI_IMM_FLOAT32
;
1084 imm
.u
[0].Float
= values
[0];
1085 imm
.u
[1].Float
= values
[1];
1086 imm
.u
[2].Float
= values
[2];
1087 imm
.u
[3].Float
= values
[3];
1089 advance
= tgsi_build_full_immediate(
1093 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
1096 ctx
->tokens_cur
+= advance
;
1101 static boolean
translate( struct translate_ctx
*ctx
)
1103 eat_opt_white( &ctx
->cur
);
1104 if (!parse_header( ctx
))
1107 while (*ctx
->cur
!= '\0') {
1110 if (!eat_white( &ctx
->cur
)) {
1111 report_error( ctx
, "Syntax error" );
1115 if (*ctx
->cur
== '\0')
1118 if (parse_label( ctx
, &label_val
)) {
1119 if (!parse_instruction( ctx
, TRUE
))
1122 else if (str_match_no_case( &ctx
->cur
, "DCL" )) {
1123 if (!parse_declaration( ctx
))
1126 else if (str_match_no_case( &ctx
->cur
, "IMM" )) {
1127 if (!parse_immediate( ctx
))
1130 else if (!parse_instruction( ctx
, FALSE
)) {
1139 tgsi_text_translate(
1141 struct tgsi_token
*tokens
,
1144 struct translate_ctx ctx
;
1148 ctx
.tokens
= tokens
;
1149 ctx
.tokens_cur
= tokens
;
1150 ctx
.tokens_end
= tokens
+ num_tokens
;
1152 if (!translate( &ctx
))
1155 return tgsi_sanity_check( tokens
);