192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri/**************************************************************************
292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Copyright 2010 Luca Barbieri
492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * Permission is hereby granted, free of charge, to any person obtaining
692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * a copy of this software and associated documentation files (the
792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * "Software"), to deal in the Software without restriction, including
892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * without limitation the rights to use, copy, modify, merge, publish,
992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * distribute, sublicense, and/or sell copies of the Software, and to
1092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * permit persons to whom the Software is furnished to do so, subject to
1192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * the following conditions:
1292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
1392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * The above copyright notice and this permission notice (including the
1492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * next paragraph) shall be included in all copies or substantial
1592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * portions of the Software.
1692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
1792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
2192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri *
2592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri **************************************************************************/
2692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
27e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri#include "sm4.h"
2892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#include "utils.h"
2992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
3092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#if 1
3192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#define check(x) assert(x)
3292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#define fail(x) assert(0 && (x))
3392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#else
3492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#define check(x) do {if(!(x)) throw(#x);} while(0)
3592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#define fail(x) throw(x)
3692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#endif
3792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
38e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieristruct sm4_parser
3992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
4092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned* tokens;
4192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	unsigned* tokens_end;
42e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri	sm4_program& program;
4392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
44e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri	sm4_parser(sm4_program& program, void* p_tokens, unsigned size)
4592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	: program(program)
4692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
4792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		tokens = (unsigned*)p_tokens;
4892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		tokens_end = (unsigned*)((char*)p_tokens + size);
4992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
5092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
5192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	/* TODO: byteswap if machine is big endian */
5292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	uint32_t read32()
5392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
5492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		check(tokens < tokens_end);
5592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return bswap_le32(*tokens++);
5692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
5792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
5892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	template<typename T>
5992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void read_token(T* tok)
6092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
6192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		*(unsigned*)tok = read32();
6292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
6392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
6492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	uint64_t read64()
6592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
6692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned a = read32();
6792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned b = read32();
6892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return (uint64_t)a | ((uint64_t)b << 32);
6992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
7092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
7192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void skip(unsigned toskip)
7292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
7392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		tokens += toskip;
7492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
7592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
76e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri	void read_op(sm4_op* pop)
7792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
78e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		sm4_op& op = *pop;
79e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		sm4_token_operand optok;
8092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		read_token(&optok);
81e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		assert(optok.file < SM4_FILE_COUNT);
8292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.swizzle[0] = 0;
8392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.swizzle[1] = 1;
8492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.swizzle[2] = 2;
8592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.swizzle[3] = 3;
8692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.mask = 0xf;
8792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		switch(optok.comps_enum)
8892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
89e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		case SM4_OPERAND_COMPNUM_0:
9092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			op.comps = 0;
9192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			break;
92e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		case SM4_OPERAND_COMPNUM_1:
9392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			op.comps = 1;
94a531513b06be45868bc4d4f6a9757fe6992ef304Christoph Bumiller			op.swizzle[1] = op.swizzle[2] = op.swizzle[3] = 0;
9592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			break;
96e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		case SM4_OPERAND_COMPNUM_4:
9792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			op.comps = 4;
9892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			op.mode = optok.mode;
9992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			switch(optok.mode)
10092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
101e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_MODE_MASK:
102e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.mask = SM4_OPERAND_SEL_MASK(optok.sel);
10392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
104e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_MODE_SWIZZLE:
105e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.swizzle[0] = SM4_OPERAND_SEL_SWZ(optok.sel, 0);
106e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.swizzle[1] = SM4_OPERAND_SEL_SWZ(optok.sel, 1);
107e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.swizzle[2] = SM4_OPERAND_SEL_SWZ(optok.sel, 2);
108e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.swizzle[3] = SM4_OPERAND_SEL_SWZ(optok.sel, 3);
10992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
110e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_MODE_SCALAR:
111e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.swizzle[0] = op.swizzle[1] = op.swizzle[2] = op.swizzle[3] = SM4_OPERAND_SEL_SCALAR(optok.sel);
11292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
11392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
11492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			break;
115e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		case SM4_OPERAND_COMPNUM_N:
11692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			fail("Unhandled operand component type");
11792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
118e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		op.file = (sm4_file)optok.file;
11992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		op.num_indices = optok.num_indices;
12092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
12192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		if(optok.extended)
12292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
123e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			sm4_token_operand_extended optokext;
12492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			read_token(&optokext);
12592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(optokext.type == 0)
12692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{}
12792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else if(optokext.type == 1)
12892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
12992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.neg = optokext.neg;
13092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.abs= optokext.abs;
13192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
13292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
13392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				fail("Unhandled extended operand token type");
13492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
13592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
13692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		for(unsigned i = 0; i < op.num_indices; ++i)
13792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
13892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			unsigned repr;
13992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			if(i == 0)
14092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				repr = optok.index0_repr;
14192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else if(i == 1)
14292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				repr = optok.index1_repr;
14392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else if(i == 2)
14492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				repr = optok.index2_repr;
14592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
14692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				fail("Unhandled operand index representation");
147d1fd740bb778d7b3763e7c9b8383b1981084c318Christoph Bumiller			op.indices[i].disp = 0;
14892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			// TODO: is disp supposed to be signed here??
14992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			switch(repr)
15092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
151e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_INDEX_REPR_IMM32:
15292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.indices[i].disp = (int32_t)read32();
15392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
154e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_INDEX_REPR_IMM64:
15592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.indices[i].disp = read64();
15692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
157e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_INDEX_REPR_REG:
15892617aeac109481258f0c3863d09c1b8903d438bLuca Barbierirelative:
159e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				op.indices[i].reg.reset(new sm4_op());
160ee09c1e1c37ba7a143db3300b11ef3b324891563Christoph Bumiller				read_op(&*op.indices[i].reg);
16192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				break;
162e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_INDEX_REPR_REG_IMM32:
16392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.indices[i].disp = (int32_t)read32();
16492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				goto relative;
165e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			case SM4_OPERAND_INDEX_REPR_REG_IMM64:
16692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.indices[i].disp = read64();
16792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				goto relative;
16892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
16992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
17092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
171e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		if(op.file == SM4_FILE_IMMEDIATE32)
17292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
17392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i < op.comps; ++i)
17492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.imm_values[i].i32 = read32();
17592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
176e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri		else if(op.file == SM4_FILE_IMMEDIATE64)
17792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
17892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			for(unsigned i = 0; i < op.comps; ++i)
17992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				op.imm_values[i].i64 = read64();
18092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
18192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
18292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
18392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	void do_parse()
18492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
18592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		read_token(&program.version);
18692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
18792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		unsigned lentok = read32();
18892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		tokens_end = tokens - 2 + lentok;
18992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
19092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		while(tokens != tokens_end)
19192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
192e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			sm4_token_instruction insntok;
19392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			read_token(&insntok);
19492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			unsigned* insn_end = tokens - 1 + insntok.length;
195e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			sm4_opcode opcode = (sm4_opcode)insntok.opcode;
196e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			check(opcode < SM4_OPCODE_COUNT);
19792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
198e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			if(opcode == SM4_OPCODE_CUSTOMDATA)
19992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
200c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				// immediate constant buffer data
20192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				unsigned customlen = read32() - 2;
202c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller
203c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				sm4_dcl& dcl = *new sm4_dcl;
204c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				program.dcls.push_back(&dcl);
205c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller
206c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				dcl.opcode = SM4_OPCODE_CUSTOMDATA;
207c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				dcl.num = customlen;
208c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				dcl.data = malloc(customlen * sizeof(tokens[0]));
209c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller
210c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller				memcpy(dcl.data, &tokens[0], customlen * sizeof(tokens[0]));
211c8ae342bf3efc2c43083ab11f0d52022cffe8ba4Christoph Bumiller
21292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				skip(customlen);
21392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				continue;
21492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
21592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
216903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller			if(opcode == SM4_OPCODE_HS_FORK_PHASE || opcode == SM4_OPCODE_HS_JOIN_PHASE)
217903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller			{
218903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller				// need to interleave these with the declarations or we cannot
219903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller				// assign fork/join phase instance counts to phases
220903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller				sm4_dcl& dcl = *new sm4_dcl;
221903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller				program.dcls.push_back(&dcl);
222903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller				dcl.opcode = opcode;
223903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller			}
224903e3257d071caeeec84a096069a78b55666f72dChristoph Bumiller
225e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri			if((opcode >= SM4_OPCODE_DCL_RESOURCE && opcode <= SM4_OPCODE_DCL_GLOBAL_FLAGS)
226e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				|| (opcode >= SM4_OPCODE_DCL_STREAM && opcode <= SM4_OPCODE_DCL_RESOURCE_STRUCTURED))
22792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
228e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				sm4_dcl& dcl = *new sm4_dcl;
22992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				program.dcls.push_back(&dcl);
230e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				(sm4_token_instruction&)dcl = insntok;
23192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
232e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				sm4_token_instruction_extended exttok;
23392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				memcpy(&exttok, &insntok, sizeof(exttok));
23492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				while(exttok.extended)
23592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
23692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					read_token(&exttok);
23792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
23892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
239e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri#define READ_OP_ANY dcl.op.reset(new sm4_op()); read_op(&*dcl.op);
24092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri#define READ_OP(FILE) READ_OP_ANY
241e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				//check(dcl.op->file == SM4_FILE_##FILE);
24292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
24392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				switch(opcode)
24492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
245e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_GLOBAL_FLAGS:
24692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
247e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_RESOURCE:
24892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(RESOURCE);
24992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					read_token(&dcl.rrt);
25092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
251e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_SAMPLER:
25292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(SAMPLER);
25392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
254e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT:
255e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_PS:
25692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(INPUT);
25792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
258e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_SIV:
259e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_SGV:
260e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_PS_SIV:
261e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_PS_SGV:
26292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(INPUT);
263e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					dcl.sv = (sm4_sv)(uint16_t)read32();
26492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
265e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_OUTPUT:
26692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(OUTPUT);
26792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
268e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_OUTPUT_SIV:
269e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_OUTPUT_SGV:
27092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(OUTPUT);
271e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					dcl.sv = (sm4_sv)(uint16_t)read32();
27292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
273e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INDEX_RANGE:
27492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP_ANY;
275e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					check(dcl.op->file == SM4_FILE_INPUT || dcl.op->file == SM4_FILE_OUTPUT);
27692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
27792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
278e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_TEMPS:
27992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
28092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
281e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INDEXABLE_TEMP:
28292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(INDEXABLE_TEMP);
28392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.indexable_temp.num = read32();
28492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.indexable_temp.comps = read32();
28592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
286e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_CONSTANT_BUFFER:
28792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(CONSTANT_BUFFER);
28892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
289e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_GS_INPUT_PRIMITIVE:
290e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
29192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
292e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
29392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
29492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
295e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_GS_INSTANCE_COUNT:
29692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
29792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
298e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT:
299e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT:
300e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_TESS_DOMAIN:
301e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_TESS_PARTITIONING:
302e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE:
30392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
304e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_HS_MAX_TESSFACTOR:
30592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.f32 = read32();
30692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
307e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
30892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
30992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
310e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_FUNCTION_BODY:
31192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
31292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
313e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_FUNCTION_TABLE:
31492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
31592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.data = malloc(dcl.num * sizeof(uint32_t));
31692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					for(unsigned i = 0; i < dcl.num; ++i)
31792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						((uint32_t*)dcl.data)[i] = read32();
31892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
319e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_INTERFACE:
32092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.intf.id = read32();
32192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.intf.expected_function_table_length = read32();
32292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					{
32392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						uint32_t v = read32();
32492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						dcl.intf.table_length = v & 0xffff;
32592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						dcl.intf.array_length = v >> 16;
32692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					}
32792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.data = malloc(dcl.intf.table_length * sizeof(uint32_t));
32892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					for(unsigned i = 0; i < dcl.intf.table_length; ++i)
32992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						((uint32_t*)dcl.data)[i] = read32();
33092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
331e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_THREAD_GROUP:
33292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.thread_group_size[0] = read32();
33392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.thread_group_size[1] = read32();
33492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.thread_group_size[2] = read32();
33592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
336e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED:
33792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(UNORDERED_ACCESS_VIEW);
33892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					read_token(&dcl.rrt);
33992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
340e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW:
34192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(UNORDERED_ACCESS_VIEW);
34292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
343e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED:
34492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(UNORDERED_ACCESS_VIEW);
34592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.structured.stride = read32();
34692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
347e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW:
34892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(THREAD_GROUP_SHARED_MEMORY);
34992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.num = read32();
35092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
351e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED:
35292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(THREAD_GROUP_SHARED_MEMORY);
35392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.structured.stride = read32();
35492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.structured.count = read32();
35592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
356e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_RESOURCE_RAW:
35792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(RESOURCE);
35892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
359e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_RESOURCE_STRUCTURED:
36092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					READ_OP(RESOURCE);
36192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					dcl.structured.stride = read32();
36292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
363e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_DCL_STREAM:
36492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					/* TODO: dcl_stream is undocumented: what is it? */
36592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					fail("Unhandled dcl_stream since it's undocumented");
36692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				default:
36792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					fail("Unhandled declaration");
36892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
36992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
37092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				check(tokens == insn_end);
37192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
37292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			else
37392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			{
374e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				sm4_insn& insn = *new sm4_insn;
37592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				program.insns.push_back(&insn);
376e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				(sm4_token_instruction&)insn = insntok;
37792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
378e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				sm4_token_instruction_extended exttok;
37992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				memcpy(&exttok, &insntok, sizeof(exttok));
38092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				while(exttok.extended)
38192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
38292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					read_token(&exttok);
383e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_SAMPLE_CONTROLS)
38492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					{
38592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.sample_offset[0] = exttok.sample_controls.offset_u;
38692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.sample_offset[1] = exttok.sample_controls.offset_v;
38792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.sample_offset[2] = exttok.sample_controls.offset_w;
38892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					}
389e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					else if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_DIM)
39092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.resource_target = exttok.resource_target.target;
391e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					else if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_RETURN_TYPE)
39292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					{
39392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.resource_return_type[0] = exttok.resource_return_type.x;
39492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.resource_return_type[1] = exttok.resource_return_type.y;
39592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.resource_return_type[2] = exttok.resource_return_type.z;
39692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri						insn.resource_return_type[3] = exttok.resource_return_type.w;
39792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					}
39892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
39992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
40092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				switch(opcode)
40192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
402e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri				case SM4_OPCODE_INTERFACE_CALL:
40392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					insn.num = read32();
40492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
40592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				default:
40692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					break;
40792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
40892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
40992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				unsigned op_num = 0;
41092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				while(tokens != insn_end)
41192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				{
41292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					check(tokens < insn_end);
413e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					check(op_num < SM4_MAX_OPS);
414e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri					insn.ops[op_num].reset(new sm4_op);
41592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					read_op(&*insn.ops[op_num]);
41692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri					++op_num;
41792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				}
41892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri				insn.num_ops = op_num;
41992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			}
42092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
42192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
42292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
42392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	const char* parse()
42492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	{
42592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		try
42692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
42792617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			do_parse();
42892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return 0;
42992617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
43092617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		catch(const char* error)
43192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		{
43292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri			return error;
43392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		}
43492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	}
43592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri};
43692617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri
437e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbierism4_program* sm4_parse(void* tokens, int size)
43892617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri{
439e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri	sm4_program* program = new sm4_program;
440e5ae4588d150a179974a812887f3b6445d8e2f34Luca Barbieri	sm4_parser parser(*program, tokens, size);
44192617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	if(!parser.parse())
44292617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri		return program;
44392617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	delete program;
44492617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri	return 0;
44592617aeac109481258f0c3863d09c1b8903d438bLuca Barbieri}
446