1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2012-2021 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17bf215546Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci *
22bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
23bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
24bf215546Sopenharmony_ci * of the Software.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci/*
29bf215546Sopenharmony_ci * ShaderParse.c --
30bf215546Sopenharmony_ci *    Functions for parsing shader tokens.
31bf215546Sopenharmony_ci */
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "Debug.h"
34bf215546Sopenharmony_ci#include "ShaderParse.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#include "util/u_memory.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_civoid
40bf215546Sopenharmony_ciShader_parse_init(struct Shader_parser *parser,
41bf215546Sopenharmony_ci                       const unsigned *code)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   parser->curr = parser->code = code;
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci   parser->header.type = DECODE_D3D10_SB_TOKENIZED_PROGRAM_TYPE(*parser->curr);
46bf215546Sopenharmony_ci   parser->header.major_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MAJOR_VERSION(*parser->curr);
47bf215546Sopenharmony_ci   parser->header.minor_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MINOR_VERSION(*parser->curr);
48bf215546Sopenharmony_ci   parser->curr++;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci   parser->header.size = DECODE_D3D10_SB_TOKENIZED_PROGRAM_LENGTH(*parser->curr);
51bf215546Sopenharmony_ci   parser->curr++;
52bf215546Sopenharmony_ci}
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci#define OP_NOT_DONE (1 << 0) /* not implemented yet */
55bf215546Sopenharmony_ci#define OP_SATURATE (1 << 1) /* saturate in opcode specific control */
56bf215546Sopenharmony_ci#define OP_TEST_BOOLEAN (1 << 2) /* test boolean in opcode specific control */
57bf215546Sopenharmony_ci#define OP_DCL (1 << 3) /* custom opcode specific control */
58bf215546Sopenharmony_ci#define OP_RESINFO_RET_TYPE (1 << 4) /* return type for resinfo */
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_cistruct dx10_opcode_info {
61bf215546Sopenharmony_ci   D3D10_SB_OPCODE_TYPE type;
62bf215546Sopenharmony_ci   const char *name;
63bf215546Sopenharmony_ci   unsigned num_dst;
64bf215546Sopenharmony_ci   unsigned num_src;
65bf215546Sopenharmony_ci   unsigned flags;
66bf215546Sopenharmony_ci};
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci#define _(_opcode) _opcode, #_opcode
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_cistatic const struct dx10_opcode_info
71bf215546Sopenharmony_ciopcode_info[D3D10_SB_NUM_OPCODES] = {
72bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ADD),                              1, 2, OP_SATURATE},
73bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_AND),                              1, 2, 0},
74bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_BREAK),                            0, 0, 0},
75bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_BREAKC),                           0, 1, OP_TEST_BOOLEAN},
76bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CALL),                             0, 1, 0},
77bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CALLC),                            0, 2, OP_TEST_BOOLEAN},
78bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CASE),                             0, 1, 0},
79bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CONTINUE),                         0, 0, 0},
80bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CONTINUEC),                        0, 1, OP_TEST_BOOLEAN},
81bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CUT),                              0, 0, 0},
82bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DEFAULT),                          0, 0, 0},
83bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DERIV_RTX),                        1, 1, OP_SATURATE},
84bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DERIV_RTY),                        1, 1, OP_SATURATE},
85bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DISCARD),                          0, 1, OP_TEST_BOOLEAN},
86bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DIV),                              1, 2, OP_SATURATE},
87bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DP2),                              1, 2, OP_SATURATE},
88bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DP3),                              1, 2, OP_SATURATE},
89bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DP4),                              1, 2, OP_SATURATE},
90bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ELSE),                             0, 0, 0},
91bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_EMIT),                             0, 0, 0},
92bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_EMITTHENCUT),                      0, 0, 0},
93bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ENDIF),                            0, 0, 0},
94bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ENDLOOP),                          0, 0, 0},
95bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ENDSWITCH),                        0, 0, 0},
96bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_EQ),                               1, 2, 0},
97bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_EXP),                              1, 1, OP_SATURATE},
98bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_FRC),                              1, 1, OP_SATURATE},
99bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_FTOI),                             1, 1, 0},
100bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_FTOU),                             1, 1, 0},
101bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_GE),                               1, 2, 0},
102bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IADD),                             1, 2, 0},
103bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IF),                               0, 1, OP_TEST_BOOLEAN},
104bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IEQ),                              1, 2, 0},
105bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IGE),                              1, 2, 0},
106bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ILT),                              1, 2, 0},
107bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IMAD),                             1, 3, 0},
108bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IMAX),                             1, 2, 0},
109bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IMIN),                             1, 2, 0},
110bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_IMUL),                             2, 2, 0},
111bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_INE),                              1, 2, 0},
112bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_INEG),                             1, 1, 0},
113bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ISHL),                             1, 2, 0},
114bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ISHR),                             1, 2, 0},
115bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ITOF),                             1, 1, 0},
116bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LABEL),                            0, 1, 0},
117bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LD),                               1, 2, 0},
118bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LD_MS),                            1, 3, 0},
119bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LOG),                              1, 1, OP_SATURATE},
120bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LOOP),                             0, 0, 0},
121bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_LT),                               1, 2, 0},
122bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MAD),                              1, 3, OP_SATURATE},
123bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MIN),                              1, 2, OP_SATURATE},
124bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MAX),                              1, 2, OP_SATURATE},
125bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_CUSTOMDATA),                       0, 0, 0},
126bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MOV),                              1, 1, OP_SATURATE},
127bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MOVC),                             1, 3, OP_SATURATE},
128bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_MUL),                              1, 2, OP_SATURATE},
129bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_NE),                               1, 2, 0},
130bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_NOP),                              0, 0, 0},
131bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_NOT),                              1, 1, 0},
132bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_OR),                               1, 2, 0},
133bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_RESINFO),                          1, 2, OP_RESINFO_RET_TYPE},
134bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_RET),                              0, 0, 0},
135bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_RETC),                             0, 1, OP_TEST_BOOLEAN},
136bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ROUND_NE),                         1, 1, OP_SATURATE},
137bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ROUND_NI),                         1, 1, OP_SATURATE},
138bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ROUND_PI),                         1, 1, OP_SATURATE},
139bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ROUND_Z),                          1, 1, OP_SATURATE},
140bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_RSQ),                              1, 1, OP_SATURATE},
141bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE),                           1, 3, 0},
142bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE_C),                         1, 4, 0},
143bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE_C_LZ),                      1, 4, 0},
144bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE_L),                         1, 4, 0},
145bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE_D),                         1, 5, 0},
146bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SAMPLE_B),                         1, 4, 0},
147bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SQRT),                             1, 1, OP_SATURATE},
148bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SWITCH),                           0, 1, 0},
149bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_SINCOS),                           2, 1, OP_SATURATE},
150bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UDIV),                             2, 2, 0},
151bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_ULT),                              1, 2, 0},
152bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UGE),                              1, 2, 0},
153bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UMUL),                             2, 2, 0},
154bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UMAD),                             1, 3, 0},
155bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UMAX),                             1, 2, 0},
156bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UMIN),                             1, 2, 0},
157bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_USHR),                             1, 2, 0},
158bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_UTOF),                             1, 1, 0},
159bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_XOR),                              1, 2, 0},
160bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_RESOURCE),                     1, 0, OP_DCL},
161bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER),              0, 1, OP_DCL},
162bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_SAMPLER),                      1, 0, OP_DCL},
163bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INDEX_RANGE),                  1, 0, OP_DCL},
164bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY), 0, 0, OP_DCL},
165bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE),           0, 0, OP_DCL},
166bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT),      0, 0, OP_DCL},
167bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT),                        1, 0, OP_DCL},
168bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT_SGV),                    1, 0, OP_DCL},
169bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT_SIV),                    1, 0, OP_DCL},
170bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT_PS),                     1, 0, OP_DCL},
171bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT_PS_SGV),                 1, 0, OP_DCL},
172bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INPUT_PS_SIV),                 1, 0, OP_DCL},
173bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_OUTPUT),                       1, 0, OP_DCL},
174bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_OUTPUT_SGV),                   1, 0, OP_DCL},
175bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_OUTPUT_SIV),                   1, 0, OP_DCL},
176bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_TEMPS),                        0, 0, OP_DCL},
177bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP),               0, 0, OP_DCL},
178bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS),                 0, 0, OP_DCL},
179bf215546Sopenharmony_ci   {_(D3D10_SB_OPCODE_RESERVED0),                        0, 0, OP_NOT_DONE},
180bf215546Sopenharmony_ci   {_(D3D10_1_SB_OPCODE_LOD),                            0, 0, OP_NOT_DONE},
181bf215546Sopenharmony_ci   {_(D3D10_1_SB_OPCODE_GATHER4),                        0, 0, OP_NOT_DONE},
182bf215546Sopenharmony_ci   {_(D3D10_1_SB_OPCODE_SAMPLE_POS),                     0, 0, OP_NOT_DONE},
183bf215546Sopenharmony_ci   {_(D3D10_1_SB_OPCODE_SAMPLE_INFO),                    0, 0, OP_NOT_DONE}
184bf215546Sopenharmony_ci};
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci#undef _
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_cistatic void
189bf215546Sopenharmony_ciparse_operand(const unsigned **curr,
190bf215546Sopenharmony_ci              struct Shader_operand *operand)
191bf215546Sopenharmony_ci{
192bf215546Sopenharmony_ci   operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci   /* Index dimension. */
195bf215546Sopenharmony_ci   switch (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr)) {
196bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_0D:
197bf215546Sopenharmony_ci      operand->index_dim = 0;
198bf215546Sopenharmony_ci      break;
199bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_1D:
200bf215546Sopenharmony_ci      operand->index_dim = 1;
201bf215546Sopenharmony_ci      break;
202bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_2D:
203bf215546Sopenharmony_ci      operand->index_dim = 2;
204bf215546Sopenharmony_ci      break;
205bf215546Sopenharmony_ci   default:
206bf215546Sopenharmony_ci      assert(0);
207bf215546Sopenharmony_ci   }
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci   if (operand->index_dim >= 1) {
210bf215546Sopenharmony_ci      operand->index[0].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr);
211bf215546Sopenharmony_ci      if (operand->index_dim >= 2) {
212bf215546Sopenharmony_ci         operand->index[1].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(1, **curr);
213bf215546Sopenharmony_ci      }
214bf215546Sopenharmony_ci   }
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci   (*curr)++;
217bf215546Sopenharmony_ci}
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_cistatic void
220bf215546Sopenharmony_ciparse_relative_operand(const unsigned **curr,
221bf215546Sopenharmony_ci                       struct Shader_relative_operand *operand)
222bf215546Sopenharmony_ci{
223bf215546Sopenharmony_ci   assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(**curr));
224bf215546Sopenharmony_ci   assert(DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(**curr) == D3D10_SB_OPERAND_4_COMPONENT);
225bf215546Sopenharmony_ci   assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(**curr) == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE);
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci   operand->comp = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(**curr);
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
230bf215546Sopenharmony_ci   assert(operand->type != D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   /* Index dimension. */
233bf215546Sopenharmony_ci   assert(DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr) == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   if (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_1D) {
236bf215546Sopenharmony_ci      (*curr)++;
237bf215546Sopenharmony_ci      operand->index[0].imm = **curr;
238bf215546Sopenharmony_ci   } else {
239bf215546Sopenharmony_ci      assert(DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_2D);
240bf215546Sopenharmony_ci      (*curr)++;
241bf215546Sopenharmony_ci      operand->index[0].imm = **curr;
242bf215546Sopenharmony_ci      (*curr)++;
243bf215546Sopenharmony_ci      operand->index[1].imm = **curr;
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci   }
246bf215546Sopenharmony_ci   (*curr)++;
247bf215546Sopenharmony_ci}
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_cistatic void
250bf215546Sopenharmony_ciparse_index(const unsigned **curr,
251bf215546Sopenharmony_ci            struct Shader_index *index)
252bf215546Sopenharmony_ci{
253bf215546Sopenharmony_ci   switch (index->index_rep) {
254bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
255bf215546Sopenharmony_ci      index->imm = *(*curr)++;
256bf215546Sopenharmony_ci      break;
257bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_RELATIVE:
258bf215546Sopenharmony_ci      index->imm = 0;
259bf215546Sopenharmony_ci      parse_relative_operand(curr, &index->rel);
260bf215546Sopenharmony_ci      break;
261bf215546Sopenharmony_ci   case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
262bf215546Sopenharmony_ci      index->imm = *(*curr)++;
263bf215546Sopenharmony_ci      parse_relative_operand(curr, &index->rel);
264bf215546Sopenharmony_ci      break;
265bf215546Sopenharmony_ci   default:
266bf215546Sopenharmony_ci      /* XXX: Support other index representations.
267bf215546Sopenharmony_ci       */
268bf215546Sopenharmony_ci      assert(0);
269bf215546Sopenharmony_ci   }
270bf215546Sopenharmony_ci}
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_cistatic void
273bf215546Sopenharmony_ciparse_operand_index(const unsigned **curr,
274bf215546Sopenharmony_ci                    struct Shader_operand *operand)
275bf215546Sopenharmony_ci{
276bf215546Sopenharmony_ci   if (operand->index_dim >= 1) {
277bf215546Sopenharmony_ci      parse_index(curr, &operand->index[0]);
278bf215546Sopenharmony_ci      if (operand->index_dim >= 2) {
279bf215546Sopenharmony_ci         parse_index(curr, &operand->index[1]);
280bf215546Sopenharmony_ci      }
281bf215546Sopenharmony_ci   }
282bf215546Sopenharmony_ci}
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ciboolean
285bf215546Sopenharmony_ciShader_parse_opcode(struct Shader_parser *parser,
286bf215546Sopenharmony_ci                         struct Shader_opcode *opcode)
287bf215546Sopenharmony_ci{
288bf215546Sopenharmony_ci   const unsigned *curr = parser->curr;
289bf215546Sopenharmony_ci   const struct dx10_opcode_info *info;
290bf215546Sopenharmony_ci   unsigned length;
291bf215546Sopenharmony_ci   boolean opcode_is_extended;
292bf215546Sopenharmony_ci   unsigned i;
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci   if (curr >= parser->code + parser->header.size) {
295bf215546Sopenharmony_ci      return FALSE;
296bf215546Sopenharmony_ci   }
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   memset(opcode, 0, sizeof *opcode);
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   /* Opcode type. */
301bf215546Sopenharmony_ci   opcode->type = DECODE_D3D10_SB_OPCODE_TYPE(*curr);
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_ci   if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
304bf215546Sopenharmony_ci      opcode->customdata._class = DECODE_D3D10_SB_CUSTOMDATA_CLASS(*curr);
305bf215546Sopenharmony_ci      curr++;
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci      assert(opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER);
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci      opcode->customdata.u.constbuf.count = *curr - 2;
310bf215546Sopenharmony_ci      curr++;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci      opcode->customdata.u.constbuf.data = MALLOC(opcode->customdata.u.constbuf.count * sizeof(unsigned));
313bf215546Sopenharmony_ci      assert(opcode->customdata.u.constbuf.data);
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci      memcpy(opcode->customdata.u.constbuf.data,
316bf215546Sopenharmony_ci             curr,
317bf215546Sopenharmony_ci             opcode->customdata.u.constbuf.count * sizeof(unsigned));
318bf215546Sopenharmony_ci      curr += opcode->customdata.u.constbuf.count;
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci      parser->curr = curr;
321bf215546Sopenharmony_ci      return TRUE;
322bf215546Sopenharmony_ci   }
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci   opcode->dcl_siv_name = D3D10_SB_NAME_UNDEFINED;
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   /* Lookup extra information based on opcode type. */
327bf215546Sopenharmony_ci   assert(opcode->type < D3D10_SB_NUM_OPCODES);
328bf215546Sopenharmony_ci   info = &opcode_info[opcode->type];
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   /* Opcode specific. */
331bf215546Sopenharmony_ci   switch (opcode->type) {
332bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_RESOURCE:
333bf215546Sopenharmony_ci      opcode->specific.dcl_resource_dimension = DECODE_D3D10_SB_RESOURCE_DIMENSION(*curr);
334bf215546Sopenharmony_ci      break;
335bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_SAMPLER:
336bf215546Sopenharmony_ci      opcode->specific.dcl_sampler_mode = DECODE_D3D10_SB_SAMPLER_MODE(*curr);
337bf215546Sopenharmony_ci      break;
338bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
339bf215546Sopenharmony_ci      opcode->specific.dcl_gs_output_primitive_topology = DECODE_D3D10_SB_GS_OUTPUT_PRIMITIVE_TOPOLOGY(*curr);
340bf215546Sopenharmony_ci      break;
341bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE:
342bf215546Sopenharmony_ci      opcode->specific.dcl_gs_input_primitive = DECODE_D3D10_SB_GS_INPUT_PRIMITIVE(*curr);
343bf215546Sopenharmony_ci      break;
344bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_PS:
345bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
346bf215546Sopenharmony_ci      opcode->specific.dcl_in_ps_interp = DECODE_D3D10_SB_INPUT_INTERPOLATION_MODE(*curr);
347bf215546Sopenharmony_ci      break;
348bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS:
349bf215546Sopenharmony_ci      opcode->specific.global_flags.refactoring_allowed = DECODE_D3D10_SB_GLOBAL_FLAGS(*curr) ? 1 : 0;
350bf215546Sopenharmony_ci      break;
351bf215546Sopenharmony_ci   default:
352bf215546Sopenharmony_ci      /* Parse opcode-specific control bits */
353bf215546Sopenharmony_ci      if (info->flags & OP_DCL) {
354bf215546Sopenharmony_ci         /* no-op */
355bf215546Sopenharmony_ci      } else if (info->flags & OP_SATURATE) {
356bf215546Sopenharmony_ci         opcode->saturate =
357bf215546Sopenharmony_ci            !!DECODE_IS_D3D10_SB_INSTRUCTION_SATURATE_ENABLED(*curr);
358bf215546Sopenharmony_ci      } else if (info->flags & OP_TEST_BOOLEAN) {
359bf215546Sopenharmony_ci         opcode->specific.test_boolean =
360bf215546Sopenharmony_ci            DECODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN(*curr);
361bf215546Sopenharmony_ci      } else if (info->flags & OP_RESINFO_RET_TYPE) {
362bf215546Sopenharmony_ci         opcode->specific.resinfo_ret_type =
363bf215546Sopenharmony_ci            DECODE_D3D10_SB_RESINFO_INSTRUCTION_RETURN_TYPE(*curr);
364bf215546Sopenharmony_ci      } else {
365bf215546Sopenharmony_ci         /* Warn if there are bits set in the opcode-specific controls (bits 23:11 inclusive)*/
366bf215546Sopenharmony_ci         if (*curr & ((1 << 24) - (1 << 11))) {
367bf215546Sopenharmony_ci            debug_printf("warning: unexpected opcode-specific control in opcode %s\n",
368bf215546Sopenharmony_ci                         info->name);
369bf215546Sopenharmony_ci         }
370bf215546Sopenharmony_ci      }
371bf215546Sopenharmony_ci      break;
372bf215546Sopenharmony_ci   }
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_ci   /* Opcode length in DWORDs. */
375bf215546Sopenharmony_ci   length = DECODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(*curr);
376bf215546Sopenharmony_ci   assert(curr + length <= parser->code + parser->header.size);
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci   /* Opcode specific fields in token0. */
379bf215546Sopenharmony_ci   switch (opcode->type) {
380bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER:
381bf215546Sopenharmony_ci      opcode->specific.dcl_cb_access_pattern =
382bf215546Sopenharmony_ci         DECODE_D3D10_SB_CONSTANT_BUFFER_ACCESS_PATTERN(*curr);
383bf215546Sopenharmony_ci      break;
384bf215546Sopenharmony_ci   default:
385bf215546Sopenharmony_ci      break;
386bf215546Sopenharmony_ci   }
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci   opcode_is_extended = DECODE_IS_D3D10_SB_OPCODE_EXTENDED(*curr);
389bf215546Sopenharmony_ci
390bf215546Sopenharmony_ci   curr++;
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   if (opcode_is_extended) {
393bf215546Sopenharmony_ci      /* NOTE: DECODE_IS_D3D10_SB_OPCODE_DOUBLE_EXTENDED is broken.
394bf215546Sopenharmony_ci       */
395bf215546Sopenharmony_ci      assert(!((*curr & D3D10_SB_OPERAND_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci      switch (DECODE_D3D10_SB_EXTENDED_OPCODE_TYPE(*curr)) {
398bf215546Sopenharmony_ci      case D3D10_SB_EXTENDED_OPCODE_EMPTY:
399bf215546Sopenharmony_ci         break;
400bf215546Sopenharmony_ci      case D3D10_SB_EXTENDED_OPCODE_SAMPLE_CONTROLS:
401bf215546Sopenharmony_ci         opcode->imm_texel_offset.u = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_U, *curr);
402bf215546Sopenharmony_ci         opcode->imm_texel_offset.v = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_V, *curr);
403bf215546Sopenharmony_ci         opcode->imm_texel_offset.w = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_W, *curr);
404bf215546Sopenharmony_ci         break;
405bf215546Sopenharmony_ci      default:
406bf215546Sopenharmony_ci         assert(0);
407bf215546Sopenharmony_ci      }
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci      curr++;
410bf215546Sopenharmony_ci   }
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci   if (info->flags & OP_NOT_DONE) {
413bf215546Sopenharmony_ci      /* XXX: Need to figure out the number of operands for this opcode.
414bf215546Sopenharmony_ci       *      Should be okay to continue execution -- we have enough info
415bf215546Sopenharmony_ci       *      to skip to the next instruction.
416bf215546Sopenharmony_ci       */
417bf215546Sopenharmony_ci      LOG_UNSUPPORTED(TRUE);
418bf215546Sopenharmony_ci      opcode->num_dst = 0;
419bf215546Sopenharmony_ci      opcode->num_src = 0;
420bf215546Sopenharmony_ci      goto skip;
421bf215546Sopenharmony_ci   }
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_ci   opcode->num_dst = info->num_dst;
424bf215546Sopenharmony_ci   opcode->num_src = info->num_src;
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   /* Destination operands. */
427bf215546Sopenharmony_ci   for (i = 0; i < info->num_dst; i++) {
428bf215546Sopenharmony_ci      D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci      assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr));
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci      num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
433bf215546Sopenharmony_ci      if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
434bf215546Sopenharmony_ci         D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci         selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
437bf215546Sopenharmony_ci         assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci         opcode->dst[i].mask = DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr);
440bf215546Sopenharmony_ci      } else {
441bf215546Sopenharmony_ci         assert(num_components == D3D10_SB_OPERAND_0_COMPONENT ||
442bf215546Sopenharmony_ci                num_components == D3D10_SB_OPERAND_1_COMPONENT);
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci         opcode->dst[i].mask = D3D10_SB_OPERAND_4_COMPONENT_MASK_X;
445bf215546Sopenharmony_ci      }
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci      parse_operand(&curr, &opcode->dst[i].base);
448bf215546Sopenharmony_ci      parse_operand_index(&curr, &opcode->dst[i].base);
449bf215546Sopenharmony_ci   }
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci   /* Source operands. */
452bf215546Sopenharmony_ci   for (i = 0; i < info->num_src; i++) {
453bf215546Sopenharmony_ci      boolean extended;
454bf215546Sopenharmony_ci      D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci      extended = DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr);
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci      num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
459bf215546Sopenharmony_ci      if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
460bf215546Sopenharmony_ci         D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci         selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci         if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE) {
465bf215546Sopenharmony_ci            opcode->src[i].swizzle[0] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 0);
466bf215546Sopenharmony_ci            opcode->src[i].swizzle[1] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 1);
467bf215546Sopenharmony_ci            opcode->src[i].swizzle[2] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 2);
468bf215546Sopenharmony_ci            opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 3);
469bf215546Sopenharmony_ci         } else if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE) {
470bf215546Sopenharmony_ci            opcode->src[i].swizzle[0] =
471bf215546Sopenharmony_ci               opcode->src[i].swizzle[1] =
472bf215546Sopenharmony_ci               opcode->src[i].swizzle[2] =
473bf215546Sopenharmony_ci               opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(*curr);
474bf215546Sopenharmony_ci         } else {
475bf215546Sopenharmony_ci            /* This case apparently happens only for 4-component 32-bit
476bf215546Sopenharmony_ci             * immediate operands.
477bf215546Sopenharmony_ci             */
478bf215546Sopenharmony_ci            assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
479bf215546Sopenharmony_ci            assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr) == 0);
480bf215546Sopenharmony_ci            assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci
483bf215546Sopenharmony_ci            opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
484bf215546Sopenharmony_ci            opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
485bf215546Sopenharmony_ci            opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
486bf215546Sopenharmony_ci            opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
487bf215546Sopenharmony_ci         }
488bf215546Sopenharmony_ci      } else if (num_components == D3D10_SB_OPERAND_1_COMPONENT) {
489bf215546Sopenharmony_ci         opcode->src[i].swizzle[0] =
490bf215546Sopenharmony_ci            opcode->src[i].swizzle[1] =
491bf215546Sopenharmony_ci            opcode->src[i].swizzle[2] =
492bf215546Sopenharmony_ci            opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_X;
493bf215546Sopenharmony_ci      } else {
494bf215546Sopenharmony_ci         /* Samplers only?
495bf215546Sopenharmony_ci          */
496bf215546Sopenharmony_ci         assert(num_components == D3D10_SB_OPERAND_0_COMPONENT);
497bf215546Sopenharmony_ci         assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_SAMPLER ||
498bf215546Sopenharmony_ci                DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_LABEL);
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_ci         opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
501bf215546Sopenharmony_ci         opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
502bf215546Sopenharmony_ci         opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
503bf215546Sopenharmony_ci         opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
504bf215546Sopenharmony_ci      }
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci      parse_operand(&curr, &opcode->src[i].base);
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci      opcode->src[i].modifier = D3D10_SB_OPERAND_MODIFIER_NONE;
509bf215546Sopenharmony_ci      if (extended) {
510bf215546Sopenharmony_ci         /* NOTE: DECODE_IS_D3D10_SB_OPERAND_DOUBLE_EXTENDED is broken.
511bf215546Sopenharmony_ci          */
512bf215546Sopenharmony_ci         assert(!((*curr & D3D10_SB_OPERAND_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci         switch (DECODE_D3D10_SB_EXTENDED_OPERAND_TYPE(*curr)) {
515bf215546Sopenharmony_ci         case D3D10_SB_EXTENDED_OPERAND_EMPTY:
516bf215546Sopenharmony_ci            break;
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci         case D3D10_SB_EXTENDED_OPERAND_MODIFIER:
519bf215546Sopenharmony_ci            opcode->src[i].modifier = DECODE_D3D10_SB_OPERAND_MODIFIER(*curr);
520bf215546Sopenharmony_ci            break;
521bf215546Sopenharmony_ci
522bf215546Sopenharmony_ci         default:
523bf215546Sopenharmony_ci            assert(0);
524bf215546Sopenharmony_ci         }
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci         curr++;
527bf215546Sopenharmony_ci      }
528bf215546Sopenharmony_ci
529bf215546Sopenharmony_ci      parse_operand_index(&curr, &opcode->src[i].base);
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci      if (opcode->src[i].base.type == D3D10_SB_OPERAND_TYPE_IMMEDIATE32) {
532bf215546Sopenharmony_ci         switch (num_components) {
533bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_1_COMPONENT:
534bf215546Sopenharmony_ci            opcode->src[i].imm[0].u32 =
535bf215546Sopenharmony_ci               opcode->src[i].imm[1].u32 =
536bf215546Sopenharmony_ci               opcode->src[i].imm[2].u32 =
537bf215546Sopenharmony_ci               opcode->src[i].imm[3].u32 = *curr++;
538bf215546Sopenharmony_ci            break;
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci         case D3D10_SB_OPERAND_4_COMPONENT:
541bf215546Sopenharmony_ci            opcode->src[i].imm[0].u32 = *curr++;
542bf215546Sopenharmony_ci            opcode->src[i].imm[1].u32 = *curr++;
543bf215546Sopenharmony_ci            opcode->src[i].imm[2].u32 = *curr++;
544bf215546Sopenharmony_ci            opcode->src[i].imm[3].u32 = *curr++;
545bf215546Sopenharmony_ci            break;
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci         default:
548bf215546Sopenharmony_ci            /* XXX: Support other component sizes.
549bf215546Sopenharmony_ci             */
550bf215546Sopenharmony_ci            assert(0);
551bf215546Sopenharmony_ci         }
552bf215546Sopenharmony_ci      }
553bf215546Sopenharmony_ci   }
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci   /* Opcode specific trailing operands. */
556bf215546Sopenharmony_ci   switch (opcode->type) {
557bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_RESOURCE:
558bf215546Sopenharmony_ci      opcode->dcl_resource_ret_type[0] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 0);
559bf215546Sopenharmony_ci      opcode->dcl_resource_ret_type[1] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 1);
560bf215546Sopenharmony_ci      opcode->dcl_resource_ret_type[2] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 2);
561bf215546Sopenharmony_ci      opcode->dcl_resource_ret_type[3] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 3);
562bf215546Sopenharmony_ci      curr++;
563bf215546Sopenharmony_ci      break;
564bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
565bf215546Sopenharmony_ci      opcode->specific.dcl_max_output_vertex_count = *curr;
566bf215546Sopenharmony_ci      curr++;
567bf215546Sopenharmony_ci      break;
568bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_SGV:
569bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_SIV:
570bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_PS_SGV:
571bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
572bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_OUTPUT_SIV:
573bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_OUTPUT_SGV:
574bf215546Sopenharmony_ci      opcode->dcl_siv_name = DECODE_D3D10_SB_NAME(*curr);
575bf215546Sopenharmony_ci      curr++;
576bf215546Sopenharmony_ci      break;
577bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_TEMPS:
578bf215546Sopenharmony_ci      opcode->specific.dcl_num_temps = *curr;
579bf215546Sopenharmony_ci      curr++;
580bf215546Sopenharmony_ci      break;
581bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
582bf215546Sopenharmony_ci      opcode->specific.dcl_indexable_temp.index = *curr++;
583bf215546Sopenharmony_ci      opcode->specific.dcl_indexable_temp.count = *curr++;
584bf215546Sopenharmony_ci      opcode->specific.dcl_indexable_temp.components = *curr++;
585bf215546Sopenharmony_ci      break;
586bf215546Sopenharmony_ci   case D3D10_SB_OPCODE_DCL_INDEX_RANGE:
587bf215546Sopenharmony_ci      opcode->specific.index_range_count = *curr++;
588bf215546Sopenharmony_ci      break;
589bf215546Sopenharmony_ci   default:
590bf215546Sopenharmony_ci      break;
591bf215546Sopenharmony_ci   }
592bf215546Sopenharmony_ci
593bf215546Sopenharmony_ci   assert(curr == parser->curr + length);
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ciskip:
596bf215546Sopenharmony_ci   /* Advance to the next opcode. */
597bf215546Sopenharmony_ci   parser->curr += length;
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_ci   return TRUE;
600bf215546Sopenharmony_ci}
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_civoid
603bf215546Sopenharmony_ciShader_opcode_free(struct Shader_opcode *opcode)
604bf215546Sopenharmony_ci{
605bf215546Sopenharmony_ci   if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
606bf215546Sopenharmony_ci      if (opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER) {
607bf215546Sopenharmony_ci         FREE(opcode->customdata.u.constbuf.data);
608bf215546Sopenharmony_ci      }
609bf215546Sopenharmony_ci   }
610bf215546Sopenharmony_ci}
611