1 /**************************************************************************
3 * Copyright 2007 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 "pipe/p_shader_tokens.h"
30 #include "tgsi_parse.h"
31 #include "util/u_memory.h"
35 struct tgsi_parse_context
*ctx
,
36 const struct tgsi_token
*tokens
)
38 ctx
->FullVersion
.Version
= *(struct tgsi_version
*) &tokens
[0];
39 if( ctx
->FullVersion
.Version
.Major
> 1 ) {
40 return TGSI_PARSE_ERROR
;
43 ctx
->FullHeader
.Header
= *(struct tgsi_header
*) &tokens
[1];
44 if( ctx
->FullHeader
.Header
.HeaderSize
>= 2 ) {
45 ctx
->FullHeader
.Processor
= *(struct tgsi_processor
*) &tokens
[2];
48 return TGSI_PARSE_ERROR
;
52 ctx
->Position
= 1 + ctx
->FullHeader
.Header
.HeaderSize
;
59 struct tgsi_parse_context
*ctx
)
64 tgsi_parse_end_of_tokens(
65 struct tgsi_parse_context
*ctx
)
67 return ctx
->Position
>=
68 1 + ctx
->FullHeader
.Header
.HeaderSize
+ ctx
->FullHeader
.Header
.BodySize
;
73 * This function is used to avoid and work-around type punning/aliasing
74 * warnings. The warnings seem harmless on x86 but on PPC they cause
78 copy_token(void *dst
, const void *src
)
85 * Get next 4-byte token, return it at address specified by 'token'
89 struct tgsi_parse_context
*ctx
,
92 assert( !tgsi_parse_end_of_tokens( ctx
) );
93 copy_token(token
, &ctx
->Tokens
[ctx
->Position
]);
100 struct tgsi_parse_context
*ctx
)
102 struct tgsi_token token
;
105 next_token( ctx
, &token
);
107 switch( token
.Type
) {
108 case TGSI_TOKEN_TYPE_DECLARATION
:
110 struct tgsi_full_declaration
*decl
= &ctx
->FullToken
.FullDeclaration
;
112 memset(decl
, 0, sizeof *decl
);
113 copy_token(&decl
->Declaration
, &token
);
115 next_token( ctx
, &decl
->Range
);
117 if( decl
->Declaration
.Semantic
) {
118 next_token( ctx
, &decl
->Semantic
);
124 case TGSI_TOKEN_TYPE_IMMEDIATE
:
126 struct tgsi_full_immediate
*imm
= &ctx
->FullToken
.FullImmediate
;
128 memset(imm
, 0, sizeof *imm
);
129 copy_token(&imm
->Immediate
, &token
);
131 switch (imm
->Immediate
.DataType
) {
132 case TGSI_IMM_FLOAT32
:
134 uint imm_count
= imm
->Immediate
.NrTokens
- 1;
135 for (i
= 0; i
< imm_count
; i
++) {
136 next_token(ctx
, &imm
->u
[i
]);
148 case TGSI_TOKEN_TYPE_INSTRUCTION
:
150 struct tgsi_full_instruction
*inst
= &ctx
->FullToken
.FullInstruction
;
152 memset(inst
, 0, sizeof *inst
);
153 copy_token(&inst
->Instruction
, &token
);
155 if (inst
->Instruction
.Predicate
) {
156 next_token(ctx
, &inst
->Predicate
);
159 if (inst
->Instruction
.Label
) {
160 next_token( ctx
, &inst
->Label
);
163 if (inst
->Instruction
.Texture
) {
164 next_token( ctx
, &inst
->Texture
);
167 assert( inst
->Instruction
.NumDstRegs
<= TGSI_FULL_MAX_DST_REGISTERS
);
169 for( i
= 0; i
< inst
->Instruction
.NumDstRegs
; i
++ ) {
171 next_token( ctx
, &inst
->Dst
[i
].Register
);
174 * No support for indirect or multi-dimensional addressing.
176 assert( !inst
->Dst
[i
].Register
.Dimension
);
178 if( inst
->Dst
[i
].Register
.Indirect
) {
179 next_token( ctx
, &inst
->Dst
[i
].Indirect
);
182 * No support for indirect or multi-dimensional addressing.
184 assert( !inst
->Dst
[i
].Indirect
.Dimension
);
185 assert( !inst
->Dst
[i
].Indirect
.Indirect
);
189 assert( inst
->Instruction
.NumSrcRegs
<= TGSI_FULL_MAX_SRC_REGISTERS
);
191 for( i
= 0; i
< inst
->Instruction
.NumSrcRegs
; i
++ ) {
193 next_token( ctx
, &inst
->Src
[i
].Register
);
195 if( inst
->Src
[i
].Register
.Indirect
) {
196 next_token( ctx
, &inst
->Src
[i
].Indirect
);
199 * No support for indirect or multi-dimensional addressing.
201 assert( !inst
->Src
[i
].Indirect
.Indirect
);
202 assert( !inst
->Src
[i
].Indirect
.Dimension
);
205 if( inst
->Src
[i
].Register
.Dimension
) {
206 next_token( ctx
, &inst
->Src
[i
].Dimension
);
209 * No support for multi-dimensional addressing.
211 assert( !inst
->Src
[i
].Dimension
.Dimension
);
213 if( inst
->Src
[i
].Dimension
.Indirect
) {
214 next_token( ctx
, &inst
->Src
[i
].DimIndirect
);
217 * No support for indirect or multi-dimensional addressing.
219 assert( !inst
->Src
[i
].Indirect
.Indirect
);
220 assert( !inst
->Src
[i
].Indirect
.Dimension
);
235 tgsi_num_tokens(const struct tgsi_token
*tokens
)
237 struct tgsi_parse_context ctx
;
238 if (tgsi_parse_init(&ctx
, tokens
) == TGSI_PARSE_OK
) {
239 unsigned len
= (ctx
.FullHeader
.Header
.HeaderSize
+
240 ctx
.FullHeader
.Header
.BodySize
+
249 * Make a new copy of a token array.
252 tgsi_dup_tokens(const struct tgsi_token
*tokens
)
254 unsigned n
= tgsi_num_tokens(tokens
);
255 unsigned bytes
= n
* sizeof(struct tgsi_token
);
256 struct tgsi_token
*new_tokens
= (struct tgsi_token
*) MALLOC(bytes
);
258 memcpy(new_tokens
, tokens
, bytes
);