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