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