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 "tgsi_text.h"
30 #include "tgsi_build.h"
31 #include "tgsi_info.h"
32 #include "tgsi_parse.h"
33 #include "tgsi_sanity.h"
34 #include "tgsi_util.h"
36 static boolean
is_alpha_underscore( const char *cur
)
39 (*cur
>= 'a' && *cur
<= 'z') ||
40 (*cur
>= 'A' && *cur
<= 'Z') ||
44 static boolean
is_digit( const char *cur
)
46 return *cur
>= '0' && *cur
<= '9';
49 static boolean
is_digit_alpha_underscore( const char *cur
)
51 return is_digit( cur
) || is_alpha_underscore( cur
);
54 static boolean
uprcase( char c
)
56 if (c
>= 'a' && c
<= 'z')
57 return c
+= 'A' - 'a';
61 static boolean
str_match_no_case( const char **pcur
, const char *str
)
63 const char *cur
= *pcur
;
65 while (*str
!= '\0' && *str
== uprcase( *cur
)) {
76 /* Eat zero or more whitespaces.
78 static void eat_opt_white( const char **pcur
)
80 while (**pcur
== ' ' || **pcur
== '\t' || **pcur
== '\n')
84 /* Eat one or more whitespaces.
85 * Return TRUE if at least one whitespace eaten.
87 static boolean
eat_white( const char **pcur
)
89 const char *cur
= *pcur
;
91 eat_opt_white( pcur
);
95 /* Parse unsigned integer.
96 * No checks for overflow.
98 static boolean
parse_uint( const char **pcur
, uint
*val
)
100 const char *cur
= *pcur
;
102 if (is_digit( cur
)) {
104 while (is_digit( cur
))
105 *val
= *val
* 10 + *cur
++ - '0';
112 /* Parse floating point.
114 static boolean
parse_float( const char **pcur
, float *val
)
116 const char *cur
= *pcur
;
117 boolean integral_part
= FALSE
;
118 boolean fractional_part
= FALSE
;
120 *val
= (float) atof( cur
);
122 if (*cur
== '-' || *cur
== '+')
124 if (is_digit( cur
)) {
126 integral_part
= TRUE
;
127 while (is_digit( cur
))
132 if (is_digit( cur
)) {
134 fractional_part
= TRUE
;
135 while (is_digit( cur
))
139 if (!integral_part
&& !fractional_part
)
141 if (uprcase( *cur
) == 'E') {
143 if (*cur
== '-' || *cur
== '+')
145 if (is_digit( cur
)) {
147 while (is_digit( cur
))
161 struct tgsi_token
*tokens
;
162 struct tgsi_token
*tokens_cur
;
163 struct tgsi_token
*tokens_end
;
164 struct tgsi_header
*header
;
167 static void report_error( struct translate_ctx
*ctx
, const char *msg
)
169 debug_printf( "\nError: %s", msg
);
172 /* Parse shader header.
173 * Return TRUE for one of the following headers.
178 static boolean
parse_header( struct translate_ctx
*ctx
)
182 if (str_match_no_case( &ctx
->cur
, "FRAG1.1" ))
183 processor
= TGSI_PROCESSOR_FRAGMENT
;
184 else if (str_match_no_case( &ctx
->cur
, "VERT1.1" ))
185 processor
= TGSI_PROCESSOR_VERTEX
;
186 else if (str_match_no_case( &ctx
->cur
, "GEOM1.1" ))
187 processor
= TGSI_PROCESSOR_GEOMETRY
;
189 report_error( ctx
, "Unknown header" );
193 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
195 *(struct tgsi_version
*) ctx
->tokens_cur
++ = tgsi_build_version();
197 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
199 ctx
->header
= (struct tgsi_header
*) ctx
->tokens_cur
++;
200 *ctx
->header
= tgsi_build_header();
202 if (ctx
->tokens_cur
>= ctx
->tokens_end
)
204 *(struct tgsi_processor
*) ctx
->tokens_cur
++ = tgsi_build_processor( processor
, ctx
->header
);
209 static boolean
parse_label( struct translate_ctx
*ctx
, uint
*val
)
211 const char *cur
= ctx
->cur
;
213 if (parse_uint( &cur
, val
)) {
214 eat_opt_white( &cur
);
224 static const char *file_names
[TGSI_FILE_COUNT
] =
237 parse_file( const char **pcur
, uint
*file
)
241 for (i
= 0; i
< TGSI_FILE_COUNT
; i
++) {
242 const char *cur
= *pcur
;
244 if (str_match_no_case( &cur
, file_names
[i
] )) {
245 if (!is_digit_alpha_underscore( cur
)) {
257 struct translate_ctx
*ctx
,
263 eat_opt_white( &cur
);
266 *writemask
= TGSI_WRITEMASK_NONE
;
267 eat_opt_white( &cur
);
268 if (uprcase( *cur
) == 'X') {
270 *writemask
|= TGSI_WRITEMASK_X
;
272 if (uprcase( *cur
) == 'Y') {
274 *writemask
|= TGSI_WRITEMASK_Y
;
276 if (uprcase( *cur
) == 'Z') {
278 *writemask
|= TGSI_WRITEMASK_Z
;
280 if (uprcase( *cur
) == 'W') {
282 *writemask
|= TGSI_WRITEMASK_W
;
285 if (*writemask
== TGSI_WRITEMASK_NONE
) {
286 report_error( ctx
, "Writemask expected" );
293 *writemask
= TGSI_WRITEMASK_XYZW
;
298 /* <register_file_bracket> ::= <file> `['
301 parse_register_file_bracket(
302 struct translate_ctx
*ctx
,
305 if (!parse_file( &ctx
->cur
, file
)) {
306 report_error( ctx
, "Unknown register file" );
309 eat_opt_white( &ctx
->cur
);
310 if (*ctx
->cur
!= '[') {
311 report_error( ctx
, "Expected `['" );
318 /* <register_file_bracket_index> ::= <register_file_bracket> <uint>
321 parse_register_file_bracket_index(
322 struct translate_ctx
*ctx
,
328 if (!parse_register_file_bracket( ctx
, file
))
330 eat_opt_white( &ctx
->cur
);
331 if (!parse_uint( &ctx
->cur
, &uindex
)) {
332 report_error( ctx
, "Expected literal unsigned integer" );
335 *index
= (int) uindex
;
339 /* Parse destination register operand.
340 * <register_dst> ::= <register_file_bracket_index> `]'
344 struct translate_ctx
*ctx
,
348 if (!parse_register_file_bracket_index( ctx
, file
, index
))
350 eat_opt_white( &ctx
->cur
);
351 if (*ctx
->cur
!= ']') {
352 report_error( ctx
, "Expected `]'" );
359 /* Parse source register operand.
360 * <register_src> ::= <register_file_bracket_index> `]' |
361 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
362 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
363 * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
367 struct translate_ctx
*ctx
,
377 *ind_comp
= TGSI_SWIZZLE_X
;
378 if (!parse_register_file_bracket( ctx
, file
))
380 eat_opt_white( &ctx
->cur
);
382 if (parse_file( &cur
, ind_file
)) {
383 if (!parse_register_dst( ctx
, ind_file
, ind_index
))
385 eat_opt_white( &ctx
->cur
);
387 if (*ctx
->cur
== '.') {
389 eat_opt_white(&ctx
->cur
);
391 switch (uprcase(*ctx
->cur
)) {
393 *ind_comp
= TGSI_SWIZZLE_X
;
396 *ind_comp
= TGSI_SWIZZLE_Y
;
399 *ind_comp
= TGSI_SWIZZLE_Z
;
402 *ind_comp
= TGSI_SWIZZLE_W
;
405 report_error(ctx
, "Expected indirect register swizzle component `x', `y', `z' or `w'");
409 eat_opt_white(&ctx
->cur
);
412 if (*ctx
->cur
== '+' || *ctx
->cur
== '-') {
415 negate
= *ctx
->cur
== '-';
417 eat_opt_white( &ctx
->cur
);
418 if (!parse_uint( &ctx
->cur
, &uindex
)) {
419 report_error( ctx
, "Expected literal unsigned integer" );
423 *index
= -(int) uindex
;
425 *index
= (int) uindex
;
432 if (!parse_uint( &ctx
->cur
, &uindex
)) {
433 report_error( ctx
, "Expected literal unsigned integer" );
436 *index
= (int) uindex
;
437 *ind_file
= TGSI_FILE_NULL
;
440 eat_opt_white( &ctx
->cur
);
441 if (*ctx
->cur
!= ']') {
442 report_error( ctx
, "Expected `]'" );
449 /* Parse register declaration.
450 * <register_dcl> ::= <register_file_bracket_index> `]' |
451 * <register_file_bracket_index> `..' <index> `]'
455 struct translate_ctx
*ctx
,
460 if (!parse_register_file_bracket_index( ctx
, file
, first
))
462 eat_opt_white( &ctx
->cur
);
463 if (ctx
->cur
[0] == '.' && ctx
->cur
[1] == '.') {
467 eat_opt_white( &ctx
->cur
);
468 if (!parse_uint( &ctx
->cur
, &uindex
)) {
469 report_error( ctx
, "Expected literal integer" );
472 *last
= (int) uindex
;
473 eat_opt_white( &ctx
->cur
);
478 if (*ctx
->cur
!= ']') {
479 report_error( ctx
, "Expected `]' or `..'" );
486 static const char *modulate_names
[TGSI_MODULATE_COUNT
] =
499 struct translate_ctx
*ctx
,
500 struct tgsi_full_dst_register
*dst
)
507 if (!parse_register_dst( ctx
, &file
, &index
))
511 eat_opt_white( &cur
);
515 for (i
= 0; i
< TGSI_MODULATE_COUNT
; i
++) {
516 if (str_match_no_case( &cur
, modulate_names
[i
] )) {
517 if (!is_digit_alpha_underscore( cur
)) {
518 dst
->DstRegisterExtModulate
.Modulate
= i
;
526 if (!parse_opt_writemask( ctx
, &writemask
))
529 dst
->DstRegister
.File
= file
;
530 dst
->DstRegister
.Index
= index
;
531 dst
->DstRegister
.WriteMask
= writemask
;
536 parse_optional_swizzle(
537 struct translate_ctx
*ctx
,
539 boolean
*parsed_swizzle
,
540 boolean
*parsed_extswizzle
)
542 const char *cur
= ctx
->cur
;
544 *parsed_swizzle
= FALSE
;
545 *parsed_extswizzle
= FALSE
;
547 eat_opt_white( &cur
);
552 eat_opt_white( &cur
);
553 for (i
= 0; i
< 4; i
++) {
554 if (uprcase( *cur
) == 'X')
555 swizzle
[i
] = TGSI_SWIZZLE_X
;
556 else if (uprcase( *cur
) == 'Y')
557 swizzle
[i
] = TGSI_SWIZZLE_Y
;
558 else if (uprcase( *cur
) == 'Z')
559 swizzle
[i
] = TGSI_SWIZZLE_Z
;
560 else if (uprcase( *cur
) == 'W')
561 swizzle
[i
] = TGSI_SWIZZLE_W
;
564 swizzle
[i
] = TGSI_EXTSWIZZLE_ZERO
;
565 else if (*cur
== '1')
566 swizzle
[i
] = TGSI_EXTSWIZZLE_ONE
;
568 report_error( ctx
, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" );
571 *parsed_extswizzle
= TRUE
;
575 *parsed_swizzle
= TRUE
;
583 struct translate_ctx
*ctx
,
584 struct tgsi_full_src_register
*src
)
594 boolean parsed_ext_negate_paren
= FALSE
;
595 boolean parsed_swizzle
;
596 boolean parsed_extswizzle
;
598 if (*ctx
->cur
== '-') {
601 eat_opt_white( &cur
);
604 src
->SrcRegisterExtMod
.Negate
= 1;
605 eat_opt_white( &cur
);
607 parsed_ext_negate_paren
= TRUE
;
609 else if (*cur
== '|') {
611 src
->SrcRegisterExtMod
.Negate
= 1;
612 src
->SrcRegisterExtMod
.Absolute
= 1;
617 else if (*ctx
->cur
== '|') {
619 eat_opt_white( &ctx
->cur
);
620 src
->SrcRegisterExtMod
.Absolute
= 1;
623 if (*ctx
->cur
== '-') {
625 eat_opt_white( &ctx
->cur
);
626 src
->SrcRegister
.Negate
= 1;
630 if (parse_float( &cur
, &value
)) {
632 eat_opt_white( &cur
);
634 report_error( ctx
, "Expected `*'" );
639 report_error( ctx
, "Expected `('" );
643 src
->SrcRegisterExtMod
.Scale2X
= 1;
644 eat_opt_white( &cur
);
649 if (*ctx
->cur
== '(') {
651 eat_opt_white( &ctx
->cur
);
652 src
->SrcRegisterExtMod
.Bias
= 1;
656 if (parse_float( &cur
, &value
)) {
658 eat_opt_white( &cur
);
660 report_error( ctx
, "Expected `-'" );
665 report_error( ctx
, "Expected `('" );
669 src
->SrcRegisterExtMod
.Complement
= 1;
670 eat_opt_white( &cur
);
675 if (!parse_register_src(ctx
, &file
, &index
, &ind_file
, &ind_index
, &ind_comp
))
677 src
->SrcRegister
.File
= file
;
678 src
->SrcRegister
.Index
= index
;
679 if (ind_file
!= TGSI_FILE_NULL
) {
680 src
->SrcRegister
.Indirect
= 1;
681 src
->SrcRegisterInd
.File
= ind_file
;
682 src
->SrcRegisterInd
.Index
= ind_index
;
683 src
->SrcRegisterInd
.SwizzleX
= ind_comp
;
684 src
->SrcRegisterInd
.SwizzleY
= ind_comp
;
685 src
->SrcRegisterInd
.SwizzleZ
= ind_comp
;
686 src
->SrcRegisterInd
.SwizzleW
= ind_comp
;
689 /* Parse optional swizzle.
691 if (parse_optional_swizzle( ctx
, swizzle
, &parsed_swizzle
, &parsed_extswizzle
)) {
692 if (parsed_extswizzle
) {
693 assert( parsed_swizzle
);
695 src
->SrcRegisterExtSwz
.ExtSwizzleX
= swizzle
[0];
696 src
->SrcRegisterExtSwz
.ExtSwizzleY
= swizzle
[1];
697 src
->SrcRegisterExtSwz
.ExtSwizzleZ
= swizzle
[2];
698 src
->SrcRegisterExtSwz
.ExtSwizzleW
= swizzle
[3];
700 else if (parsed_swizzle
) {
701 src
->SrcRegister
.SwizzleX
= swizzle
[0];
702 src
->SrcRegister
.SwizzleY
= swizzle
[1];
703 src
->SrcRegister
.SwizzleZ
= swizzle
[2];
704 src
->SrcRegister
.SwizzleW
= swizzle
[3];
708 if (src
->SrcRegisterExtMod
.Complement
) {
709 eat_opt_white( &ctx
->cur
);
710 if (*ctx
->cur
!= ')') {
711 report_error( ctx
, "Expected `)'" );
717 if (src
->SrcRegisterExtMod
.Bias
) {
718 eat_opt_white( &ctx
->cur
);
719 if (*ctx
->cur
!= ')') {
720 report_error( ctx
, "Expected `)'" );
724 eat_opt_white( &ctx
->cur
);
725 if (*ctx
->cur
!= '-') {
726 report_error( ctx
, "Expected `-'" );
730 eat_opt_white( &ctx
->cur
);
731 if (!parse_float( &ctx
->cur
, &value
)) {
732 report_error( ctx
, "Expected literal floating point" );
736 report_error( ctx
, "Expected 0.5" );
741 if (src
->SrcRegisterExtMod
.Scale2X
) {
742 eat_opt_white( &ctx
->cur
);
743 if (*ctx
->cur
!= ')') {
744 report_error( ctx
, "Expected `)'" );
750 if (src
->SrcRegisterExtMod
.Absolute
) {
751 eat_opt_white( &ctx
->cur
);
752 if (*ctx
->cur
!= '|') {
753 report_error( ctx
, "Expected `|'" );
759 if (parsed_ext_negate_paren
) {
760 eat_opt_white( &ctx
->cur
);
761 if (*ctx
->cur
!= ')') {
762 report_error( ctx
, "Expected `)'" );
771 static const char *texture_names
[TGSI_TEXTURE_COUNT
] =
785 match_inst_mnemonic(const char **pcur
,
786 const struct tgsi_opcode_info
*info
)
788 if (str_match_no_case(pcur
, info
->mnemonic
)) {
791 if (info
->alt_mnemonic1
) {
792 if (str_match_no_case(pcur
, info
->alt_mnemonic1
)) {
795 if (info
->alt_mnemonic2
) {
796 if (str_match_no_case(pcur
, info
->alt_mnemonic2
)) {
806 struct translate_ctx
*ctx
,
810 uint saturate
= TGSI_SAT_NONE
;
811 const struct tgsi_opcode_info
*info
;
812 struct tgsi_full_instruction inst
;
815 /* Parse instruction name.
817 eat_opt_white( &ctx
->cur
);
818 for (i
= 0; i
< TGSI_OPCODE_LAST
; i
++) {
819 const char *cur
= ctx
->cur
;
821 info
= tgsi_get_opcode_info( i
);
822 if (match_inst_mnemonic(&cur
, info
)) {
823 if (str_match_no_case( &cur
, "_SATNV" ))
824 saturate
= TGSI_SAT_MINUS_PLUS_ONE
;
825 else if (str_match_no_case( &cur
, "_SAT" ))
826 saturate
= TGSI_SAT_ZERO_ONE
;
828 if (info
->num_dst
+ info
->num_src
+ info
->is_tex
== 0) {
829 if (!is_digit_alpha_underscore( cur
)) {
834 else if (*cur
== '\0' || eat_white( &cur
)) {
840 if (i
== TGSI_OPCODE_LAST
) {
842 report_error( ctx
, "Unknown opcode" );
844 report_error( ctx
, "Expected `DCL', `IMM' or a label" );
848 inst
= tgsi_default_full_instruction();
849 inst
.Instruction
.Opcode
= i
;
850 inst
.Instruction
.Saturate
= saturate
;
851 inst
.Instruction
.NumDstRegs
= info
->num_dst
;
852 inst
.Instruction
.NumSrcRegs
= info
->num_src
;
854 /* Parse instruction operands.
856 for (i
= 0; i
< info
->num_dst
+ info
->num_src
+ info
->is_tex
; i
++) {
858 eat_opt_white( &ctx
->cur
);
859 if (*ctx
->cur
!= ',') {
860 report_error( ctx
, "Expected `,'" );
864 eat_opt_white( &ctx
->cur
);
867 if (i
< info
->num_dst
) {
868 if (!parse_dst_operand( ctx
, &inst
.FullDstRegisters
[i
] ))
871 else if (i
< info
->num_dst
+ info
->num_src
) {
872 if (!parse_src_operand( ctx
, &inst
.FullSrcRegisters
[i
- info
->num_dst
] ))
878 for (j
= 0; j
< TGSI_TEXTURE_COUNT
; j
++) {
879 if (str_match_no_case( &ctx
->cur
, texture_names
[j
] )) {
880 if (!is_digit_alpha_underscore( ctx
->cur
)) {
881 inst
.InstructionExtTexture
.Texture
= j
;
886 if (j
== TGSI_TEXTURE_COUNT
) {
887 report_error( ctx
, "Expected texture target" );
893 if (info
->is_branch
) {
896 eat_opt_white( &ctx
->cur
);
897 if (*ctx
->cur
!= ':') {
898 report_error( ctx
, "Expected `:'" );
902 eat_opt_white( &ctx
->cur
);
903 if (!parse_uint( &ctx
->cur
, &target
)) {
904 report_error( ctx
, "Expected a label" );
907 inst
.InstructionExtLabel
.Label
= target
;
910 advance
= tgsi_build_full_instruction(
914 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
917 ctx
->tokens_cur
+= advance
;
922 static const char *semantic_names
[TGSI_SEMANTIC_COUNT
] =
933 static const char *interpolate_names
[TGSI_INTERPOLATE_COUNT
] =
940 static boolean
parse_declaration( struct translate_ctx
*ctx
)
942 struct tgsi_full_declaration decl
;
950 if (!eat_white( &ctx
->cur
)) {
951 report_error( ctx
, "Syntax error" );
954 if (!parse_register_dcl( ctx
, &file
, &first
, &last
))
956 if (!parse_opt_writemask( ctx
, &writemask
))
959 decl
= tgsi_default_full_declaration();
960 decl
.Declaration
.File
= file
;
961 decl
.Declaration
.UsageMask
= writemask
;
962 decl
.DeclarationRange
.First
= first
;
963 decl
.DeclarationRange
.Last
= last
;
966 eat_opt_white( &cur
);
971 eat_opt_white( &cur
);
972 for (i
= 0; i
< TGSI_SEMANTIC_COUNT
; i
++) {
973 if (str_match_no_case( &cur
, semantic_names
[i
] )) {
974 const char *cur2
= cur
;
977 if (is_digit_alpha_underscore( cur
))
979 eat_opt_white( &cur2
);
982 eat_opt_white( &cur2
);
983 if (!parse_uint( &cur2
, &index
)) {
984 report_error( ctx
, "Expected literal integer" );
987 eat_opt_white( &cur2
);
989 report_error( ctx
, "Expected `]'" );
994 decl
.Semantic
.SemanticIndex
= index
;
999 decl
.Declaration
.Semantic
= 1;
1000 decl
.Semantic
.SemanticName
= i
;
1009 eat_opt_white( &cur
);
1014 eat_opt_white( &cur
);
1015 for (i
= 0; i
< TGSI_INTERPOLATE_COUNT
; i
++) {
1016 if (str_match_no_case( &cur
, interpolate_names
[i
] )) {
1017 if (is_digit_alpha_underscore( cur
))
1019 decl
.Declaration
.Interpolate
= i
;
1025 if (i
== TGSI_INTERPOLATE_COUNT
) {
1026 report_error( ctx
, "Expected semantic or interpolate attribute" );
1031 advance
= tgsi_build_full_declaration(
1035 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
1038 ctx
->tokens_cur
+= advance
;
1043 static boolean
parse_immediate( struct translate_ctx
*ctx
)
1045 struct tgsi_full_immediate imm
;
1050 if (!eat_white( &ctx
->cur
)) {
1051 report_error( ctx
, "Syntax error" );
1054 if (!str_match_no_case( &ctx
->cur
, "FLT32" ) || is_digit_alpha_underscore( ctx
->cur
)) {
1055 report_error( ctx
, "Expected `FLT32'" );
1058 eat_opt_white( &ctx
->cur
);
1059 if (*ctx
->cur
!= '{') {
1060 report_error( ctx
, "Expected `{'" );
1064 for (i
= 0; i
< 4; i
++) {
1065 eat_opt_white( &ctx
->cur
);
1067 if (*ctx
->cur
!= ',') {
1068 report_error( ctx
, "Expected `,'" );
1072 eat_opt_white( &ctx
->cur
);
1074 if (!parse_float( &ctx
->cur
, &values
[i
] )) {
1075 report_error( ctx
, "Expected literal floating point" );
1079 eat_opt_white( &ctx
->cur
);
1080 if (*ctx
->cur
!= '}') {
1081 report_error( ctx
, "Expected `}'" );
1086 imm
= tgsi_default_full_immediate();
1087 imm
.Immediate
.NrTokens
+= 4;
1088 imm
.Immediate
.DataType
= TGSI_IMM_FLOAT32
;
1089 imm
.u
.Pointer
= values
;
1091 advance
= tgsi_build_full_immediate(
1095 (uint
) (ctx
->tokens_end
- ctx
->tokens_cur
) );
1098 ctx
->tokens_cur
+= advance
;
1103 static boolean
translate( struct translate_ctx
*ctx
)
1105 eat_opt_white( &ctx
->cur
);
1106 if (!parse_header( ctx
))
1109 while (*ctx
->cur
!= '\0') {
1112 if (!eat_white( &ctx
->cur
)) {
1113 report_error( ctx
, "Syntax error" );
1117 if (*ctx
->cur
== '\0')
1120 if (parse_label( ctx
, &label_val
)) {
1121 if (!parse_instruction( ctx
, TRUE
))
1124 else if (str_match_no_case( &ctx
->cur
, "DCL" )) {
1125 if (!parse_declaration( ctx
))
1128 else if (str_match_no_case( &ctx
->cur
, "IMM" )) {
1129 if (!parse_immediate( ctx
))
1132 else if (!parse_instruction( ctx
, FALSE
)) {
1141 tgsi_text_translate(
1143 struct tgsi_token
*tokens
,
1146 struct translate_ctx ctx
;
1150 ctx
.tokens
= tokens
;
1151 ctx
.tokens_cur
= tokens
;
1152 ctx
.tokens_end
= tokens
+ num_tokens
;
1154 if (!translate( &ctx
))
1157 return tgsi_sanity_check( tokens
);