Path: blob/21.2-virgl/src/gallium/auxiliary/tgsi/tgsi_parse.c
4565 views
/**************************************************************************1*2* Copyright 2007 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include "util/u_debug.h"28#include "pipe/p_shader_tokens.h"29#include "tgsi_parse.h"30#include "util/u_memory.h"3132unsigned33tgsi_parse_init(34struct tgsi_parse_context *ctx,35const struct tgsi_token *tokens )36{37ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[0];38if (ctx->FullHeader.Header.HeaderSize >= 2) {39ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[1];40}41else {42return TGSI_PARSE_ERROR;43}4445ctx->Tokens = tokens;46ctx->Position = ctx->FullHeader.Header.HeaderSize;4748return TGSI_PARSE_OK;49}5051void52tgsi_parse_free(53UNUSED struct tgsi_parse_context *ctx )54{55}5657boolean58tgsi_parse_end_of_tokens(59struct tgsi_parse_context *ctx )60{61/* All values involved are unsigned, but the sum will be promoted to62* a signed value (at least on 64 bit). To capture a possible overflow63* make it a signed comparison.64*/65return (int)ctx->Position >=66ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;67}686970/**71* This function is used to avoid and work-around type punning/aliasing72* warnings. The warnings seem harmless on x86 but on PPC they cause73* real failures.74*/75static inline void76copy_token(void *dst, const void *src)77{78memcpy(dst, src, 4);79}808182/**83* Get next 4-byte token, return it at address specified by 'token'84*/85static void86next_token(87struct tgsi_parse_context *ctx,88void *token )89{90assert( !tgsi_parse_end_of_tokens( ctx ) );91copy_token(token, &ctx->Tokens[ctx->Position]);92ctx->Position++;93}949596void97tgsi_parse_token(98struct tgsi_parse_context *ctx )99{100struct tgsi_token token;101unsigned i;102103next_token( ctx, &token );104105switch( token.Type ) {106case TGSI_TOKEN_TYPE_DECLARATION:107{108struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration;109110memset(decl, 0, sizeof *decl);111copy_token(&decl->Declaration, &token);112113next_token( ctx, &decl->Range );114115if (decl->Declaration.Dimension) {116next_token(ctx, &decl->Dim);117}118119if (decl->Declaration.Interpolate) {120next_token( ctx, &decl->Interp );121}122123if (decl->Declaration.Semantic) {124next_token( ctx, &decl->Semantic );125}126127if (decl->Declaration.File == TGSI_FILE_IMAGE) {128next_token(ctx, &decl->Image);129}130131if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {132next_token(ctx, &decl->SamplerView);133}134135if (decl->Declaration.Array) {136next_token(ctx, &decl->Array);137}138139break;140}141142case TGSI_TOKEN_TYPE_IMMEDIATE:143{144struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;145uint imm_count;146147memset(imm, 0, sizeof *imm);148copy_token(&imm->Immediate, &token);149150imm_count = imm->Immediate.NrTokens - 1;151152switch (imm->Immediate.DataType) {153case TGSI_IMM_FLOAT32:154case TGSI_IMM_FLOAT64:155for (i = 0; i < imm_count; i++) {156next_token(ctx, &imm->u[i].Float);157}158break;159160case TGSI_IMM_UINT32:161case TGSI_IMM_UINT64:162for (i = 0; i < imm_count; i++) {163next_token(ctx, &imm->u[i].Uint);164}165break;166167case TGSI_IMM_INT32:168case TGSI_IMM_INT64:169for (i = 0; i < imm_count; i++) {170next_token(ctx, &imm->u[i].Int);171}172break;173174default:175assert( 0 );176}177178break;179}180181case TGSI_TOKEN_TYPE_INSTRUCTION:182{183struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;184185memset(inst, 0, sizeof *inst);186copy_token(&inst->Instruction, &token);187188if (inst->Instruction.Label) {189next_token( ctx, &inst->Label);190}191192if (inst->Instruction.Texture) {193next_token( ctx, &inst->Texture);194for (i = 0; i < inst->Texture.NumOffsets; i++) {195next_token( ctx, &inst->TexOffsets[i] );196}197}198199if (inst->Instruction.Memory) {200next_token(ctx, &inst->Memory);201}202203assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );204205for (i = 0; i < inst->Instruction.NumDstRegs; i++) {206207next_token( ctx, &inst->Dst[i].Register );208209if (inst->Dst[i].Register.Indirect)210next_token( ctx, &inst->Dst[i].Indirect );211212if (inst->Dst[i].Register.Dimension) {213next_token( ctx, &inst->Dst[i].Dimension );214215/*216* No support for multi-dimensional addressing.217*/218assert( !inst->Dst[i].Dimension.Dimension );219220if (inst->Dst[i].Dimension.Indirect)221next_token( ctx, &inst->Dst[i].DimIndirect );222}223}224225assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );226227for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {228229next_token( ctx, &inst->Src[i].Register );230231if (inst->Src[i].Register.Indirect)232next_token( ctx, &inst->Src[i].Indirect );233234if (inst->Src[i].Register.Dimension) {235next_token( ctx, &inst->Src[i].Dimension );236237/*238* No support for multi-dimensional addressing.239*/240assert( !inst->Src[i].Dimension.Dimension );241242if (inst->Src[i].Dimension.Indirect)243next_token( ctx, &inst->Src[i].DimIndirect );244}245}246247break;248}249250case TGSI_TOKEN_TYPE_PROPERTY:251{252struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;253uint prop_count;254255memset(prop, 0, sizeof *prop);256copy_token(&prop->Property, &token);257258prop_count = prop->Property.NrTokens - 1;259for (i = 0; i < prop_count; i++) {260next_token(ctx, &prop->u[i]);261}262263break;264}265266default:267assert( 0 );268}269}270271272273274/**275* Make a new copy of a token array.276*/277struct tgsi_token *278tgsi_dup_tokens(const struct tgsi_token *tokens)279{280unsigned n = tgsi_num_tokens(tokens);281unsigned bytes = n * sizeof(struct tgsi_token);282struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);283if (new_tokens)284memcpy(new_tokens, tokens, bytes);285return new_tokens;286}287288289/**290* Allocate memory for num_tokens tokens.291*/292struct tgsi_token *293tgsi_alloc_tokens(unsigned num_tokens)294{295unsigned bytes = num_tokens * sizeof(struct tgsi_token);296return (struct tgsi_token *) MALLOC(bytes);297}298299300/**301* Free tokens allocated by tgsi_alloc_tokens() or tgsi_dup_tokens()302*/303void304tgsi_free_tokens(const struct tgsi_token *tokens)305{306FREE((void *) tokens);307}308309310void311tgsi_dump_tokens(const struct tgsi_token *tokens)312{313const unsigned *dwords = (const unsigned *)tokens;314int nr = tgsi_num_tokens(tokens);315int i;316317STATIC_ASSERT(sizeof(*tokens) == sizeof(unsigned));318319debug_printf("const unsigned tokens[%d] = {\n", nr);320for (i = 0; i < nr; i++)321debug_printf("0x%08x,\n", dwords[i]);322debug_printf("};\n");323}324325unsigned326tgsi_get_processor_type(const struct tgsi_token *tokens)327{328struct tgsi_parse_context parse;329330if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {331debug_printf("tgsi_parse_init() failed in %s:%i!\n", __func__, __LINE__);332return ~0;333}334return parse.FullHeader.Processor.Processor;335}336337338