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"
2922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin#include "util/u_memory.h"
30a00da63e6612607044e93f2900fba21bddfd0cadZack Rusin#include "util/u_prim.h"
3122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin#include "cso_cache/cso_hash.h"
322727702b1731a478de8806481416080d02af5862Michal Krol#include "tgsi_sanity.h"
334b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol#include "tgsi_info.h"
341e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol#include "tgsi_iterate.h"
352727702b1731a478de8806481416080d02af5862Michal Krol
369f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
377f5202be63c6dc639e57d11ef8253e79dd349f59Jakob BornecrantzDEBUG_GET_ONCE_BOOL_OPTION(print_sanity, "TGSI_PRINT_SANITY", FALSE)
389f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
399f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
4022370990f28987b361c6adf8e81c5a18184e88eaZack Rusintypedef struct {
4122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint file : 28;
4222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   /* max 2 dimensions */
4322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint dimensions : 4;
4422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint indices[2];
4522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin} scan_register;
46ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol
472727702b1731a478de8806481416080d02af5862Michal Krolstruct sanity_check_ctx
482727702b1731a478de8806481416080d02af5862Michal Krol{
491e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context iter;
5022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_decl;
5122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_used;
5222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_ind_used;
532727702b1731a478de8806481416080d02af5862Michal Krol
542727702b1731a478de8806481416080d02af5862Michal Krol   uint num_imms;
552727702b1731a478de8806481416080d02af5862Michal Krol   uint num_instructions;
562727702b1731a478de8806481416080d02af5862Michal Krol   uint index_of_END;
572727702b1731a478de8806481416080d02af5862Michal Krol
582727702b1731a478de8806481416080d02af5862Michal Krol   uint errors;
592727702b1731a478de8806481416080d02af5862Michal Krol   uint warnings;
6022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint implied_array_size;
619f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
629f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz   boolean print;
632727702b1731a478de8806481416080d02af5862Michal Krol};
642727702b1731a478de8806481416080d02af5862Michal Krol
6522370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic INLINE unsigned
6622370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_key(const scan_register *reg)
6722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
6822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   unsigned key = reg->file;
6922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   key |= (reg->indices[0] << 4);
7022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   key |= (reg->indices[1] << 18);
7122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
7222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return key;
7322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
7422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
7522370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
7622370990f28987b361c6adf8e81c5a18184e88eaZack Rusinfill_scan_register1d(scan_register *reg,
7722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                     uint file, uint index)
7822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
7922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->file = file;
8022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->dimensions = 1;
8122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[0] = index;
8222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[1] = 0;
8322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
8422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
8522370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
8622370990f28987b361c6adf8e81c5a18184e88eaZack Rusinfill_scan_register2d(scan_register *reg,
8722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                     uint file, uint index1, uint index2)
8822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
8922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->file = file;
9022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->dimensions = 2;
9122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[0] = index1;
9222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[1] = index2;
9322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
9422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
9522370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
9622370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_dst(scan_register *reg,
9722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  struct tgsi_full_dst_register *dst)
9822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
99101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin   if (dst->Register.Dimension) {
100101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin      /*FIXME: right now we don't support indirect
101101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin       * multidimensional addressing */
102101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin      fill_scan_register2d(reg,
103101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin                           dst->Register.File,
104101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin                           dst->Register.Index,
105101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin                           dst->Dimension.Index);
106101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin   } else {
107101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin      fill_scan_register1d(reg,
108101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin                           dst->Register.File,
109101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin                           dst->Register.Index);
110101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin   }
11122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
11222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
11322370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
11422370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_src(scan_register *reg,
11522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  struct tgsi_full_src_register *src)
11622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
11722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (src->Register.Dimension) {
11822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      /*FIXME: right now we don't support indirect
11922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * multidimensional addressing */
12022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      fill_scan_register2d(reg,
12122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.File,
12222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.Index,
12322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Dimension.Index);
12422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   } else {
12522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      fill_scan_register1d(reg,
12622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.File,
12722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.Index);
12822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
12922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
13022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
13122370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic scan_register *
13222370990f28987b361c6adf8e81c5a18184e88eaZack Rusincreate_scan_register_src(struct tgsi_full_src_register *src)
13322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
13422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg = MALLOC(sizeof(scan_register));
13522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register_src(reg, src);
13622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
13722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return reg;
13822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
13922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
14022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic scan_register *
14122370990f28987b361c6adf8e81c5a18184e88eaZack Rusincreate_scan_register_dst(struct tgsi_full_dst_register *dst)
14222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
14322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg = MALLOC(sizeof(scan_register));
14422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register_dst(reg, dst);
14522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
14622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return reg;
14722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
14822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
1492727702b1731a478de8806481416080d02af5862Michal Krolstatic void
1502727702b1731a478de8806481416080d02af5862Michal Krolreport_error(
1512727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
15251d219dbfe6852d348755574184639940af444e3Michal Krol   const char *format,
15351d219dbfe6852d348755574184639940af444e3Michal Krol   ... )
1542727702b1731a478de8806481416080d02af5862Michal Krol{
15551d219dbfe6852d348755574184639940af444e3Michal Krol   va_list args;
15651d219dbfe6852d348755574184639940af444e3Michal Krol
1579f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz   if (!ctx->print)
1589f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz      return;
1599f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
16051d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "Error  : " );
16151d219dbfe6852d348755574184639940af444e3Michal Krol   va_start( args, format );
16251d219dbfe6852d348755574184639940af444e3Michal Krol   _debug_vprintf( format, args );
16351d219dbfe6852d348755574184639940af444e3Michal Krol   va_end( args );
16451d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "\n" );
1652727702b1731a478de8806481416080d02af5862Michal Krol   ctx->errors++;
1662727702b1731a478de8806481416080d02af5862Michal Krol}
1672727702b1731a478de8806481416080d02af5862Michal Krol
1682727702b1731a478de8806481416080d02af5862Michal Krolstatic void
1692727702b1731a478de8806481416080d02af5862Michal Krolreport_warning(
1702727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
17151d219dbfe6852d348755574184639940af444e3Michal Krol   const char *format,
17251d219dbfe6852d348755574184639940af444e3Michal Krol   ... )
1732727702b1731a478de8806481416080d02af5862Michal Krol{
17451d219dbfe6852d348755574184639940af444e3Michal Krol   va_list args;
17551d219dbfe6852d348755574184639940af444e3Michal Krol
1769f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz   if (!ctx->print)
1779f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz      return;
1789f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz
17951d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "Warning: " );
18051d219dbfe6852d348755574184639940af444e3Michal Krol   va_start( args, format );
18151d219dbfe6852d348755574184639940af444e3Michal Krol   _debug_vprintf( format, args );
18251d219dbfe6852d348755574184639940af444e3Michal Krol   va_end( args );
18351d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "\n" );
1842727702b1731a478de8806481416080d02af5862Michal Krol   ctx->warnings++;
1852727702b1731a478de8806481416080d02af5862Michal Krol}
1862727702b1731a478de8806481416080d02af5862Michal Krol
1872727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
1882727702b1731a478de8806481416080d02af5862Michal Krolcheck_file_name(
1892727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
1902727702b1731a478de8806481416080d02af5862Michal Krol   uint file )
1912727702b1731a478de8806481416080d02af5862Michal Krol{
1922727702b1731a478de8806481416080d02af5862Michal Krol   if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) {
193ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid register file name", file );
1942727702b1731a478de8806481416080d02af5862Michal Krol      return FALSE;
1952727702b1731a478de8806481416080d02af5862Michal Krol   }
1962727702b1731a478de8806481416080d02af5862Michal Krol   return TRUE;
1972727702b1731a478de8806481416080d02af5862Michal Krol}
1982727702b1731a478de8806481416080d02af5862Michal Krol
1992727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
2002727702b1731a478de8806481416080d02af5862Michal Krolis_register_declared(
2012727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
20222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   const scan_register *reg)
2032727702b1731a478de8806481416080d02af5862Michal Krol{
20422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   void *data = cso_hash_find_data_from_template(
20522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      ctx->regs_decl, scan_register_key(reg),
20622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      (void*)reg, sizeof(scan_register));
20722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return  data ? TRUE : FALSE;
2082727702b1731a478de8806481416080d02af5862Michal Krol}
2092727702b1731a478de8806481416080d02af5862Michal Krol
2102727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
21173e1d0be756537376495547bc1e798805884b8efMichal Krolis_any_register_declared(
21273e1d0be756537376495547bc1e798805884b8efMichal Krol   struct sanity_check_ctx *ctx,
21373e1d0be756537376495547bc1e798805884b8efMichal Krol   uint file )
21473e1d0be756537376495547bc1e798805884b8efMichal Krol{
21522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash_iter iter =
21622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      cso_hash_first_node(ctx->regs_decl);
21773e1d0be756537376495547bc1e798805884b8efMichal Krol
218767d1472df68a777c51c406fa3f8d642c7cf58c0Michal Krol   while (!cso_hash_iter_is_null(iter)) {
21922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
22022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (reg->file == file)
22173e1d0be756537376495547bc1e798805884b8efMichal Krol         return TRUE;
22222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      iter = cso_hash_iter_next(iter);
22322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
22422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
22573e1d0be756537376495547bc1e798805884b8efMichal Krol   return FALSE;
22673e1d0be756537376495547bc1e798805884b8efMichal Krol}
22773e1d0be756537376495547bc1e798805884b8efMichal Krol
22873e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean
2292727702b1731a478de8806481416080d02af5862Michal Krolis_register_used(
2302727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
23122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg)
2322727702b1731a478de8806481416080d02af5862Michal Krol{
23322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   void *data = cso_hash_find_data_from_template(
23422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      ctx->regs_used, scan_register_key(reg),
23522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg, sizeof(scan_register));
23622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return  data ? TRUE : FALSE;
23722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
2382727702b1731a478de8806481416080d02af5862Michal Krol
23922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
24022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic boolean
24122370990f28987b361c6adf8e81c5a18184e88eaZack Rusinis_ind_register_used(
24222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct sanity_check_ctx *ctx,
24322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg)
24422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
24522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return cso_hash_contains(ctx->regs_ind_used, reg->file);
2462727702b1731a478de8806481416080d02af5862Michal Krol}
2472727702b1731a478de8806481416080d02af5862Michal Krol
248cf8907018e449580b397f09c267219a612ba5db4Michal Krolstatic const char *file_names[TGSI_FILE_COUNT] =
24951d219dbfe6852d348755574184639940af444e3Michal Krol{
25051d219dbfe6852d348755574184639940af444e3Michal Krol   "NULL",
25151d219dbfe6852d348755574184639940af444e3Michal Krol   "CONST",
25251d219dbfe6852d348755574184639940af444e3Michal Krol   "IN",
25351d219dbfe6852d348755574184639940af444e3Michal Krol   "OUT",
25451d219dbfe6852d348755574184639940af444e3Michal Krol   "TEMP",
25551d219dbfe6852d348755574184639940af444e3Michal Krol   "SAMP",
25651d219dbfe6852d348755574184639940af444e3Michal Krol   "ADDR",
257cf8907018e449580b397f09c267219a612ba5db4Michal Krol   "IMM",
258d288698a76e2ad8408d303570578856a05ea96d0José Fonseca   "PRED",
2592b221e11da7a8bf759e3c359f22ba6f49d5f0997Zack Rusin   "SV",
260101f792a2af9c9a19a050afba8b60caa689466a5Zack Rusin   "IMMX",
261bdbe77f9c6f06cfaa155f27c2ade3c523d7fbea7Zack Rusin   "TEMPX",
262bdbe77f9c6f06cfaa155f27c2ade3c523d7fbea7Zack Rusin   "RES"
26351d219dbfe6852d348755574184639940af444e3Michal Krol};
26451d219dbfe6852d348755574184639940af444e3Michal Krol
2651e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
26673e1d0be756537376495547bc1e798805884b8efMichal Krolcheck_register_usage(
26773e1d0be756537376495547bc1e798805884b8efMichal Krol   struct sanity_check_ctx *ctx,
26822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg,
26951d219dbfe6852d348755574184639940af444e3Michal Krol   const char *name,
27051d219dbfe6852d348755574184639940af444e3Michal Krol   boolean indirect_access )
27173e1d0be756537376495547bc1e798805884b8efMichal Krol{
27222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (!check_file_name( ctx, reg->file )) {
27355b5c8816e95528cbe68599bade44796e10711cdMichal Krol      FREE(reg);
27473e1d0be756537376495547bc1e798805884b8efMichal Krol      return FALSE;
27522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
276ad16ecbbe4fe8c1bcb18ed8fbbd672c68a0b17faJakob Bornecrantz
27751d219dbfe6852d348755574184639940af444e3Michal Krol   if (indirect_access) {
278639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian      /* Note that 'index' is an offset relative to the value of the
27922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * address register.  No range checking done here.*/
28022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg->indices[0] = 0;
28122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg->indices[1] = 0;
28222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_any_register_declared( ctx, reg->file ))
28322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
28422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_ind_register_used(ctx, reg))
28522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
28622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      else
28755b5c8816e95528cbe68599bade44796e10711cdMichal Krol         FREE(reg);
28873e1d0be756537376495547bc1e798805884b8efMichal Krol   }
28973e1d0be756537376495547bc1e798805884b8efMichal Krol   else {
29022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_register_declared( ctx, reg )) {
2910c6794c46fdd1225bb1d8ece77ea937cb822a1a3Brian Paul         if (reg->dimensions == 2) {
29222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_error( ctx, "%s[%d][%d]: Undeclared %s register", file_names[reg->file],
29322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                          reg->indices[0], reg->indices[1], name );
2940c6794c46fdd1225bb1d8ece77ea937cb822a1a3Brian Paul         }
2950c6794c46fdd1225bb1d8ece77ea937cb822a1a3Brian Paul         else {
29622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_error( ctx, "%s[%d]: Undeclared %s register", file_names[reg->file],
29722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                          reg->indices[0], name );
29822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         }
2990c6794c46fdd1225bb1d8ece77ea937cb822a1a3Brian Paul      }
30022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_register_used( ctx, reg ))
30122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
30222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      else
30355b5c8816e95528cbe68599bade44796e10711cdMichal Krol         FREE(reg);
30473e1d0be756537376495547bc1e798805884b8efMichal Krol   }
30573e1d0be756537376495547bc1e798805884b8efMichal Krol   return TRUE;
30673e1d0be756537376495547bc1e798805884b8efMichal Krol}
30773e1d0be756537376495547bc1e798805884b8efMichal Krol
30873e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean
3091e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_instruction(
3101e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
3112727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_instruction *inst )
3122727702b1731a478de8806481416080d02af5862Michal Krol{
3131e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
3144b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   const struct tgsi_opcode_info *info;
3152727702b1731a478de8806481416080d02af5862Michal Krol   uint i;
3162727702b1731a478de8806481416080d02af5862Michal Krol
317e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
318e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      if (ctx->index_of_END != ~0) {
319e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul         report_error( ctx, "Too many END instructions" );
320e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      }
3212727702b1731a478de8806481416080d02af5862Michal Krol      ctx->index_of_END = ctx->num_instructions;
3222727702b1731a478de8806481416080d02af5862Michal Krol   }
3232727702b1731a478de8806481416080d02af5862Michal Krol
3244b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   info = tgsi_get_opcode_info( inst->Instruction.Opcode );
3254b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info == NULL) {
326ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode );
3274b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol      return TRUE;
3284b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3294b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol
3304b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info->num_dst != inst->Instruction.NumDstRegs) {
331848ab8be8c34b00b2afe6120882f8c29f047ced5Keith Whitwell      report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
3324b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3334b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info->num_src != inst->Instruction.NumSrcRegs) {
334848ab8be8c34b00b2afe6120882f8c29f047ced5Keith Whitwell      report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
3354b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3364b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol
3372727702b1731a478de8806481416080d02af5862Michal Krol   /* Check destination and source registers' validity.
3382727702b1731a478de8806481416080d02af5862Michal Krol    * Mark the registers as used.
3392727702b1731a478de8806481416080d02af5862Michal Krol    */
3402727702b1731a478de8806481416080d02af5862Michal Krol   for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
34122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = create_scan_register_dst(&inst->Dst[i]);
34273e1d0be756537376495547bc1e798805884b8efMichal Krol      check_register_usage(
34373e1d0be756537376495547bc1e798805884b8efMichal Krol         ctx,
34422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         reg,
34551d219dbfe6852d348755574184639940af444e3Michal Krol         "destination",
34673e1d0be756537376495547bc1e798805884b8efMichal Krol         FALSE );
34728e80aa0b85aac3ed3d34ee13b6412be4d9d5773José Fonseca      if (!inst->Dst[i].Register.WriteMask) {
34828e80aa0b85aac3ed3d34ee13b6412be4d9d5773José Fonseca         report_error(ctx, "Destination register has empty writemask");
34928e80aa0b85aac3ed3d34ee13b6412be4d9d5773José Fonseca      }
3502727702b1731a478de8806481416080d02af5862Michal Krol   }
3512727702b1731a478de8806481416080d02af5862Michal Krol   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
35222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = create_scan_register_src(&inst->Src[i]);
35373e1d0be756537376495547bc1e798805884b8efMichal Krol      check_register_usage(
35473e1d0be756537376495547bc1e798805884b8efMichal Krol         ctx,
35522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         reg,
35651d219dbfe6852d348755574184639940af444e3Michal Krol         "source",
35791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         (boolean)inst->Src[i].Register.Indirect );
35891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (inst->Src[i].Register.Indirect) {
35922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *ind_reg = MALLOC(sizeof(scan_register));
36025a7f422b4e307dce966220d47794fb056d04aacMichal Krol
36122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         fill_scan_register1d(ind_reg,
36222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                              inst->Src[i].Indirect.File,
36322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                              inst->Src[i].Indirect.Index);
36451d219dbfe6852d348755574184639940af444e3Michal Krol         check_register_usage(
36551d219dbfe6852d348755574184639940af444e3Michal Krol            ctx,
366d1767bfdabac4fd1eedb1ad9ddea368e077725c6Michal Krol            ind_reg,
36751d219dbfe6852d348755574184639940af444e3Michal Krol            "indirect",
36851d219dbfe6852d348755574184639940af444e3Michal Krol            FALSE );
36973e1d0be756537376495547bc1e798805884b8efMichal Krol      }
3702727702b1731a478de8806481416080d02af5862Michal Krol   }
3712727702b1731a478de8806481416080d02af5862Michal Krol
3722727702b1731a478de8806481416080d02af5862Michal Krol   ctx->num_instructions++;
3731e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
3741e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
3752727702b1731a478de8806481416080d02af5862Michal Krol}
3762727702b1731a478de8806481416080d02af5862Michal Krol
37722370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
37822370990f28987b361c6adf8e81c5a18184e88eaZack Rusincheck_and_declare(struct sanity_check_ctx *ctx,
37922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  scan_register *reg)
38022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
38122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (is_register_declared( ctx, reg))
38222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      report_error( ctx, "%s[%u]: The same register declared more than once",
38322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                    file_names[reg->file], reg->indices[0] );
38422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_insert(ctx->regs_decl,
38522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                   scan_register_key(reg),
38622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                   reg);
38722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
38822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
38922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
3901e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
3911e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_declaration(
3921e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
3932727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_declaration *decl )
3942727702b1731a478de8806481416080d02af5862Michal Krol{
3951e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
3962727702b1731a478de8806481416080d02af5862Michal Krol   uint file;
3972727702b1731a478de8806481416080d02af5862Michal Krol   uint i;
3982727702b1731a478de8806481416080d02af5862Michal Krol
3992727702b1731a478de8806481416080d02af5862Michal Krol   /* No declarations allowed after the first instruction.
4002727702b1731a478de8806481416080d02af5862Michal Krol    */
4012727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->num_instructions > 0)
4022727702b1731a478de8806481416080d02af5862Michal Krol      report_error( ctx, "Instruction expected but declaration found" );
4032727702b1731a478de8806481416080d02af5862Michal Krol
4042727702b1731a478de8806481416080d02af5862Michal Krol   /* Check registers' validity.
4052727702b1731a478de8806481416080d02af5862Michal Krol    * Mark the registers as declared.
4062727702b1731a478de8806481416080d02af5862Michal Krol    */
4072727702b1731a478de8806481416080d02af5862Michal Krol   file = decl->Declaration.File;
4082727702b1731a478de8806481416080d02af5862Michal Krol   if (!check_file_name( ctx, file ))
4091e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol      return TRUE;
410fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell   for (i = decl->Range.First; i <= decl->Range.Last; i++) {
41122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      /* declared TGSI_FILE_INPUT's for geometry processor
41222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * have an implied second dimension */
41322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (file == TGSI_FILE_INPUT &&
41422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin          ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
41522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         uint vert;
41622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         for (vert = 0; vert < ctx->implied_array_size; ++vert) {
41722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            scan_register *reg = MALLOC(sizeof(scan_register));
4187472cd0f1f0f8284729274bc5c453d59d9ab4b55Michal Krol            fill_scan_register2d(reg, file, i, vert);
41922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            check_and_declare(ctx, reg);
42022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         }
42122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      } else {
42222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *reg = MALLOC(sizeof(scan_register));
4234367de152cc5bd7240d75a33e75c1b1671b5cc16Michal Krol         if (decl->Declaration.Dimension) {
4244367de152cc5bd7240d75a33e75c1b1671b5cc16Michal Krol            fill_scan_register2d(reg, file, i, decl->Dim.Index2D);
4254367de152cc5bd7240d75a33e75c1b1671b5cc16Michal Krol         } else {
4264367de152cc5bd7240d75a33e75c1b1671b5cc16Michal Krol            fill_scan_register1d(reg, file, i);
4274367de152cc5bd7240d75a33e75c1b1671b5cc16Michal Krol         }
42822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         check_and_declare(ctx, reg);
42922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      }
4302727702b1731a478de8806481416080d02af5862Michal Krol   }
4311e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
4321e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
4332727702b1731a478de8806481416080d02af5862Michal Krol}
4342727702b1731a478de8806481416080d02af5862Michal Krol
4351e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
4361e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_immediate(
4371e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
4382727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_immediate *imm )
4392727702b1731a478de8806481416080d02af5862Michal Krol{
4401e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
44122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg;
4422727702b1731a478de8806481416080d02af5862Michal Krol
4432727702b1731a478de8806481416080d02af5862Michal Krol   /* No immediates allowed after the first instruction.
4442727702b1731a478de8806481416080d02af5862Michal Krol    */
4452727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->num_instructions > 0)
4462727702b1731a478de8806481416080d02af5862Michal Krol      report_error( ctx, "Instruction expected but immediate found" );
4472727702b1731a478de8806481416080d02af5862Michal Krol
4482727702b1731a478de8806481416080d02af5862Michal Krol   /* Mark the register as declared.
4492727702b1731a478de8806481416080d02af5862Michal Krol    */
45022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg = MALLOC(sizeof(scan_register));
45122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   fill_scan_register1d(reg, TGSI_FILE_IMMEDIATE, ctx->num_imms);
45222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_insert(ctx->regs_decl, scan_register_key(reg), reg);
45351d219dbfe6852d348755574184639940af444e3Michal Krol   ctx->num_imms++;
4542727702b1731a478de8806481416080d02af5862Michal Krol
4552727702b1731a478de8806481416080d02af5862Michal Krol   /* Check data type validity.
4562727702b1731a478de8806481416080d02af5862Michal Krol    */
457ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol   if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
458ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol       imm->Immediate.DataType != TGSI_IMM_UINT32 &&
459ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol       imm->Immediate.DataType != TGSI_IMM_INT32) {
460ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
4611e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol      return TRUE;
4622727702b1731a478de8806481416080d02af5862Michal Krol   }
4631e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
4641e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
4652727702b1731a478de8806481416080d02af5862Michal Krol}
4662727702b1731a478de8806481416080d02af5862Michal Krol
4673ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
4683ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusinstatic boolean
4693ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusiniter_property(
4703ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   struct tgsi_iterate_context *iter,
4713ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   struct tgsi_full_property *prop )
4723ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin{
47322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
4743ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
47522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY &&
47622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
477a00da63e6612607044e93f2900fba21bddfd0cadZack Rusin      ctx->implied_array_size = u_vertices_per_prim(prop->u[0].Data);
47822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
4793ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   return TRUE;
4803ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin}
4813ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
4821e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
4831e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolepilog(
4841e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter )
4852727702b1731a478de8806481416080d02af5862Michal Krol{
4861e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
4872727702b1731a478de8806481416080d02af5862Michal Krol
488e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   /* There must be an END instruction somewhere.
4892727702b1731a478de8806481416080d02af5862Michal Krol    */
490e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   if (ctx->index_of_END == ~0) {
491e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      report_error( ctx, "Missing END instruction" );
4922727702b1731a478de8806481416080d02af5862Michal Krol   }
4932727702b1731a478de8806481416080d02af5862Michal Krol
4942727702b1731a478de8806481416080d02af5862Michal Krol   /* Check if all declared registers were used.
4952727702b1731a478de8806481416080d02af5862Michal Krol    */
49622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   {
49722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      struct cso_hash_iter iter =
49822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_first_node(ctx->regs_decl);
49922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
500767d1472df68a777c51c406fa3f8d642c7cf58c0Michal Krol      while (!cso_hash_iter_is_null(iter)) {
50122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
50222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         if (!is_register_used(ctx, reg) && !is_ind_register_used(ctx, reg)) {
50322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_warning( ctx, "%s[%u]: Register never used",
50422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                            file_names[reg->file], reg->indices[0] );
5052727702b1731a478de8806481416080d02af5862Michal Krol         }
50622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         iter = cso_hash_iter_next(iter);
5072727702b1731a478de8806481416080d02af5862Michal Krol      }
5082727702b1731a478de8806481416080d02af5862Michal Krol   }
5092727702b1731a478de8806481416080d02af5862Michal Krol
5102727702b1731a478de8806481416080d02af5862Michal Krol   /* Print totals, if any.
5112727702b1731a478de8806481416080d02af5862Michal Krol    */
5122727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->errors || ctx->warnings)
513eb5b16d278e0f7ee0121049e43dfee1d52f2b0f7José Fonseca      debug_printf( "%u errors, %u warnings\n", ctx->errors, ctx->warnings );
5141e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
5151e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
5162727702b1731a478de8806481416080d02af5862Michal Krol}
5172727702b1731a478de8806481416080d02af5862Michal Krol
51822370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
51922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinregs_hash_destroy(struct cso_hash *hash)
52022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
52122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash_iter iter = cso_hash_first_node(hash);
52222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   while (!cso_hash_iter_is_null(iter)) {
52322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
52422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      iter = cso_hash_erase(hash, iter);
5257335d8006fdc065c8dbe6b63007ffa77ffd53470Brian Paul      assert(reg->file < TGSI_FILE_COUNT);
52655b5c8816e95528cbe68599bade44796e10711cdMichal Krol      FREE(reg);
52722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
52822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_delete(hash);
52922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
53022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
5312727702b1731a478de8806481416080d02af5862Michal Krolboolean
5322727702b1731a478de8806481416080d02af5862Michal Kroltgsi_sanity_check(
533983b261e6d85020ae19418428d25f2e70f43d7ddKeith Whitwell   const struct tgsi_token *tokens )
5342727702b1731a478de8806481416080d02af5862Michal Krol{
5352727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx ctx;
5362727702b1731a478de8806481416080d02af5862Michal Krol
5371e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.prolog = NULL;
5381e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_instruction = iter_instruction;
5391e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_declaration = iter_declaration;
5401e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_immediate = iter_immediate;
5413ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   ctx.iter.iterate_property = iter_property;
5421e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.epilog = epilog;
5432727702b1731a478de8806481416080d02af5862Michal Krol
54422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_decl = cso_hash_create();
54522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_used = cso_hash_create();
54622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_ind_used = cso_hash_create();
54722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
5482727702b1731a478de8806481416080d02af5862Michal Krol   ctx.num_imms = 0;
5492727702b1731a478de8806481416080d02af5862Michal Krol   ctx.num_instructions = 0;
5502727702b1731a478de8806481416080d02af5862Michal Krol   ctx.index_of_END = ~0;
5512727702b1731a478de8806481416080d02af5862Michal Krol
5522727702b1731a478de8806481416080d02af5862Michal Krol   ctx.errors = 0;
5532727702b1731a478de8806481416080d02af5862Michal Krol   ctx.warnings = 0;
55422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.implied_array_size = 0;
5559f5c1194ff0ff69be5d7641d68169b152bc6cd0aJakob Bornecrantz   ctx.print = debug_get_option_print_sanity();
5562727702b1731a478de8806481416080d02af5862Michal Krol
557fef7f2b070ab797f78ebc210bb40a24685c6d4b7Michal Krol   if (!tgsi_iterate_shader( tokens, &ctx.iter ))
5582727702b1731a478de8806481416080d02af5862Michal Krol      return FALSE;
5592727702b1731a478de8806481416080d02af5862Michal Krol
56022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_decl);
56122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_used);
56222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_ind_used);
563ff26c50153b3a348b35843262ceb27062ab37214José Fonseca   return ctx.errors == 0;
5642727702b1731a478de8806481416080d02af5862Michal Krol}
565