1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 Luca Barbieri
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Header for Shader Model 4.0, 4.1 and 5.0 */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef SM4_H_
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SM4_H_
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdint.h>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h>
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <memory>
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <vector>
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <map>
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <iostream>
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "le32.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sm4_defs.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_opcode_names[];
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_file_names[];
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_shortfile_names[];
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_target_names[];
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_interpolation_names[];
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern const char* sm4_sv_names[];
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_token_version
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned minor : 4;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned major : 4;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned format : 8;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned type : 16;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_token_instruction
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	// we don't make it an union directly because unions can't be inherited from
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	union
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		// length and extended are always present, but they are only here to reduce duplication
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned _11_23 : 13;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned length : 7;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned extended : 1;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		};
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned resinfo_return_type : 2;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned sat : 1;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned _14_17 : 4;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned test_nz : 1; // bit 18
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned precise_mask : 4;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned _23 : 1;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned length : 7;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned extended : 1;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} insn;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned threads_in_group : 1;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned shared_memory : 1;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned uav_group : 1;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned uav_global : 1;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned _15_17 : 3;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} sync;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned allow_refactoring : 1;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned fp64 : 1;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned early_depth_stencil : 1;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned enable_raw_and_structured_in_non_cs : 1;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_global_flags;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned target : 5;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned nr_samples : 7;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_resource;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned shadow : 1;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned mono : 1;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_sampler;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned interpolation : 5;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_input_ps;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned dynamic : 1;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_constant_buffer;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned primitive : 6;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_gs_input_primitive;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned primitive_topology : 7;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_gs_output_primitive_topology;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned control_points : 6;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_input_control_point_count;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned control_points : 6;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_output_control_point_count;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned domain : 3; /* D3D_TESSELLATOR_DOMAIN */
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_tess_domain;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned partitioning : 3; /* D3D_TESSELLATOR_PARTITIONING */
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_tess_partitioning;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned opcode : 11;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned primitive : 3; /* D3D_TESSELLATOR_OUTPUT_PRIMITIVE */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} dcl_tess_output_primitive;
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion sm4_token_instruction_extended
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned type : 6;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned _6_30 : 25;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned extended :1;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned type : 6;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned _6_8 : 3;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int offset_u : 4;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int offset_v : 4;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int offset_w : 4;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} sample_controls;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned type : 6;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned target : 5;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} resource_target;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned type : 6;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned x : 4;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned y : 4;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned z : 4;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned w : 4;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} resource_return_type;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_token_resource_return_type
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned x : 4;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned y : 4;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned z : 4;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned w : 4;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_token_operand
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned comps_enum : 2; /* sm4_operands_comps */
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned mode : 2; /* sm4_operand_mode */
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned sel : 8;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned file : 8; /* sm4_file */
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_indices : 2;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned index0_repr : 3; /* sm4_operand_index_repr */
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned index1_repr : 3; /* sm4_operand_index_repr */
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned index2_repr : 3; /* sm4_operand_index_repr */
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned extended : 1;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SM4_OPERAND_SEL_MASK(sel) ((sel) & 0xf)
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SM4_OPERAND_SEL_SWZ(sel, i) (((sel) >> ((i) * 2)) & 3)
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SM4_OPERAND_SEL_SCALAR(sel) ((sel) & 3)
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_token_operand_extended
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned type : 6;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned neg : 1;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned abs : 1;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunion sm4_any
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	double f64;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	float f32;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int64_t i64;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int32_t i32;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint64_t u64;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int64_t u32;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_op;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_insn;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_dcl;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_program;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::ostream& operator <<(std::ostream& out, const sm4_op& op);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::ostream& operator <<(std::ostream& out, const sm4_insn& op);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::ostream& operator <<(std::ostream& out, const sm4_dcl& op);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::ostream& operator <<(std::ostream& out, const sm4_program& op);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_op
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t mode;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t comps;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t mask;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t num_indices;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t swizzle[4];
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_file file;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_any imm_values[4];
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool neg;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool abs;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		int64_t disp;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		std::auto_ptr<sm4_op> reg;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} indices[3];
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool is_index_simple(unsigned i) const
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 return !indices[i].reg.get() && indices[i].disp >= 0 && (int64_t)(int32_t)indices[i].disp == indices[i].disp;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool has_simple_index() const
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return num_indices == 1 && is_index_simple(0);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_op()
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(this, 0, sizeof(*this));
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void dump();
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_op(const sm4_op& op)
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{}
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* for sample_d */
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SM4_MAX_OPS 6
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_insn : public sm4_token_instruction
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int8_t sample_offset[3];
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t resource_target;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	uint8_t resource_return_type[4];
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num;
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_ops;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::auto_ptr<sm4_op> ops[SM4_MAX_OPS];
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_insn()
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(this, 0, sizeof(*this));
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void dump();
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_insn(const sm4_insn& op)
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{}
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_dcl : public sm4_token_instruction
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::auto_ptr<sm4_op> op;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	union
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned num;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		float f32;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sm4_sv sv;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned id;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned expected_function_table_length;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned table_length;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned array_length;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} intf;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned thread_group_size[3];
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		sm4_token_resource_return_type rrt;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned num;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned comps;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} indexable_temp;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		{
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned stride;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned count;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		} structured;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	};
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void* data;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_dcl()
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(this, 0, sizeof(*this));
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	~sm4_dcl()
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		free(data);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void dump();
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_dcl(const sm4_dcl& op)
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{}
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct _D3D11_SIGNATURE_PARAMETER_DESC;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_program
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_token_version version;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::vector<sm4_dcl*> dcls;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::vector<sm4_insn*> insns;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_D3D11_SIGNATURE_PARAMETER_DESC* params_in;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_D3D11_SIGNATURE_PARAMETER_DESC* params_out;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_D3D11_SIGNATURE_PARAMETER_DESC* params_patch;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_params_in;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_params_out;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned num_params_patch;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* for ifs, the insn number of the else or endif if there is no else
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * for elses, the insn number of the endif
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * for endifs, the insn number of the if
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * for loops, the insn number of the endloop
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * for endloops, the insn number of the loop
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * for all others, -1
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::vector<int> cf_insn_linked;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bool labels_found;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	std::vector<int> label_to_insn_num;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_program()
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memset(&version, 0, sizeof(version));
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		labels_found = false;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		num_params_in = num_params_out = num_params_patch = 0;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	~sm4_program()
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(std::vector<sm4_dcl*>::iterator i = dcls.begin(), e = dcls.end(); i != e; ++i)
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			delete *i;
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for(std::vector<sm4_insn*>::iterator i = insns.begin(), e = insns.end(); i != e; ++i)
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			delete *i;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(num_params_in)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			free(params_in);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(num_params_out)
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			free(params_out);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if(num_params_patch)
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			free(params_patch);
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void dump();
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sm4_program(const sm4_dcl& op)
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{}
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsm4_program* sm4_parse(void* tokens, int size);
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool sm4_link_cf_insns(sm4_program& program);
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool sm4_find_labels(sm4_program& program);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* SM4_H_ */
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417