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#include "sm4.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "utils.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 1 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define check(x) assert(x) 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define fail(x) assert(0 && (x)) 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define check(x) do {if(!(x)) throw(#x);} while(0) 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define fail(x) throw(x) 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct sm4_parser 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* tokens; 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* tokens_end; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_program& program; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_parser(sm4_program& program, void* p_tokens, unsigned size) 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : program(program) 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens = (unsigned*)p_tokens; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens_end = (unsigned*)((char*)p_tokens + size); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: byteswap if machine is big endian */ 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t read32() 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(tokens < tokens_end); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bswap_le32(*tokens++); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template<typename T> 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void read_token(T* tok) 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(unsigned*)tok = read32(); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint64_t read64() 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned a = read32(); 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned b = read32(); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (uint64_t)a | ((uint64_t)b << 32); 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void skip(unsigned toskip) 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens += toskip; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void read_op(sm4_op* pop) 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_op& op = *pop; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_token_operand optok; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&optok); 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(optok.file < SM4_FILE_COUNT); 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[0] = 0; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[1] = 1; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[2] = 2; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[3] = 3; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.mask = 0xf; 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(optok.comps_enum) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_COMPNUM_0: 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.comps = 0; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_COMPNUM_1: 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.comps = 1; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[1] = op.swizzle[2] = op.swizzle[3] = 0; 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_COMPNUM_4: 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.comps = 4; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.mode = optok.mode; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(optok.mode) 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_MODE_MASK: 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.mask = SM4_OPERAND_SEL_MASK(optok.sel); 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_MODE_SWIZZLE: 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[0] = SM4_OPERAND_SEL_SWZ(optok.sel, 0); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[1] = SM4_OPERAND_SEL_SWZ(optok.sel, 1); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[2] = SM4_OPERAND_SEL_SWZ(optok.sel, 2); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[3] = SM4_OPERAND_SEL_SWZ(optok.sel, 3); 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_MODE_SCALAR: 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.swizzle[0] = op.swizzle[1] = op.swizzle[2] = op.swizzle[3] = SM4_OPERAND_SEL_SCALAR(optok.sel); 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_COMPNUM_N: 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail("Unhandled operand component type"); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.file = (sm4_file)optok.file; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.num_indices = optok.num_indices; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(optok.extended) 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_token_operand_extended optokext; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&optokext); 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(optokext.type == 0) 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {} 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(optokext.type == 1) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.neg = optokext.neg; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.abs= optokext.abs; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail("Unhandled extended operand token type"); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < op.num_indices; ++i) 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned repr; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(i == 0) 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org repr = optok.index0_repr; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(i == 1) 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org repr = optok.index1_repr; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(i == 2) 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org repr = optok.index2_repr; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail("Unhandled operand index representation"); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].disp = 0; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: is disp supposed to be signed here?? 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(repr) 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_INDEX_REPR_IMM32: 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].disp = (int32_t)read32(); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_INDEX_REPR_IMM64: 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].disp = read64(); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_INDEX_REPR_REG: 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrelative: 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].reg.reset(new sm4_op()); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_op(&*op.indices[i].reg); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_INDEX_REPR_REG_IMM32: 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].disp = (int32_t)read32(); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto relative; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPERAND_INDEX_REPR_REG_IMM64: 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.indices[i].disp = read64(); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto relative; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(op.file == SM4_FILE_IMMEDIATE32) 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < op.comps; ++i) 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.imm_values[i].i32 = read32(); 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(op.file == SM4_FILE_IMMEDIATE64) 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < op.comps; ++i) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op.imm_values[i].i64 = read64(); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void do_parse() 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&program.version); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned lentok = read32(); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens_end = tokens - 2 + lentok; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(tokens != tokens_end) 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_token_instruction insntok; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&insntok); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned* insn_end = tokens - 1 + insntok.length; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_opcode opcode = (sm4_opcode)insntok.opcode; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(opcode < SM4_OPCODE_COUNT); 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(opcode == SM4_OPCODE_CUSTOMDATA) 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // immediate constant buffer data 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned customlen = read32() - 2; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_dcl& dcl = *new sm4_dcl; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program.dcls.push_back(&dcl); 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.opcode = SM4_OPCODE_CUSTOMDATA; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = customlen; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.data = malloc(customlen * sizeof(tokens[0])); 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(dcl.data, &tokens[0], customlen * sizeof(tokens[0])); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org skip(customlen); 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(opcode == SM4_OPCODE_HS_FORK_PHASE || opcode == SM4_OPCODE_HS_JOIN_PHASE) 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // need to interleave these with the declarations or we cannot 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // assign fork/join phase instance counts to phases 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_dcl& dcl = *new sm4_dcl; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program.dcls.push_back(&dcl); 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.opcode = opcode; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if((opcode >= SM4_OPCODE_DCL_RESOURCE && opcode <= SM4_OPCODE_DCL_GLOBAL_FLAGS) 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (opcode >= SM4_OPCODE_DCL_STREAM && opcode <= SM4_OPCODE_DCL_RESOURCE_STRUCTURED)) 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_dcl& dcl = *new sm4_dcl; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program.dcls.push_back(&dcl); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (sm4_token_instruction&)dcl = insntok; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_token_instruction_extended exttok; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&exttok, &insntok, sizeof(exttok)); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(exttok.extended) 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&exttok); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define READ_OP_ANY dcl.op.reset(new sm4_op()); read_op(&*dcl.op); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define READ_OP(FILE) READ_OP_ANY 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //check(dcl.op->file == SM4_FILE_##FILE); 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(opcode) 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_GLOBAL_FLAGS: 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_RESOURCE: 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(RESOURCE); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&dcl.rrt); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_SAMPLER: 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(SAMPLER); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT: 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_PS: 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(INPUT); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_SIV: 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_SGV: 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_PS_SIV: 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_PS_SGV: 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(INPUT); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.sv = (sm4_sv)(uint16_t)read32(); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_OUTPUT: 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(OUTPUT); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_OUTPUT_SIV: 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_OUTPUT_SGV: 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(OUTPUT); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.sv = (sm4_sv)(uint16_t)read32(); 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INDEX_RANGE: 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP_ANY; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(dcl.op->file == SM4_FILE_INPUT || dcl.op->file == SM4_FILE_OUTPUT); 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_TEMPS: 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INDEXABLE_TEMP: 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(INDEXABLE_TEMP); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.indexable_temp.num = read32(); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.indexable_temp.comps = read32(); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_CONSTANT_BUFFER: 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(CONSTANT_BUFFER); 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_GS_INPUT_PRIMITIVE: 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_GS_INSTANCE_COUNT: 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_TESS_DOMAIN: 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_TESS_PARTITIONING: 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_HS_MAX_TESSFACTOR: 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.f32 = read32(); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_FUNCTION_BODY: 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_FUNCTION_TABLE: 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.data = malloc(dcl.num * sizeof(uint32_t)); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < dcl.num; ++i) 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((uint32_t*)dcl.data)[i] = read32(); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_INTERFACE: 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.intf.id = read32(); 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.intf.expected_function_table_length = read32(); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t v = read32(); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.intf.table_length = v & 0xffff; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.intf.array_length = v >> 16; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.data = malloc(dcl.intf.table_length * sizeof(uint32_t)); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned i = 0; i < dcl.intf.table_length; ++i) 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((uint32_t*)dcl.data)[i] = read32(); 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_THREAD_GROUP: 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.thread_group_size[0] = read32(); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.thread_group_size[1] = read32(); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.thread_group_size[2] = read32(); 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(UNORDERED_ACCESS_VIEW); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&dcl.rrt); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(UNORDERED_ACCESS_VIEW); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(UNORDERED_ACCESS_VIEW); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.structured.stride = read32(); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW: 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(THREAD_GROUP_SHARED_MEMORY); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.num = read32(); 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(THREAD_GROUP_SHARED_MEMORY); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.structured.stride = read32(); 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.structured.count = read32(); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_RESOURCE_RAW: 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(RESOURCE); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_RESOURCE_STRUCTURED: 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org READ_OP(RESOURCE); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dcl.structured.stride = read32(); 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_DCL_STREAM: 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TODO: dcl_stream is undocumented: what is it? */ 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail("Unhandled dcl_stream since it's undocumented"); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail("Unhandled declaration"); 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(tokens == insn_end); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_insn& insn = *new sm4_insn; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program.insns.push_back(&insn); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (sm4_token_instruction&)insn = insntok; 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_token_instruction_extended exttok; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&exttok, &insntok, sizeof(exttok)); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(exttok.extended) 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_token(&exttok); 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_SAMPLE_CONTROLS) 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.sample_offset[0] = exttok.sample_controls.offset_u; 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.sample_offset[1] = exttok.sample_controls.offset_v; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.sample_offset[2] = exttok.sample_controls.offset_w; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_DIM) 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.resource_target = exttok.resource_target.target; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if(exttok.type == SM4_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_RETURN_TYPE) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.resource_return_type[0] = exttok.resource_return_type.x; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.resource_return_type[1] = exttok.resource_return_type.y; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.resource_return_type[2] = exttok.resource_return_type.z; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.resource_return_type[3] = exttok.resource_return_type.w; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(opcode) 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case SM4_OPCODE_INTERFACE_CALL: 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.num = read32(); 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned op_num = 0; 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while(tokens != insn_end) 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(tokens < insn_end); 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check(op_num < SM4_MAX_OPS); 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.ops[op_num].reset(new sm4_op); 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_op(&*insn.ops[op_num]); 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++op_num; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insn.num_ops = op_num; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char* parse() 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_parse(); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org catch(const char* error) 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return error; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsm4_program* sm4_parse(void* tokens, int size) 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_program* program = new sm4_program; 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sm4_parser parser(*program, tokens, size); 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!parser.parse()) 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return program; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete program; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 446