tgsi_sanity.c revision cf8907018e449580b397f09c267219a612ba5db4
12727702b1731a478de8806481416080d02af5862Michal Krol/************************************************************************** 22727702b1731a478de8806481416080d02af5862Michal Krol * 32727702b1731a478de8806481416080d02af5862Michal Krol * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 42727702b1731a478de8806481416080d02af5862Michal Krol * All Rights Reserved. 52727702b1731a478de8806481416080d02af5862Michal Krol * 62727702b1731a478de8806481416080d02af5862Michal Krol * Permission is hereby granted, free of charge, to any person obtaining a 72727702b1731a478de8806481416080d02af5862Michal Krol * copy of this software and associated documentation files (the 82727702b1731a478de8806481416080d02af5862Michal Krol * "Software"), to deal in the Software without restriction, including 92727702b1731a478de8806481416080d02af5862Michal Krol * without limitation the rights to use, copy, modify, merge, publish, 102727702b1731a478de8806481416080d02af5862Michal Krol * distribute, sub license, and/or sell copies of the Software, and to 112727702b1731a478de8806481416080d02af5862Michal Krol * permit persons to whom the Software is furnished to do so, subject to 122727702b1731a478de8806481416080d02af5862Michal Krol * the following conditions: 132727702b1731a478de8806481416080d02af5862Michal Krol * 142727702b1731a478de8806481416080d02af5862Michal Krol * The above copyright notice and this permission notice (including the 152727702b1731a478de8806481416080d02af5862Michal Krol * next paragraph) shall be included in all copies or substantial portions 162727702b1731a478de8806481416080d02af5862Michal Krol * of the Software. 172727702b1731a478de8806481416080d02af5862Michal Krol * 182727702b1731a478de8806481416080d02af5862Michal Krol * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 192727702b1731a478de8806481416080d02af5862Michal Krol * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 202727702b1731a478de8806481416080d02af5862Michal Krol * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 212727702b1731a478de8806481416080d02af5862Michal Krol * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 222727702b1731a478de8806481416080d02af5862Michal Krol * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 232727702b1731a478de8806481416080d02af5862Michal Krol * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 242727702b1731a478de8806481416080d02af5862Michal Krol * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 252727702b1731a478de8806481416080d02af5862Michal Krol * 262727702b1731a478de8806481416080d02af5862Michal Krol **************************************************************************/ 272727702b1731a478de8806481416080d02af5862Michal Krol 28ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h" 292727702b1731a478de8806481416080d02af5862Michal Krol#include "tgsi_sanity.h" 304b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol#include "tgsi_info.h" 311e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol#include "tgsi_iterate.h" 322727702b1731a478de8806481416080d02af5862Michal Krol 332727702b1731a478de8806481416080d02af5862Michal Kroltypedef uint reg_flag; 342727702b1731a478de8806481416080d02af5862Michal Krol 352727702b1731a478de8806481416080d02af5862Michal Krol#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8) 362727702b1731a478de8806481416080d02af5862Michal Krol 37ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol#define MAX_REGISTERS 256 38ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol#define MAX_REG_FLAGS ((MAX_REGISTERS + BITS_IN_REG_FLAG - 1) / BITS_IN_REG_FLAG) 39ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol 402727702b1731a478de8806481416080d02af5862Michal Krolstruct sanity_check_ctx 412727702b1731a478de8806481416080d02af5862Michal Krol{ 421e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct tgsi_iterate_context iter; 432727702b1731a478de8806481416080d02af5862Michal Krol 44ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REG_FLAGS]; 45ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol reg_flag regs_used[TGSI_FILE_COUNT][MAX_REG_FLAGS]; 4673e1d0be756537376495547bc1e798805884b8efMichal Krol boolean regs_ind_used[TGSI_FILE_COUNT]; 472727702b1731a478de8806481416080d02af5862Michal Krol uint num_imms; 482727702b1731a478de8806481416080d02af5862Michal Krol uint num_instructions; 492727702b1731a478de8806481416080d02af5862Michal Krol uint index_of_END; 502727702b1731a478de8806481416080d02af5862Michal Krol 512727702b1731a478de8806481416080d02af5862Michal Krol uint errors; 522727702b1731a478de8806481416080d02af5862Michal Krol uint warnings; 532727702b1731a478de8806481416080d02af5862Michal Krol}; 542727702b1731a478de8806481416080d02af5862Michal Krol 552727702b1731a478de8806481416080d02af5862Michal Krolstatic void 562727702b1731a478de8806481416080d02af5862Michal Krolreport_error( 572727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx *ctx, 5851d219dbfe6852d348755574184639940af444e3Michal Krol const char *format, 5951d219dbfe6852d348755574184639940af444e3Michal Krol ... ) 602727702b1731a478de8806481416080d02af5862Michal Krol{ 6151d219dbfe6852d348755574184639940af444e3Michal Krol va_list args; 6251d219dbfe6852d348755574184639940af444e3Michal Krol 6351d219dbfe6852d348755574184639940af444e3Michal Krol debug_printf( "Error : " ); 6451d219dbfe6852d348755574184639940af444e3Michal Krol va_start( args, format ); 6551d219dbfe6852d348755574184639940af444e3Michal Krol _debug_vprintf( format, args ); 6651d219dbfe6852d348755574184639940af444e3Michal Krol va_end( args ); 6751d219dbfe6852d348755574184639940af444e3Michal Krol debug_printf( "\n" ); 682727702b1731a478de8806481416080d02af5862Michal Krol ctx->errors++; 692727702b1731a478de8806481416080d02af5862Michal Krol} 702727702b1731a478de8806481416080d02af5862Michal Krol 712727702b1731a478de8806481416080d02af5862Michal Krolstatic void 722727702b1731a478de8806481416080d02af5862Michal Krolreport_warning( 732727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx *ctx, 7451d219dbfe6852d348755574184639940af444e3Michal Krol const char *format, 7551d219dbfe6852d348755574184639940af444e3Michal Krol ... ) 762727702b1731a478de8806481416080d02af5862Michal Krol{ 7751d219dbfe6852d348755574184639940af444e3Michal Krol va_list args; 7851d219dbfe6852d348755574184639940af444e3Michal Krol 7951d219dbfe6852d348755574184639940af444e3Michal Krol debug_printf( "Warning: " ); 8051d219dbfe6852d348755574184639940af444e3Michal Krol va_start( args, format ); 8151d219dbfe6852d348755574184639940af444e3Michal Krol _debug_vprintf( format, args ); 8251d219dbfe6852d348755574184639940af444e3Michal Krol va_end( args ); 8351d219dbfe6852d348755574184639940af444e3Michal Krol debug_printf( "\n" ); 842727702b1731a478de8806481416080d02af5862Michal Krol ctx->warnings++; 852727702b1731a478de8806481416080d02af5862Michal Krol} 862727702b1731a478de8806481416080d02af5862Michal Krol 872727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean 882727702b1731a478de8806481416080d02af5862Michal Krolcheck_file_name( 892727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx *ctx, 902727702b1731a478de8806481416080d02af5862Michal Krol uint file ) 912727702b1731a478de8806481416080d02af5862Michal Krol{ 922727702b1731a478de8806481416080d02af5862Michal Krol if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) { 93ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "(%u): Invalid register file name", file ); 942727702b1731a478de8806481416080d02af5862Michal Krol return FALSE; 952727702b1731a478de8806481416080d02af5862Michal Krol } 962727702b1731a478de8806481416080d02af5862Michal Krol return TRUE; 972727702b1731a478de8806481416080d02af5862Michal Krol} 982727702b1731a478de8806481416080d02af5862Michal Krol 992727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean 1002727702b1731a478de8806481416080d02af5862Michal Krolis_register_declared( 1012727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx *ctx, 1022727702b1731a478de8806481416080d02af5862Michal Krol uint file, 10373e1d0be756537376495547bc1e798805884b8efMichal Krol int index ) 1042727702b1731a478de8806481416080d02af5862Michal Krol{ 10573e1d0be756537376495547bc1e798805884b8efMichal Krol assert( index >= 0 && index < MAX_REGISTERS ); 1062727702b1731a478de8806481416080d02af5862Michal Krol 1072727702b1731a478de8806481416080d02af5862Michal Krol return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; 1082727702b1731a478de8806481416080d02af5862Michal Krol} 1092727702b1731a478de8806481416080d02af5862Michal Krol 1102727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean 11173e1d0be756537376495547bc1e798805884b8efMichal Krolis_any_register_declared( 11273e1d0be756537376495547bc1e798805884b8efMichal Krol struct sanity_check_ctx *ctx, 11373e1d0be756537376495547bc1e798805884b8efMichal Krol uint file ) 11473e1d0be756537376495547bc1e798805884b8efMichal Krol{ 11573e1d0be756537376495547bc1e798805884b8efMichal Krol uint i; 11673e1d0be756537376495547bc1e798805884b8efMichal Krol 117ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol for (i = 0; i < MAX_REG_FLAGS; i++) 11873e1d0be756537376495547bc1e798805884b8efMichal Krol if (ctx->regs_decl[file][i]) 11973e1d0be756537376495547bc1e798805884b8efMichal Krol return TRUE; 12073e1d0be756537376495547bc1e798805884b8efMichal Krol return FALSE; 12173e1d0be756537376495547bc1e798805884b8efMichal Krol} 12273e1d0be756537376495547bc1e798805884b8efMichal Krol 12373e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean 1242727702b1731a478de8806481416080d02af5862Michal Krolis_register_used( 1252727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx *ctx, 1262727702b1731a478de8806481416080d02af5862Michal Krol uint file, 12773e1d0be756537376495547bc1e798805884b8efMichal Krol int index ) 1282727702b1731a478de8806481416080d02af5862Michal Krol{ 1292727702b1731a478de8806481416080d02af5862Michal Krol assert( index < MAX_REGISTERS ); 1302727702b1731a478de8806481416080d02af5862Michal Krol 1312727702b1731a478de8806481416080d02af5862Michal Krol return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; 1322727702b1731a478de8806481416080d02af5862Michal Krol} 1332727702b1731a478de8806481416080d02af5862Michal Krol 134cf8907018e449580b397f09c267219a612ba5db4Michal Krolstatic const char *file_names[TGSI_FILE_COUNT] = 13551d219dbfe6852d348755574184639940af444e3Michal Krol{ 13651d219dbfe6852d348755574184639940af444e3Michal Krol "NULL", 13751d219dbfe6852d348755574184639940af444e3Michal Krol "CONST", 13851d219dbfe6852d348755574184639940af444e3Michal Krol "IN", 13951d219dbfe6852d348755574184639940af444e3Michal Krol "OUT", 14051d219dbfe6852d348755574184639940af444e3Michal Krol "TEMP", 14151d219dbfe6852d348755574184639940af444e3Michal Krol "SAMP", 14251d219dbfe6852d348755574184639940af444e3Michal Krol "ADDR", 143cf8907018e449580b397f09c267219a612ba5db4Michal Krol "IMM", 144cf8907018e449580b397f09c267219a612ba5db4Michal Krol "LOOP" 14551d219dbfe6852d348755574184639940af444e3Michal Krol}; 14651d219dbfe6852d348755574184639940af444e3Michal Krol 1471e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean 14873e1d0be756537376495547bc1e798805884b8efMichal Krolcheck_register_usage( 14973e1d0be756537376495547bc1e798805884b8efMichal Krol struct sanity_check_ctx *ctx, 15073e1d0be756537376495547bc1e798805884b8efMichal Krol uint file, 15173e1d0be756537376495547bc1e798805884b8efMichal Krol int index, 15251d219dbfe6852d348755574184639940af444e3Michal Krol const char *name, 15351d219dbfe6852d348755574184639940af444e3Michal Krol boolean indirect_access ) 15473e1d0be756537376495547bc1e798805884b8efMichal Krol{ 15573e1d0be756537376495547bc1e798805884b8efMichal Krol if (!check_file_name( ctx, file )) 15673e1d0be756537376495547bc1e798805884b8efMichal Krol return FALSE; 157ad16ecbbe4fe8c1bcb18ed8fbbd672c68a0b17faJakob Bornecrantz 15851d219dbfe6852d348755574184639940af444e3Michal Krol if (indirect_access) { 159639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian /* Note that 'index' is an offset relative to the value of the 160639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian * address register. No range checking done here. 161639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian */ 16273e1d0be756537376495547bc1e798805884b8efMichal Krol if (!is_any_register_declared( ctx, file )) 16351d219dbfe6852d348755574184639940af444e3Michal Krol report_error( ctx, "%s: Undeclared %s register", file_names[file], name ); 16473e1d0be756537376495547bc1e798805884b8efMichal Krol ctx->regs_ind_used[file] = TRUE; 16573e1d0be756537376495547bc1e798805884b8efMichal Krol } 16673e1d0be756537376495547bc1e798805884b8efMichal Krol else { 167ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol if (index < 0 || index >= MAX_REGISTERS) { 168ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "%s[%d]: Invalid %s index", file_names[file], index, name ); 169639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian return FALSE; 170639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian } 171639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian 17273e1d0be756537376495547bc1e798805884b8efMichal Krol if (!is_register_declared( ctx, file, index )) 17351d219dbfe6852d348755574184639940af444e3Michal Krol report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name ); 17473e1d0be756537376495547bc1e798805884b8efMichal Krol ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); 17573e1d0be756537376495547bc1e798805884b8efMichal Krol } 17673e1d0be756537376495547bc1e798805884b8efMichal Krol return TRUE; 17773e1d0be756537376495547bc1e798805884b8efMichal Krol} 17873e1d0be756537376495547bc1e798805884b8efMichal Krol 17973e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean 1801e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_instruction( 1811e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct tgsi_iterate_context *iter, 1822727702b1731a478de8806481416080d02af5862Michal Krol struct tgsi_full_instruction *inst ) 1832727702b1731a478de8806481416080d02af5862Michal Krol{ 1841e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; 1854b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol const struct tgsi_opcode_info *info; 1862727702b1731a478de8806481416080d02af5862Michal Krol uint i; 1872727702b1731a478de8806481416080d02af5862Michal Krol 188e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul if (inst->Instruction.Opcode == TGSI_OPCODE_END) { 189e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul if (ctx->index_of_END != ~0) { 190e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul report_error( ctx, "Too many END instructions" ); 191e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul } 1922727702b1731a478de8806481416080d02af5862Michal Krol ctx->index_of_END = ctx->num_instructions; 1932727702b1731a478de8806481416080d02af5862Michal Krol } 1942727702b1731a478de8806481416080d02af5862Michal Krol 1954b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol info = tgsi_get_opcode_info( inst->Instruction.Opcode ); 1964b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol if (info == NULL) { 197ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode ); 1984b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol return TRUE; 1994b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol } 2004b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol 2014b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol if (info->num_dst != inst->Instruction.NumDstRegs) { 202ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "Invalid number of destination operands, should be %u", info->num_dst ); 2034b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol } 2044b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol if (info->num_src != inst->Instruction.NumSrcRegs) { 205ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "Invalid number of source operands, should be %u", info->num_src ); 2064b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol } 2074b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol 2082727702b1731a478de8806481416080d02af5862Michal Krol /* Check destination and source registers' validity. 2092727702b1731a478de8806481416080d02af5862Michal Krol * Mark the registers as used. 2102727702b1731a478de8806481416080d02af5862Michal Krol */ 2112727702b1731a478de8806481416080d02af5862Michal Krol for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 21273e1d0be756537376495547bc1e798805884b8efMichal Krol check_register_usage( 21373e1d0be756537376495547bc1e798805884b8efMichal Krol ctx, 21473e1d0be756537376495547bc1e798805884b8efMichal Krol inst->FullDstRegisters[i].DstRegister.File, 21573e1d0be756537376495547bc1e798805884b8efMichal Krol inst->FullDstRegisters[i].DstRegister.Index, 21651d219dbfe6852d348755574184639940af444e3Michal Krol "destination", 21773e1d0be756537376495547bc1e798805884b8efMichal Krol FALSE ); 2182727702b1731a478de8806481416080d02af5862Michal Krol } 2192727702b1731a478de8806481416080d02af5862Michal Krol for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 22073e1d0be756537376495547bc1e798805884b8efMichal Krol check_register_usage( 22173e1d0be756537376495547bc1e798805884b8efMichal Krol ctx, 22273e1d0be756537376495547bc1e798805884b8efMichal Krol inst->FullSrcRegisters[i].SrcRegister.File, 22373e1d0be756537376495547bc1e798805884b8efMichal Krol inst->FullSrcRegisters[i].SrcRegister.Index, 22451d219dbfe6852d348755574184639940af444e3Michal Krol "source", 22583869ceab5b3faed8569a5ca752d4dc426db1aecJosé Fonseca (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect ); 22673e1d0be756537376495547bc1e798805884b8efMichal Krol if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { 22725a7f422b4e307dce966220d47794fb056d04aacMichal Krol uint file; 22825a7f422b4e307dce966220d47794fb056d04aacMichal Krol int index; 22925a7f422b4e307dce966220d47794fb056d04aacMichal Krol 23025a7f422b4e307dce966220d47794fb056d04aacMichal Krol file = inst->FullSrcRegisters[i].SrcRegisterInd.File; 23125a7f422b4e307dce966220d47794fb056d04aacMichal Krol index = inst->FullSrcRegisters[i].SrcRegisterInd.Index; 23251d219dbfe6852d348755574184639940af444e3Michal Krol check_register_usage( 23351d219dbfe6852d348755574184639940af444e3Michal Krol ctx, 23451d219dbfe6852d348755574184639940af444e3Michal Krol file, 23551d219dbfe6852d348755574184639940af444e3Michal Krol index, 23651d219dbfe6852d348755574184639940af444e3Michal Krol "indirect", 23751d219dbfe6852d348755574184639940af444e3Michal Krol FALSE ); 23825a7f422b4e307dce966220d47794fb056d04aacMichal Krol if (file != TGSI_FILE_ADDRESS || index != 0) 23925a7f422b4e307dce966220d47794fb056d04aacMichal Krol report_warning( ctx, "Indirect register not ADDR[0]" ); 24073e1d0be756537376495547bc1e798805884b8efMichal Krol } 2412727702b1731a478de8806481416080d02af5862Michal Krol } 2422727702b1731a478de8806481416080d02af5862Michal Krol 2432727702b1731a478de8806481416080d02af5862Michal Krol ctx->num_instructions++; 2441e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol 2451e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 2462727702b1731a478de8806481416080d02af5862Michal Krol} 2472727702b1731a478de8806481416080d02af5862Michal Krol 2481e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean 2491e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_declaration( 2501e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct tgsi_iterate_context *iter, 2512727702b1731a478de8806481416080d02af5862Michal Krol struct tgsi_full_declaration *decl ) 2522727702b1731a478de8806481416080d02af5862Michal Krol{ 2531e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; 2542727702b1731a478de8806481416080d02af5862Michal Krol uint file; 2552727702b1731a478de8806481416080d02af5862Michal Krol uint i; 2562727702b1731a478de8806481416080d02af5862Michal Krol 2572727702b1731a478de8806481416080d02af5862Michal Krol /* No declarations allowed after the first instruction. 2582727702b1731a478de8806481416080d02af5862Michal Krol */ 2592727702b1731a478de8806481416080d02af5862Michal Krol if (ctx->num_instructions > 0) 2602727702b1731a478de8806481416080d02af5862Michal Krol report_error( ctx, "Instruction expected but declaration found" ); 2612727702b1731a478de8806481416080d02af5862Michal Krol 2622727702b1731a478de8806481416080d02af5862Michal Krol /* Check registers' validity. 2632727702b1731a478de8806481416080d02af5862Michal Krol * Mark the registers as declared. 2642727702b1731a478de8806481416080d02af5862Michal Krol */ 2652727702b1731a478de8806481416080d02af5862Michal Krol file = decl->Declaration.File; 2662727702b1731a478de8806481416080d02af5862Michal Krol if (!check_file_name( ctx, file )) 2671e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 2682727702b1731a478de8806481416080d02af5862Michal Krol for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) { 2692727702b1731a478de8806481416080d02af5862Michal Krol if (is_register_declared( ctx, file, i )) 270ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "%s[%u]: The same register declared more than once", file_names[file], i ); 2712727702b1731a478de8806481416080d02af5862Michal Krol ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG)); 2722727702b1731a478de8806481416080d02af5862Michal Krol } 2731e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol 2741e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 2752727702b1731a478de8806481416080d02af5862Michal Krol} 2762727702b1731a478de8806481416080d02af5862Michal Krol 2771e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean 2781e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_immediate( 2791e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct tgsi_iterate_context *iter, 2802727702b1731a478de8806481416080d02af5862Michal Krol struct tgsi_full_immediate *imm ) 2812727702b1731a478de8806481416080d02af5862Michal Krol{ 2821e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; 2832727702b1731a478de8806481416080d02af5862Michal Krol 2842727702b1731a478de8806481416080d02af5862Michal Krol assert( ctx->num_imms < MAX_REGISTERS ); 2852727702b1731a478de8806481416080d02af5862Michal Krol 2862727702b1731a478de8806481416080d02af5862Michal Krol /* No immediates allowed after the first instruction. 2872727702b1731a478de8806481416080d02af5862Michal Krol */ 2882727702b1731a478de8806481416080d02af5862Michal Krol if (ctx->num_instructions > 0) 2892727702b1731a478de8806481416080d02af5862Michal Krol report_error( ctx, "Instruction expected but immediate found" ); 2902727702b1731a478de8806481416080d02af5862Michal Krol 2912727702b1731a478de8806481416080d02af5862Michal Krol /* Mark the register as declared. 2922727702b1731a478de8806481416080d02af5862Michal Krol */ 2932727702b1731a478de8806481416080d02af5862Michal Krol ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG)); 29451d219dbfe6852d348755574184639940af444e3Michal Krol ctx->num_imms++; 2952727702b1731a478de8806481416080d02af5862Michal Krol 2962727702b1731a478de8806481416080d02af5862Michal Krol /* Check data type validity. 2972727702b1731a478de8806481416080d02af5862Michal Krol */ 2982727702b1731a478de8806481416080d02af5862Michal Krol if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) { 299ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType ); 3001e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 3012727702b1731a478de8806481416080d02af5862Michal Krol } 3021e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol 3031e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 3042727702b1731a478de8806481416080d02af5862Michal Krol} 3052727702b1731a478de8806481416080d02af5862Michal Krol 3061e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean 3071e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolepilog( 3081e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct tgsi_iterate_context *iter ) 3092727702b1731a478de8806481416080d02af5862Michal Krol{ 3101e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; 3112727702b1731a478de8806481416080d02af5862Michal Krol uint file; 3122727702b1731a478de8806481416080d02af5862Michal Krol 313e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul /* There must be an END instruction somewhere. 3142727702b1731a478de8806481416080d02af5862Michal Krol */ 315e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul if (ctx->index_of_END == ~0) { 316e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul report_error( ctx, "Missing END instruction" ); 3172727702b1731a478de8806481416080d02af5862Michal Krol } 3182727702b1731a478de8806481416080d02af5862Michal Krol 3192727702b1731a478de8806481416080d02af5862Michal Krol /* Check if all declared registers were used. 3202727702b1731a478de8806481416080d02af5862Michal Krol */ 3212727702b1731a478de8806481416080d02af5862Michal Krol for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) { 3222727702b1731a478de8806481416080d02af5862Michal Krol uint i; 3232727702b1731a478de8806481416080d02af5862Michal Krol 3242727702b1731a478de8806481416080d02af5862Michal Krol for (i = 0; i < MAX_REGISTERS; i++) { 32573e1d0be756537376495547bc1e798805884b8efMichal Krol if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) { 326ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol report_warning( ctx, "%s[%u]: Register never used", file_names[file], i ); 3272727702b1731a478de8806481416080d02af5862Michal Krol } 3282727702b1731a478de8806481416080d02af5862Michal Krol } 3292727702b1731a478de8806481416080d02af5862Michal Krol } 3302727702b1731a478de8806481416080d02af5862Michal Krol 3312727702b1731a478de8806481416080d02af5862Michal Krol /* Print totals, if any. 3322727702b1731a478de8806481416080d02af5862Michal Krol */ 3332727702b1731a478de8806481416080d02af5862Michal Krol if (ctx->errors || ctx->warnings) 334eb5b16d278e0f7ee0121049e43dfee1d52f2b0f7José Fonseca debug_printf( "%u errors, %u warnings\n", ctx->errors, ctx->warnings ); 3351e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol 3361e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol return TRUE; 3372727702b1731a478de8806481416080d02af5862Michal Krol} 3382727702b1731a478de8806481416080d02af5862Michal Krol 3392727702b1731a478de8806481416080d02af5862Michal Krolboolean 3402727702b1731a478de8806481416080d02af5862Michal Kroltgsi_sanity_check( 3412727702b1731a478de8806481416080d02af5862Michal Krol struct tgsi_token *tokens ) 3422727702b1731a478de8806481416080d02af5862Michal Krol{ 3432727702b1731a478de8806481416080d02af5862Michal Krol struct sanity_check_ctx ctx; 3442727702b1731a478de8806481416080d02af5862Michal Krol 3451e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol ctx.iter.prolog = NULL; 3461e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol ctx.iter.iterate_instruction = iter_instruction; 3471e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol ctx.iter.iterate_declaration = iter_declaration; 3481e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol ctx.iter.iterate_immediate = iter_immediate; 3491e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol ctx.iter.epilog = epilog; 3502727702b1731a478de8806481416080d02af5862Michal Krol 3512727702b1731a478de8806481416080d02af5862Michal Krol memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); 3522727702b1731a478de8806481416080d02af5862Michal Krol memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); 35373e1d0be756537376495547bc1e798805884b8efMichal Krol memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) ); 3542727702b1731a478de8806481416080d02af5862Michal Krol ctx.num_imms = 0; 3552727702b1731a478de8806481416080d02af5862Michal Krol ctx.num_instructions = 0; 3562727702b1731a478de8806481416080d02af5862Michal Krol ctx.index_of_END = ~0; 3572727702b1731a478de8806481416080d02af5862Michal Krol 3582727702b1731a478de8806481416080d02af5862Michal Krol ctx.errors = 0; 3592727702b1731a478de8806481416080d02af5862Michal Krol ctx.warnings = 0; 3602727702b1731a478de8806481416080d02af5862Michal Krol 361fef7f2b070ab797f78ebc210bb40a24685c6d4b7Michal Krol if (!tgsi_iterate_shader( tokens, &ctx.iter )) 3622727702b1731a478de8806481416080d02af5862Michal Krol return FALSE; 3632727702b1731a478de8806481416080d02af5862Michal Krol 364ff26c50153b3a348b35843262ceb27062ab37214José Fonseca return ctx.errors == 0; 3652727702b1731a478de8806481416080d02af5862Michal Krol} 366