tgsi_sanity.c revision 767d1472df68a777c51c406fa3f8d642c7cf58c0
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
3622370990f28987b361c6adf8e81c5a18184e88eaZack Rusintypedef struct {
3722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint file : 28;
3822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   /* max 2 dimensions */
3922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint dimensions : 4;
4022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint indices[2];
4122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin} scan_register;
42ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol
432727702b1731a478de8806481416080d02af5862Michal Krolstruct sanity_check_ctx
442727702b1731a478de8806481416080d02af5862Michal Krol{
451e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context iter;
4622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_decl;
4722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_used;
4822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash *regs_ind_used;
492727702b1731a478de8806481416080d02af5862Michal Krol
502727702b1731a478de8806481416080d02af5862Michal Krol   uint num_imms;
512727702b1731a478de8806481416080d02af5862Michal Krol   uint num_instructions;
522727702b1731a478de8806481416080d02af5862Michal Krol   uint index_of_END;
532727702b1731a478de8806481416080d02af5862Michal Krol
542727702b1731a478de8806481416080d02af5862Michal Krol   uint errors;
552727702b1731a478de8806481416080d02af5862Michal Krol   uint warnings;
5622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   uint implied_array_size;
572727702b1731a478de8806481416080d02af5862Michal Krol};
582727702b1731a478de8806481416080d02af5862Michal Krol
5922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic INLINE unsigned
6022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_key(const scan_register *reg)
6122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
6222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   unsigned key = reg->file;
6322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   key |= (reg->indices[0] << 4);
6422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   key |= (reg->indices[1] << 18);
6522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
6622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return key;
6722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
6822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
6922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
7022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinfill_scan_register1d(scan_register *reg,
7122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                     uint file, uint index)
7222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
7322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->file = file;
7422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->dimensions = 1;
7522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[0] = index;
7622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[1] = 0;
7722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
7822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
7922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
8022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinfill_scan_register2d(scan_register *reg,
8122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                     uint file, uint index1, uint index2)
8222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
8322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->file = file;
8422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->dimensions = 2;
8522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[0] = index1;
8622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg->indices[1] = index2;
8722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
8822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
8922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
9022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_dst(scan_register *reg,
9122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  struct tgsi_full_dst_register *dst)
9222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
9322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   fill_scan_register1d(reg,
9422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                        dst->Register.File,
9522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                        dst->Register.Index);
9622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
9722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
9822370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
9922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinscan_register_src(scan_register *reg,
10022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  struct tgsi_full_src_register *src)
10122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
10222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (src->Register.Dimension) {
10322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      /*FIXME: right now we don't support indirect
10422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * multidimensional addressing */
10522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      debug_assert(!src->Dimension.Indirect);
10622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      fill_scan_register2d(reg,
10722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.File,
10822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.Index,
10922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Dimension.Index);
11022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   } else {
11122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      fill_scan_register1d(reg,
11222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.File,
11322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                           src->Register.Index);
11422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
11522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
11622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
11722370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic scan_register *
11822370990f28987b361c6adf8e81c5a18184e88eaZack Rusincreate_scan_register_src(struct tgsi_full_src_register *src)
11922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
12022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg = MALLOC(sizeof(scan_register));
12122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register_src(reg, src);
12222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
12322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return reg;
12422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
12522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
12622370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic scan_register *
12722370990f28987b361c6adf8e81c5a18184e88eaZack Rusincreate_scan_register_dst(struct tgsi_full_dst_register *dst)
12822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
12922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg = MALLOC(sizeof(scan_register));
13022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register_dst(reg, dst);
13122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
13222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return reg;
13322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
13422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
1352727702b1731a478de8806481416080d02af5862Michal Krolstatic void
1362727702b1731a478de8806481416080d02af5862Michal Krolreport_error(
1372727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
13851d219dbfe6852d348755574184639940af444e3Michal Krol   const char *format,
13951d219dbfe6852d348755574184639940af444e3Michal Krol   ... )
1402727702b1731a478de8806481416080d02af5862Michal Krol{
14151d219dbfe6852d348755574184639940af444e3Michal Krol   va_list args;
14251d219dbfe6852d348755574184639940af444e3Michal Krol
14351d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "Error  : " );
14451d219dbfe6852d348755574184639940af444e3Michal Krol   va_start( args, format );
14551d219dbfe6852d348755574184639940af444e3Michal Krol   _debug_vprintf( format, args );
14651d219dbfe6852d348755574184639940af444e3Michal Krol   va_end( args );
14751d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "\n" );
1482727702b1731a478de8806481416080d02af5862Michal Krol   ctx->errors++;
1492727702b1731a478de8806481416080d02af5862Michal Krol}
1502727702b1731a478de8806481416080d02af5862Michal Krol
1512727702b1731a478de8806481416080d02af5862Michal Krolstatic void
1522727702b1731a478de8806481416080d02af5862Michal Krolreport_warning(
1532727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
15451d219dbfe6852d348755574184639940af444e3Michal Krol   const char *format,
15551d219dbfe6852d348755574184639940af444e3Michal Krol   ... )
1562727702b1731a478de8806481416080d02af5862Michal Krol{
15751d219dbfe6852d348755574184639940af444e3Michal Krol   va_list args;
15851d219dbfe6852d348755574184639940af444e3Michal Krol
15951d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "Warning: " );
16051d219dbfe6852d348755574184639940af444e3Michal Krol   va_start( args, format );
16151d219dbfe6852d348755574184639940af444e3Michal Krol   _debug_vprintf( format, args );
16251d219dbfe6852d348755574184639940af444e3Michal Krol   va_end( args );
16351d219dbfe6852d348755574184639940af444e3Michal Krol   debug_printf( "\n" );
1642727702b1731a478de8806481416080d02af5862Michal Krol   ctx->warnings++;
1652727702b1731a478de8806481416080d02af5862Michal Krol}
1662727702b1731a478de8806481416080d02af5862Michal Krol
1672727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
1682727702b1731a478de8806481416080d02af5862Michal Krolcheck_file_name(
1692727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
1702727702b1731a478de8806481416080d02af5862Michal Krol   uint file )
1712727702b1731a478de8806481416080d02af5862Michal Krol{
1722727702b1731a478de8806481416080d02af5862Michal Krol   if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) {
173ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid register file name", file );
1742727702b1731a478de8806481416080d02af5862Michal Krol      return FALSE;
1752727702b1731a478de8806481416080d02af5862Michal Krol   }
1762727702b1731a478de8806481416080d02af5862Michal Krol   return TRUE;
1772727702b1731a478de8806481416080d02af5862Michal Krol}
1782727702b1731a478de8806481416080d02af5862Michal Krol
1792727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
1802727702b1731a478de8806481416080d02af5862Michal Krolis_register_declared(
1812727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
18222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   const scan_register *reg)
1832727702b1731a478de8806481416080d02af5862Michal Krol{
18422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   void *data = cso_hash_find_data_from_template(
18522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      ctx->regs_decl, scan_register_key(reg),
18622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      (void*)reg, sizeof(scan_register));
18722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return  data ? TRUE : FALSE;
1882727702b1731a478de8806481416080d02af5862Michal Krol}
1892727702b1731a478de8806481416080d02af5862Michal Krol
1902727702b1731a478de8806481416080d02af5862Michal Krolstatic boolean
19173e1d0be756537376495547bc1e798805884b8efMichal Krolis_any_register_declared(
19273e1d0be756537376495547bc1e798805884b8efMichal Krol   struct sanity_check_ctx *ctx,
19373e1d0be756537376495547bc1e798805884b8efMichal Krol   uint file )
19473e1d0be756537376495547bc1e798805884b8efMichal Krol{
19522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash_iter iter =
19622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      cso_hash_first_node(ctx->regs_decl);
19773e1d0be756537376495547bc1e798805884b8efMichal Krol
198767d1472df68a777c51c406fa3f8d642c7cf58c0Michal Krol   while (!cso_hash_iter_is_null(iter)) {
19922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
20022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (reg->file == file)
20173e1d0be756537376495547bc1e798805884b8efMichal Krol         return TRUE;
20222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      iter = cso_hash_iter_next(iter);
20322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
20422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
20573e1d0be756537376495547bc1e798805884b8efMichal Krol   return FALSE;
20673e1d0be756537376495547bc1e798805884b8efMichal Krol}
20773e1d0be756537376495547bc1e798805884b8efMichal Krol
20873e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean
2092727702b1731a478de8806481416080d02af5862Michal Krolis_register_used(
2102727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx *ctx,
21122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg)
2122727702b1731a478de8806481416080d02af5862Michal Krol{
21322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   void *data = cso_hash_find_data_from_template(
21422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      ctx->regs_used, scan_register_key(reg),
21522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg, sizeof(scan_register));
21622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return  data ? TRUE : FALSE;
21722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
2182727702b1731a478de8806481416080d02af5862Michal Krol
21922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
22022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic boolean
22122370990f28987b361c6adf8e81c5a18184e88eaZack Rusinis_ind_register_used(
22222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct sanity_check_ctx *ctx,
22322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg)
22422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
22522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   return cso_hash_contains(ctx->regs_ind_used, reg->file);
2262727702b1731a478de8806481416080d02af5862Michal Krol}
2272727702b1731a478de8806481416080d02af5862Michal Krol
228cf8907018e449580b397f09c267219a612ba5db4Michal Krolstatic const char *file_names[TGSI_FILE_COUNT] =
22951d219dbfe6852d348755574184639940af444e3Michal Krol{
23051d219dbfe6852d348755574184639940af444e3Michal Krol   "NULL",
23151d219dbfe6852d348755574184639940af444e3Michal Krol   "CONST",
23251d219dbfe6852d348755574184639940af444e3Michal Krol   "IN",
23351d219dbfe6852d348755574184639940af444e3Michal Krol   "OUT",
23451d219dbfe6852d348755574184639940af444e3Michal Krol   "TEMP",
23551d219dbfe6852d348755574184639940af444e3Michal Krol   "SAMP",
23651d219dbfe6852d348755574184639940af444e3Michal Krol   "ADDR",
237cf8907018e449580b397f09c267219a612ba5db4Michal Krol   "IMM",
238aa2b2e5d7d53ddd08425536edddec509a8834bfcMichal Krol   "LOOP",
239aa2b2e5d7d53ddd08425536edddec509a8834bfcMichal Krol   "PRED"
24051d219dbfe6852d348755574184639940af444e3Michal Krol};
24151d219dbfe6852d348755574184639940af444e3Michal Krol
2421e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
24373e1d0be756537376495547bc1e798805884b8efMichal Krolcheck_register_usage(
24473e1d0be756537376495547bc1e798805884b8efMichal Krol   struct sanity_check_ctx *ctx,
24522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg,
24651d219dbfe6852d348755574184639940af444e3Michal Krol   const char *name,
24751d219dbfe6852d348755574184639940af444e3Michal Krol   boolean indirect_access )
24873e1d0be756537376495547bc1e798805884b8efMichal Krol{
24922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (!check_file_name( ctx, reg->file )) {
25022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      free(reg);
25173e1d0be756537376495547bc1e798805884b8efMichal Krol      return FALSE;
25222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
253ad16ecbbe4fe8c1bcb18ed8fbbd672c68a0b17faJakob Bornecrantz
25451d219dbfe6852d348755574184639940af444e3Michal Krol   if (indirect_access) {
255639a2b0ec853eda49e3e7150b2ed7f8f40d101afBrian      /* Note that 'index' is an offset relative to the value of the
25622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * address register.  No range checking done here.*/
25722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg->indices[0] = 0;
25822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      reg->indices[1] = 0;
25922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_any_register_declared( ctx, reg->file ))
26022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
26122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_ind_register_used(ctx, reg))
26222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
26322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      else
26422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         free(reg);
26573e1d0be756537376495547bc1e798805884b8efMichal Krol   }
26673e1d0be756537376495547bc1e798805884b8efMichal Krol   else {
26722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_register_declared( ctx, reg )) {
26822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         if (reg->dimensions == 2)
26922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_error( ctx, "%s[%d][%d]: Undeclared %s register", file_names[reg->file],
27022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                          reg->indices[0], reg->indices[1], name );
27122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         else
27222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_error( ctx, "%s[%d]: Undeclared %s register", file_names[reg->file],
27322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                          reg->indices[0], name );
27422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         }
27522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (!is_register_used( ctx, reg ))
27622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
27722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      else
27822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         free(reg);
27973e1d0be756537376495547bc1e798805884b8efMichal Krol   }
28073e1d0be756537376495547bc1e798805884b8efMichal Krol   return TRUE;
28173e1d0be756537376495547bc1e798805884b8efMichal Krol}
28273e1d0be756537376495547bc1e798805884b8efMichal Krol
28373e1d0be756537376495547bc1e798805884b8efMichal Krolstatic boolean
2841e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_instruction(
2851e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
2862727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_instruction *inst )
2872727702b1731a478de8806481416080d02af5862Michal Krol{
2881e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
2894b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   const struct tgsi_opcode_info *info;
2902727702b1731a478de8806481416080d02af5862Michal Krol   uint i;
2912727702b1731a478de8806481416080d02af5862Michal Krol
292e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
293e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      if (ctx->index_of_END != ~0) {
294e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul         report_error( ctx, "Too many END instructions" );
295e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      }
2962727702b1731a478de8806481416080d02af5862Michal Krol      ctx->index_of_END = ctx->num_instructions;
2972727702b1731a478de8806481416080d02af5862Michal Krol   }
2982727702b1731a478de8806481416080d02af5862Michal Krol
2994b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   info = tgsi_get_opcode_info( inst->Instruction.Opcode );
3004b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info == NULL) {
301ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode );
3024b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol      return TRUE;
3034b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3044b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol
3054b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info->num_dst != inst->Instruction.NumDstRegs) {
306848ab8be8c34b00b2afe6120882f8c29f047ced5Keith Whitwell      report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
3074b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3084b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   if (info->num_src != inst->Instruction.NumSrcRegs) {
309848ab8be8c34b00b2afe6120882f8c29f047ced5Keith Whitwell      report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
3104b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol   }
3114b929b32d03a58d80cacbd63c172dbd7221c8a8fMichal Krol
3122727702b1731a478de8806481416080d02af5862Michal Krol   /* Check destination and source registers' validity.
3132727702b1731a478de8806481416080d02af5862Michal Krol    * Mark the registers as used.
3142727702b1731a478de8806481416080d02af5862Michal Krol    */
3152727702b1731a478de8806481416080d02af5862Michal Krol   for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
31622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = create_scan_register_dst(&inst->Dst[i]);
31773e1d0be756537376495547bc1e798805884b8efMichal Krol      check_register_usage(
31873e1d0be756537376495547bc1e798805884b8efMichal Krol         ctx,
31922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         reg,
32051d219dbfe6852d348755574184639940af444e3Michal Krol         "destination",
32173e1d0be756537376495547bc1e798805884b8efMichal Krol         FALSE );
3222727702b1731a478de8806481416080d02af5862Michal Krol   }
3232727702b1731a478de8806481416080d02af5862Michal Krol   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
32422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = create_scan_register_src(&inst->Src[i]);
32573e1d0be756537376495547bc1e798805884b8efMichal Krol      check_register_usage(
32673e1d0be756537376495547bc1e798805884b8efMichal Krol         ctx,
32722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         reg,
32851d219dbfe6852d348755574184639940af444e3Michal Krol         "source",
32991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         (boolean)inst->Src[i].Register.Indirect );
33091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (inst->Src[i].Register.Indirect) {
33122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *ind_reg = MALLOC(sizeof(scan_register));
33225a7f422b4e307dce966220d47794fb056d04aacMichal Krol
33322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         fill_scan_register1d(ind_reg,
33422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                              inst->Src[i].Indirect.File,
33522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                              inst->Src[i].Indirect.Index);
33651d219dbfe6852d348755574184639940af444e3Michal Krol         check_register_usage(
33751d219dbfe6852d348755574184639940af444e3Michal Krol            ctx,
33822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            reg,
33951d219dbfe6852d348755574184639940af444e3Michal Krol            "indirect",
34051d219dbfe6852d348755574184639940af444e3Michal Krol            FALSE );
34122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         if (!(reg->file == TGSI_FILE_ADDRESS || reg->file == TGSI_FILE_LOOP) ||
34222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin             reg->indices[0] != 0) {
3436c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol            report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
3446c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol         }
34573e1d0be756537376495547bc1e798805884b8efMichal Krol      }
3462727702b1731a478de8806481416080d02af5862Michal Krol   }
3472727702b1731a478de8806481416080d02af5862Michal Krol
3486c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol   switch (inst->Instruction.Opcode) {
349cb90c43676c258419e4b617c908570891d3674cbMichal Krol   case TGSI_OPCODE_BGNFOR:
350cb90c43676c258419e4b617c908570891d3674cbMichal Krol   case TGSI_OPCODE_ENDFOR:
3515b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      if (inst->Dst[0].Register.File != TGSI_FILE_LOOP ||
3525b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell          inst->Dst[0].Register.Index != 0) {
3536c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol         report_error(ctx, "Destination register must be LOOP[0]");
3546c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol      }
3556c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol      break;
3566c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol   }
3576c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol
3586c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol   switch (inst->Instruction.Opcode) {
359cb90c43676c258419e4b617c908570891d3674cbMichal Krol   case TGSI_OPCODE_BGNFOR:
36091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (inst->Src[0].Register.File != TGSI_FILE_CONSTANT &&
36191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell          inst->Src[0].Register.File != TGSI_FILE_IMMEDIATE) {
3626c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol         report_error(ctx, "Source register file must be either CONST or IMM");
3636c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol      }
3646c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol      break;
3656c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol   }
3666c70285e330bd19db78b7d45e43a01b0255ca15fMichal Krol
3672727702b1731a478de8806481416080d02af5862Michal Krol   ctx->num_instructions++;
3681e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
3691e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
3702727702b1731a478de8806481416080d02af5862Michal Krol}
3712727702b1731a478de8806481416080d02af5862Michal Krol
37222370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
37322370990f28987b361c6adf8e81c5a18184e88eaZack Rusincheck_and_declare(struct sanity_check_ctx *ctx,
37422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                  scan_register *reg)
37522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
37622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (is_register_declared( ctx, reg))
37722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      report_error( ctx, "%s[%u]: The same register declared more than once",
37822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                    file_names[reg->file], reg->indices[0] );
37922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_insert(ctx->regs_decl,
38022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                   scan_register_key(reg),
38122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                   reg);
38222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
38322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
38422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
3851e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
3861e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_declaration(
3871e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
3882727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_declaration *decl )
3892727702b1731a478de8806481416080d02af5862Michal Krol{
3901e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
3912727702b1731a478de8806481416080d02af5862Michal Krol   uint file;
3922727702b1731a478de8806481416080d02af5862Michal Krol   uint i;
3932727702b1731a478de8806481416080d02af5862Michal Krol
3942727702b1731a478de8806481416080d02af5862Michal Krol   /* No declarations allowed after the first instruction.
3952727702b1731a478de8806481416080d02af5862Michal Krol    */
3962727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->num_instructions > 0)
3972727702b1731a478de8806481416080d02af5862Michal Krol      report_error( ctx, "Instruction expected but declaration found" );
3982727702b1731a478de8806481416080d02af5862Michal Krol
3992727702b1731a478de8806481416080d02af5862Michal Krol   /* Check registers' validity.
4002727702b1731a478de8806481416080d02af5862Michal Krol    * Mark the registers as declared.
4012727702b1731a478de8806481416080d02af5862Michal Krol    */
4022727702b1731a478de8806481416080d02af5862Michal Krol   file = decl->Declaration.File;
4032727702b1731a478de8806481416080d02af5862Michal Krol   if (!check_file_name( ctx, file ))
4041e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol      return TRUE;
405fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell   for (i = decl->Range.First; i <= decl->Range.Last; i++) {
40622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      /* declared TGSI_FILE_INPUT's for geometry processor
40722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       * have an implied second dimension */
40822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      if (file == TGSI_FILE_INPUT &&
40922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin          ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
41022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         uint vert;
41122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         for (vert = 0; vert < ctx->implied_array_size; ++vert) {
41222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            scan_register *reg = MALLOC(sizeof(scan_register));
41322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            fill_scan_register2d(reg, file, vert, i);
41422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            check_and_declare(ctx, reg);
41522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         }
41622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      } else {
41722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *reg = MALLOC(sizeof(scan_register));
41822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         fill_scan_register1d(reg, file, i);
41922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         check_and_declare(ctx, reg);
42022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      }
4212727702b1731a478de8806481416080d02af5862Michal Krol   }
4221e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
4231e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
4242727702b1731a478de8806481416080d02af5862Michal Krol}
4252727702b1731a478de8806481416080d02af5862Michal Krol
4261e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
4271e5419fa3061386413a98b75d0908cb3e3c6894eMichal Kroliter_immediate(
4281e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter,
4292727702b1731a478de8806481416080d02af5862Michal Krol   struct tgsi_full_immediate *imm )
4302727702b1731a478de8806481416080d02af5862Michal Krol{
4311e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
43222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   scan_register *reg;
4332727702b1731a478de8806481416080d02af5862Michal Krol
4342727702b1731a478de8806481416080d02af5862Michal Krol   /* No immediates allowed after the first instruction.
4352727702b1731a478de8806481416080d02af5862Michal Krol    */
4362727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->num_instructions > 0)
4372727702b1731a478de8806481416080d02af5862Michal Krol      report_error( ctx, "Instruction expected but immediate found" );
4382727702b1731a478de8806481416080d02af5862Michal Krol
4392727702b1731a478de8806481416080d02af5862Michal Krol   /* Mark the register as declared.
4402727702b1731a478de8806481416080d02af5862Michal Krol    */
44122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   reg = MALLOC(sizeof(scan_register));
44222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   fill_scan_register1d(reg, TGSI_FILE_IMMEDIATE, ctx->num_imms);
44322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_insert(ctx->regs_decl, scan_register_key(reg), reg);
44451d219dbfe6852d348755574184639940af444e3Michal Krol   ctx->num_imms++;
4452727702b1731a478de8806481416080d02af5862Michal Krol
4462727702b1731a478de8806481416080d02af5862Michal Krol   /* Check data type validity.
4472727702b1731a478de8806481416080d02af5862Michal Krol    */
448ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol   if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
449ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol       imm->Immediate.DataType != TGSI_IMM_UINT32 &&
450ff56a12051a91c5c69db9afb85e4a3ebdb17ef96Michal Krol       imm->Immediate.DataType != TGSI_IMM_INT32) {
451ba91e79dad6a3666ae31b13c0c4b3b174f10b747Michal Krol      report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
4521e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol      return TRUE;
4532727702b1731a478de8806481416080d02af5862Michal Krol   }
4541e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
4551e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
4562727702b1731a478de8806481416080d02af5862Michal Krol}
4572727702b1731a478de8806481416080d02af5862Michal Krol
4583ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
4593ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusinstatic boolean
4603ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusiniter_property(
4613ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   struct tgsi_iterate_context *iter,
4623ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   struct tgsi_full_property *prop )
4633ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin{
46422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
4653ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
46622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY &&
46722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin       prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
468a00da63e6612607044e93f2900fba21bddfd0cadZack Rusin      ctx->implied_array_size = u_vertices_per_prim(prop->u[0].Data);
46922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
4703ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   return TRUE;
4713ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin}
4723ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin
4731e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolstatic boolean
4741e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krolepilog(
4751e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct tgsi_iterate_context *iter )
4762727702b1731a478de8806481416080d02af5862Michal Krol{
4771e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
4782727702b1731a478de8806481416080d02af5862Michal Krol
479e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   /* There must be an END instruction somewhere.
4802727702b1731a478de8806481416080d02af5862Michal Krol    */
481e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul   if (ctx->index_of_END == ~0) {
482e6a120fefea44078b3a8d4292d83671e6c41357fBrian Paul      report_error( ctx, "Missing END instruction" );
4832727702b1731a478de8806481416080d02af5862Michal Krol   }
4842727702b1731a478de8806481416080d02af5862Michal Krol
4852727702b1731a478de8806481416080d02af5862Michal Krol   /* Check if all declared registers were used.
4862727702b1731a478de8806481416080d02af5862Michal Krol    */
48722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   {
48822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      struct cso_hash_iter iter =
48922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         cso_hash_first_node(ctx->regs_decl);
49022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
491767d1472df68a777c51c406fa3f8d642c7cf58c0Michal Krol      while (!cso_hash_iter_is_null(iter)) {
49222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
49322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         if (!is_register_used(ctx, reg) && !is_ind_register_used(ctx, reg)) {
49422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin            report_warning( ctx, "%s[%u]: Register never used",
49522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin                            file_names[reg->file], reg->indices[0] );
4962727702b1731a478de8806481416080d02af5862Michal Krol         }
49722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin         iter = cso_hash_iter_next(iter);
4982727702b1731a478de8806481416080d02af5862Michal Krol      }
4992727702b1731a478de8806481416080d02af5862Michal Krol   }
5002727702b1731a478de8806481416080d02af5862Michal Krol
5012727702b1731a478de8806481416080d02af5862Michal Krol   /* Print totals, if any.
5022727702b1731a478de8806481416080d02af5862Michal Krol    */
5032727702b1731a478de8806481416080d02af5862Michal Krol   if (ctx->errors || ctx->warnings)
504eb5b16d278e0f7ee0121049e43dfee1d52f2b0f7José Fonseca      debug_printf( "%u errors, %u warnings\n", ctx->errors, ctx->warnings );
5051e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol
5061e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   return TRUE;
5072727702b1731a478de8806481416080d02af5862Michal Krol}
5082727702b1731a478de8806481416080d02af5862Michal Krol
50922370990f28987b361c6adf8e81c5a18184e88eaZack Rusinstatic void
51022370990f28987b361c6adf8e81c5a18184e88eaZack Rusinregs_hash_destroy(struct cso_hash *hash)
51122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin{
51222370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   struct cso_hash_iter iter = cso_hash_first_node(hash);
51322370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   while (!cso_hash_iter_is_null(iter)) {
51422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
51522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      iter = cso_hash_erase(hash, iter);
51622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin      free(reg);
51722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   }
51822370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   cso_hash_delete(hash);
51922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin}
52022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
5212727702b1731a478de8806481416080d02af5862Michal Krolboolean
5222727702b1731a478de8806481416080d02af5862Michal Kroltgsi_sanity_check(
523983b261e6d85020ae19418428d25f2e70f43d7ddKeith Whitwell   const struct tgsi_token *tokens )
5242727702b1731a478de8806481416080d02af5862Michal Krol{
5252727702b1731a478de8806481416080d02af5862Michal Krol   struct sanity_check_ctx ctx;
5262727702b1731a478de8806481416080d02af5862Michal Krol
5271e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.prolog = NULL;
5281e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_instruction = iter_instruction;
5291e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_declaration = iter_declaration;
5301e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.iterate_immediate = iter_immediate;
5313ff688ea299581e60caf5d6e1a464f68c717fe83Zack Rusin   ctx.iter.iterate_property = iter_property;
5321e5419fa3061386413a98b75d0908cb3e3c6894eMichal Krol   ctx.iter.epilog = epilog;
5332727702b1731a478de8806481416080d02af5862Michal Krol
53422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_decl = cso_hash_create();
53522370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_used = cso_hash_create();
53622370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.regs_ind_used = cso_hash_create();
53722370990f28987b361c6adf8e81c5a18184e88eaZack Rusin
5382727702b1731a478de8806481416080d02af5862Michal Krol   ctx.num_imms = 0;
5392727702b1731a478de8806481416080d02af5862Michal Krol   ctx.num_instructions = 0;
5402727702b1731a478de8806481416080d02af5862Michal Krol   ctx.index_of_END = ~0;
5412727702b1731a478de8806481416080d02af5862Michal Krol
5422727702b1731a478de8806481416080d02af5862Michal Krol   ctx.errors = 0;
5432727702b1731a478de8806481416080d02af5862Michal Krol   ctx.warnings = 0;
54422370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   ctx.implied_array_size = 0;
5452727702b1731a478de8806481416080d02af5862Michal Krol
546fef7f2b070ab797f78ebc210bb40a24685c6d4b7Michal Krol   if (!tgsi_iterate_shader( tokens, &ctx.iter ))
5472727702b1731a478de8806481416080d02af5862Michal Krol      return FALSE;
5482727702b1731a478de8806481416080d02af5862Michal Krol
54922370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_decl);
55022370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_used);
55122370990f28987b361c6adf8e81c5a18184e88eaZack Rusin   regs_hash_destroy(ctx.regs_ind_used);
552ff26c50153b3a348b35843262ceb27062ab37214José Fonseca   return ctx.errors == 0;
5532727702b1731a478de8806481416080d02af5862Michal Krol}
554