/*
 * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
 * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
 * Copyright © 2010 Intel Corporation
 * Copyright © 2011 Bryan Cain
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file glsl_to_tgsi.cpp
 *
 * Translate GLSL IR to TGSI.
 */

#include "st_glsl_to_tgsi.h"

#include "compiler/glsl/glsl_parser_extras.h"
#include "compiler/glsl/ir_optimization.h"
#include "compiler/glsl/program.h"

#include "main/errors.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
#include "main/shaderapi.h"
#include "main/shaderimage.h"
#include "program/prog_instruction.h"

#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "st_program.h"
#include "st_mesa_to_tgsi.h"
#include "st_format.h"
#include "st_glsl_to_tgsi_temprename.h"

#include "util/hash_table.h"
#include <algorithm>

#define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) |    \
                           (1 << PROGRAM_CONSTANT) |     \
                           (1 << PROGRAM_UNIFORM))

#define MAX_GLSL_TEXTURE_OFFSET 4

#ifndef NDEBUG
#include "util/u_atomic.h"
#include "util/simple_mtx.h"
#include <fstream>
#include <ios>

/* Prepare to make it possible to specify log file */
static std::ofstream stats_log;

/* Helper function to check whether we want to write some statistics
 * of the shader conversion.
 */

static simple_mtx_t print_stats_mutex = _SIMPLE_MTX_INITIALIZER_NP;

static inline bool print_stats_enabled ()
{
   static int stats_enabled = 0;

   if (!stats_enabled) {
      simple_mtx_lock(&print_stats_mutex);
      if (!stats_enabled) {
	 const char *stats_filename = getenv("GLSL_TO_TGSI_PRINT_STATS");
	 if (stats_filename) {
	    bool write_header = std::ifstream(stats_filename).fail();
	    stats_log.open(stats_filename, std::ios_base::out | std::ios_base::app);
	    stats_enabled = stats_log.good() ? 1 : -1;
	    if (write_header)
	       stats_log << "arrays,temps,temps in arrays,total,instructions\n";
	 } else {
	    stats_enabled = -1;
	 }
      }
      simple_mtx_unlock(&print_stats_mutex);
   }
   return stats_enabled > 0;
}
#define PRINT_STATS(X) if (print_stats_enabled()) do { X; } while (false);
#else
#define PRINT_STATS(X)
#endif


static unsigned is_precise(const ir_variable *ir)
{
   if (!ir)
      return 0;
   return ir->data.precise || ir->data.invariant;
}

class variable_storage {
   DECLARE_RZALLOC_CXX_OPERATORS(variable_storage)

public:
   variable_storage(ir_variable *var, gl_register_file file, int index,
                    unsigned array_id = 0)
      : file(file), index(index), component(0), var(var), array_id(array_id)
   {
      assert(file != PROGRAM_ARRAY || array_id != 0);
   }

   gl_register_file file;
   int index;

   /* Explicit component location. This is given in terms of the GLSL-style
    * swizzles where each double is a single component, i.e. for 64-bit types
    * it can only be 0 or 1.
    */
   int component;
   ir_variable *var; /* variable that maps to this, if any */
   unsigned array_id;
};

class immediate_storage : public exec_node {
public:
   immediate_storage(gl_constant_value *values, int size32, GLenum type)
   {
      memcpy(this->values, values, size32 * sizeof(gl_constant_value));
      this->size32 = size32;
      this->type = type;
   }

   /* doubles are stored across 2 gl_constant_values */
   gl_constant_value values[4];
   int size32; /**< Number of 32-bit components (1-4) */
   GLenum type; /**< GL_DOUBLE, GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */
};

static const st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
static const st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);

struct inout_decl {
   unsigned mesa_index;
   unsigned array_id; /* TGSI ArrayID; 1-based: 0 means not an array */
   unsigned size;
   unsigned interp_loc;
   unsigned gs_out_streams;
   enum glsl_interp_mode interp;
   enum glsl_base_type base_type;
   ubyte usage_mask; /* GLSL-style usage-mask,  i.e. single bit per double */
   bool invariant;
};

static struct inout_decl *
find_inout_array(struct inout_decl *decls, unsigned count, unsigned array_id)
{
   assert(array_id != 0);

   for (unsigned i = 0; i < count; i++) {
      struct inout_decl *decl = &decls[i];

      if (array_id == decl->array_id) {
         return decl;
      }
   }

   return NULL;
}

static enum glsl_base_type
find_array_type(struct inout_decl *decls, unsigned count, unsigned array_id)
{
   if (!array_id)
      return GLSL_TYPE_ERROR;
   struct inout_decl *decl = find_inout_array(decls, count, array_id);
   if (decl)
      return decl->base_type;
   return GLSL_TYPE_ERROR;
}

struct hwatomic_decl {
   unsigned location;
   unsigned binding;
   unsigned size;
   unsigned array_id;
};

struct glsl_to_tgsi_visitor : public ir_visitor {
public:
   glsl_to_tgsi_visitor();
   ~glsl_to_tgsi_visitor();

   struct gl_context *ctx;
   struct gl_program *prog;
   struct gl_shader_program *shader_program;
   struct gl_linked_shader *shader;
   struct gl_shader_compiler_options *options;

   int next_temp;

   unsigned *array_sizes;
   unsigned max_num_arrays;
   unsigned next_array;

   struct inout_decl inputs[4 * PIPE_MAX_SHADER_INPUTS];
   unsigned num_inputs;
   unsigned num_input_arrays;
   struct inout_decl outputs[4 * PIPE_MAX_SHADER_OUTPUTS];
   unsigned num_outputs;
   unsigned num_output_arrays;

   struct hwatomic_decl atomic_info[PIPE_MAX_HW_ATOMIC_BUFFERS];
   unsigned num_atomics;
   unsigned num_atomic_arrays;
   int num_address_regs;
   uint32_t samplers_used;
   glsl_base_type sampler_types[PIPE_MAX_SAMPLERS];
   enum tgsi_texture_type sampler_targets[PIPE_MAX_SAMPLERS];
   int images_used;
   enum tgsi_texture_type image_targets[PIPE_MAX_SHADER_IMAGES];
   enum pipe_format image_formats[PIPE_MAX_SHADER_IMAGES];
   bool image_wr[PIPE_MAX_SHADER_IMAGES];
   bool indirect_addr_consts;
   int wpos_transform_const;

   bool native_integers;
   bool have_sqrt;
   bool have_fma;
   bool use_shared_memory;
   bool has_tex_txf_lz;
   bool precise;
   bool need_uarl;
   bool tg4_component_in_swizzle;

   variable_storage *find_variable_storage(ir_variable *var);

   int add_constant(gl_register_file file, gl_constant_value values[8],
                    int size, GLenum datatype, uint16_t *swizzle_out);

   st_src_reg get_temp(const glsl_type *type);
   void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr);

   st_src_reg st_src_reg_for_double(double val);
   st_src_reg st_src_reg_for_float(float val);
   st_src_reg st_src_reg_for_int(int val);
   st_src_reg st_src_reg_for_int64(int64_t val);
   st_src_reg st_src_reg_for_type(enum glsl_base_type type, int val);

   /**
    * \name Visit methods
    *
    * As typical for the visitor pattern, there must be one \c visit method for
    * each concrete subclass of \c ir_instruction.  Virtual base classes within
    * the hierarchy should not have \c visit methods.
    */
   /*@{*/
   virtual void visit(ir_variable *);
   virtual void visit(ir_loop *);
   virtual void visit(ir_loop_jump *);
   virtual void visit(ir_function_signature *);
   virtual void visit(ir_function *);
   virtual void visit(ir_expression *);
   virtual void visit(ir_swizzle *);
   virtual void visit(ir_dereference_variable  *);
   virtual void visit(ir_dereference_array *);
   virtual void visit(ir_dereference_record *);
   virtual void visit(ir_assignment *);
   virtual void visit(ir_constant *);
   virtual void visit(ir_call *);
   virtual void visit(ir_return *);
   virtual void visit(ir_discard *);
   virtual void visit(ir_demote *);
   virtual void visit(ir_texture *);
   virtual void visit(ir_if *);
   virtual void visit(ir_emit_vertex *);
   virtual void visit(ir_end_primitive *);
   virtual void visit(ir_barrier *);
   /*@}*/

   void visit_expression(ir_expression *, st_src_reg *) ATTRIBUTE_NOINLINE;

   void visit_atomic_counter_intrinsic(ir_call *);
   void visit_ssbo_intrinsic(ir_call *);
   void visit_membar_intrinsic(ir_call *);
   void visit_shared_intrinsic(ir_call *);
   void visit_image_intrinsic(ir_call *);
   void visit_generic_intrinsic(ir_call *, enum tgsi_opcode op);

   st_src_reg result;

   /** List of variable_storage */
   struct hash_table *variables;

   /** List of immediate_storage */
   exec_list immediates;
   unsigned num_immediates;

   /** List of glsl_to_tgsi_instruction */
   exec_list instructions;

   glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, enum tgsi_opcode op,
                                      st_dst_reg dst = undef_dst,
                                      st_src_reg src0 = undef_src,
                                      st_src_reg src1 = undef_src,
                                      st_src_reg src2 = undef_src,
                                      st_src_reg src3 = undef_src);

   glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, enum tgsi_opcode op,
                                      st_dst_reg dst, st_dst_reg dst1,
                                      st_src_reg src0 = undef_src,
                                      st_src_reg src1 = undef_src,
                                      st_src_reg src2 = undef_src,
                                      st_src_reg src3 = undef_src);

   enum tgsi_opcode get_opcode(enum tgsi_opcode op,
                               st_dst_reg dst,
                               st_src_reg src0, st_src_reg src1);

   /**
    * Emit the correct dot-product instruction for the type of arguments
    */
   glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir,
                                     st_dst_reg dst,
                                     st_src_reg src0,
                                     st_src_reg src1,
                                     unsigned elements);

   void emit_scalar(ir_instruction *ir, enum tgsi_opcode op,
                    st_dst_reg dst, st_src_reg src0);

   void emit_scalar(ir_instruction *ir, enum tgsi_opcode op,
                    st_dst_reg dst, st_src_reg src0, st_src_reg src1);

   void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);

   void get_deref_offsets(ir_dereference *ir,
                          unsigned *array_size,
                          unsigned *base,
                          uint16_t *index,
                          st_src_reg *reladdr,
                          bool opaque);
  void calc_deref_offsets(ir_dereference *tail,
                          unsigned *array_elements,
                          uint16_t *index,
                          st_src_reg *indirect,
                          unsigned *location);
   st_src_reg canonicalize_gather_offset(st_src_reg offset);
   bool handle_bound_deref(ir_dereference *ir);

   bool try_emit_mad(ir_expression *ir,
              int mul_operand);
   bool try_emit_mad_for_and_not(ir_expression *ir,
              int mul_operand);

   void emit_swz(ir_expression *ir);

   bool process_move_condition(ir_rvalue *ir);

   void simplify_cmp(void);

   void rename_temp_registers(struct rename_reg_pair *renames);
   void get_first_temp_read(int *first_reads);
   void get_first_temp_write(int *first_writes);
   void get_last_temp_read_first_temp_write(int *last_reads, int *first_writes);
   void get_last_temp_write(int *last_writes);

   void copy_propagate(void);
   int eliminate_dead_code(void);

   void split_arrays(void);
   void merge_two_dsts(void);
   void merge_registers(void);
   void renumber_registers(void);

   void emit_block_mov(ir_assignment *ir, const struct glsl_type *type,
                       st_dst_reg *l, st_src_reg *r,
                       st_src_reg *cond, bool cond_swap);

   void print_stats();

   void *mem_ctx;
};

static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X,
                                           GLSL_TYPE_FLOAT, 0);
static st_dst_reg address_reg2 = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X,
                                            GLSL_TYPE_FLOAT, 1);
static st_dst_reg sampler_reladdr = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X,
                                               GLSL_TYPE_FLOAT, 2);

static void
fail_link(struct gl_shader_program *prog, const char *fmt, ...)
   PRINTFLIKE(2, 3);

static void
fail_link(struct gl_shader_program *prog, const char *fmt, ...)
{
   va_list args;
   va_start(args, fmt);
   ralloc_vasprintf_append(&prog->data->InfoLog, fmt, args);
   va_end(args);

   prog->data->LinkStatus = LINKING_FAILURE;
}

int
swizzle_for_size(int size)
{
   static const int size_swizzles[4] = {
      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
   };

   assert((size >= 1) && (size <= 4));
   return size_swizzles[size - 1];
}


glsl_to_tgsi_instruction *
glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, enum tgsi_opcode op,
                               st_dst_reg dst, st_dst_reg dst1,
                               st_src_reg src0, st_src_reg src1,
                               st_src_reg src2, st_src_reg src3)
{
   glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
   int num_reladdr = 0, i, j;
   bool dst_is_64bit[2];

   op = get_opcode(op, dst, src0, src1);

   /* If we have to do relative addressing, we want to load the ARL
    * reg directly for one of the regs, and preload the other reladdr
    * sources into temps.
    */
   num_reladdr += dst.reladdr != NULL || dst.reladdr2;
   assert(!dst1.reladdr); /* should be lowered in earlier passes */
   num_reladdr += src0.reladdr != NULL || src0.reladdr2 != NULL;
   num_reladdr += src1.reladdr != NULL || src1.reladdr2 != NULL;
   num_reladdr += src2.reladdr != NULL || src2.reladdr2 != NULL;
   num_reladdr += src3.reladdr != NULL || src3.reladdr2 != NULL;

   reladdr_to_temp(ir, &src3, &num_reladdr);
   reladdr_to_temp(ir, &src2, &num_reladdr);
   reladdr_to_temp(ir, &src1, &num_reladdr);
   reladdr_to_temp(ir, &src0, &num_reladdr);

   if (dst.reladdr || dst.reladdr2) {
      if (dst.reladdr)
         emit_arl(ir, address_reg, *dst.reladdr);
      if (dst.reladdr2)
         emit_arl(ir, address_reg2, *dst.reladdr2);
      num_reladdr--;
   }

   assert(num_reladdr == 0);

   /* inst->op has only 8 bits. */
   STATIC_ASSERT(TGSI_OPCODE_LAST <= 255);

   inst->op = op;
   inst->precise = this->precise;
   inst->info = tgsi_get_opcode_info(op);
   inst->dst[0] = dst;
   inst->dst[1] = dst1;
   inst->src[0] = src0;
   inst->src[1] = src1;
   inst->src[2] = src2;
   inst->src[3] = src3;
   inst->is_64bit_expanded = false;
   inst->ir = ir;
   inst->dead_mask = 0;
   inst->tex_offsets = NULL;
   inst->tex_offset_num_offset = 0;
   inst->saturate = 0;
   inst->tex_shadow = 0;
   /* default to float, for paths where this is not initialized
    * (since 0==UINT which is likely wrong):
    */
   inst->tex_type = GLSL_TYPE_FLOAT;

   /* Update indirect addressing status used by TGSI */
   if (dst.reladdr || dst.reladdr2) {
      switch (dst.file) {
      case PROGRAM_STATE_VAR:
      case PROGRAM_CONSTANT:
      case PROGRAM_UNIFORM:
         this->indirect_addr_consts = true;
         break;
      case PROGRAM_IMMEDIATE:
         assert(!"immediates should not have indirect addressing");
         break;
      default:
         break;
      }
   }
   else {
      for (i = 0; i < 4; i++) {
         if (inst->src[i].reladdr) {
            switch (inst->src[i].file) {
            case PROGRAM_STATE_VAR:
            case PROGRAM_CONSTANT:
            case PROGRAM_UNIFORM:
               this->indirect_addr_consts = true;
               break;
            case PROGRAM_IMMEDIATE:
               assert(!"immediates should not have indirect addressing");
               break;
            default:
               break;
            }
         }
      }
   }

   /*
    * This section contains the double processing.
    * GLSL just represents doubles as single channel values,
    * however most HW and TGSI represent doubles as pairs of register channels.
    *
    * so we have to fixup destination writemask/index and src swizzle/indexes.
    * dest writemasks need to translate from single channel write mask
    * to a dual-channel writemask, but also need to modify the index,
    * if we are touching the Z,W fields in the pre-translated writemask.
    *
    * src channels have similiar index modifications along with swizzle
    * changes to we pick the XY, ZW pairs from the correct index.
    *
    * GLSL [0].x -> TGSI [0].xy
    * GLSL [0].y -> TGSI [0].zw
    * GLSL [0].z -> TGSI [1].xy
    * GLSL [0].w -> TGSI [1].zw
    */
   for (j = 0; j < 2; j++) {
      dst_is_64bit[j] = glsl_base_type_is_64bit(inst->dst[j].type);
      if (!dst_is_64bit[j] && inst->dst[j].file == PROGRAM_OUTPUT &&
          inst->dst[j].type == GLSL_TYPE_ARRAY) {
         enum glsl_base_type type = find_array_type(this->outputs,
                                                    this->num_outputs,
                                                    inst->dst[j].array_id);
         if (glsl_base_type_is_64bit(type))
            dst_is_64bit[j] = true;
      }
   }

   if (dst_is_64bit[0] || dst_is_64bit[1] ||
       glsl_base_type_is_64bit(inst->src[0].type)) {
      glsl_to_tgsi_instruction *dinst = NULL;
      int initial_src_swz[4], initial_src_idx[4];
      int initial_dst_idx[2], initial_dst_writemask[2];
      /* select the writemask for dst0 or dst1 */
      unsigned writemask = inst->dst[1].file == PROGRAM_UNDEFINED
         ? inst->dst[0].writemask : inst->dst[1].writemask;

      /* copy out the writemask, index and swizzles for all src/dsts. */
      for (j = 0; j < 2; j++) {
         initial_dst_writemask[j] = inst->dst[j].writemask;
         initial_dst_idx[j] = inst->dst[j].index;
      }

      for (j = 0; j < 4; j++) {
         initial_src_swz[j] = inst->src[j].swizzle;
         initial_src_idx[j] = inst->src[j].index;
      }

      /*
       * scan all the components in the dst writemask
       * generate an instruction for each of them if required.
       */
      st_src_reg addr;
      while (writemask) {

         int i = u_bit_scan(&writemask);

         /* before emitting the instruction, see if we have to adjust
          * load / store address */
         if (i > 1 && (inst->op == TGSI_OPCODE_LOAD ||
                       inst->op == TGSI_OPCODE_STORE) &&
             addr.file == PROGRAM_UNDEFINED) {
            /* We have to advance the buffer address by 16 */
            addr = get_temp(glsl_type::uint_type);
            emit_asm(ir, TGSI_OPCODE_UADD, st_dst_reg(addr),
                     inst->src[0], st_src_reg_for_int(16));
         }

         /* first time use previous instruction */
         if (dinst == NULL) {
            dinst = inst;
         } else {
            /* create a new instructions for subsequent attempts */
            dinst = new(mem_ctx) glsl_to_tgsi_instruction();
            *dinst = *inst;
            dinst->next = NULL;
            dinst->prev = NULL;
         }
         this->instructions.push_tail(dinst);
         dinst->is_64bit_expanded = true;

         /* modify the destination if we are splitting */
         for (j = 0; j < 2; j++) {
            if (dst_is_64bit[j]) {
               dinst->dst[j].writemask = (i & 1) ? WRITEMASK_ZW : WRITEMASK_XY;
               dinst->dst[j].index = initial_dst_idx[j];
               if (i > 1) {
                  if (dinst->op == TGSI_OPCODE_LOAD ||
                      dinst->op == TGSI_OPCODE_STORE)
                     dinst->src[0] = addr;
                  if (dinst->op != TGSI_OPCODE_STORE)
                     dinst->dst[j].index++;
               }
            } else {
               /* if we aren't writing to a double, just get the bit of the
                * initial writemask for this channel
                */
               dinst->dst[j].writemask = initial_dst_writemask[j] & (1 << i);
            }
         }

         /* modify the src registers */
         for (j = 0; j < 4; j++) {
            int swz = GET_SWZ(initial_src_swz[j], i);

            if (glsl_base_type_is_64bit(dinst->src[j].type)) {
               dinst->src[j].index = initial_src_idx[j];
               if (swz > 1) {
                  dinst->src[j].double_reg2 = true;
                  dinst->src[j].index++;
               }

               if (swz & 1)
                  dinst->src[j].swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W,
                                                        SWIZZLE_Z, SWIZZLE_W);
               else
                  dinst->src[j].swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
                                                        SWIZZLE_X, SWIZZLE_Y);

            } else {
               /* some opcodes are special case in what they use as sources
                * - [FUI]2D/[UI]2I64 is a float/[u]int src0, (D)LDEXP is
                * integer src1
                */
               if (op == TGSI_OPCODE_F2D || op == TGSI_OPCODE_U2D ||
                   op == TGSI_OPCODE_I2D ||
                   op == TGSI_OPCODE_I2I64 || op == TGSI_OPCODE_U2I64 ||
                   op == TGSI_OPCODE_DLDEXP || op == TGSI_OPCODE_LDEXP ||
                   (op == TGSI_OPCODE_UCMP && dst_is_64bit[0])) {
                  dinst->src[j].swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
               }
            }
         }
      }
      inst = dinst;
   } else {
      this->instructions.push_tail(inst);
   }


   return inst;
}

glsl_to_tgsi_instruction *
glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, enum tgsi_opcode op,
                               st_dst_reg dst,
                               st_src_reg src0, st_src_reg src1,
                               st_src_reg src2, st_src_reg src3)
{
   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3);
}

/**
 * Determines whether to use an integer, unsigned integer, or float opcode
 * based on the operands and input opcode, then emits the result.
 */
enum tgsi_opcode
glsl_to_tgsi_visitor::get_opcode(enum tgsi_opcode op,
                                 st_dst_reg dst,
                                 st_src_reg src0, st_src_reg src1)
{
   enum glsl_base_type type = GLSL_TYPE_FLOAT;

   if (op == TGSI_OPCODE_MOV)
       return op;

   assert(src0.type != GLSL_TYPE_ARRAY);
   assert(src0.type != GLSL_TYPE_STRUCT);
   assert(src1.type != GLSL_TYPE_ARRAY);
   assert(src1.type != GLSL_TYPE_STRUCT);

   if (is_resource_instruction(op))
      type = src1.type;
   else if (src0.type == GLSL_TYPE_INT64 || src1.type == GLSL_TYPE_INT64)
      type = GLSL_TYPE_INT64;
   else if (src0.type == GLSL_TYPE_UINT64 || src1.type == GLSL_TYPE_UINT64)
      type = GLSL_TYPE_UINT64;
   else if (src0.type == GLSL_TYPE_DOUBLE || src1.type == GLSL_TYPE_DOUBLE)
      type = GLSL_TYPE_DOUBLE;
   else if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT)
      type = GLSL_TYPE_FLOAT;
   else if (native_integers)
      type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type;

#define case7(c, f, i, u, d, i64, ui64)             \
   case TGSI_OPCODE_##c: \
      if (type == GLSL_TYPE_UINT64)           \
         op = TGSI_OPCODE_##ui64; \
      else if (type == GLSL_TYPE_INT64)       \
         op = TGSI_OPCODE_##i64; \
      else if (type == GLSL_TYPE_DOUBLE)       \
         op = TGSI_OPCODE_##d; \
      else if (type == GLSL_TYPE_INT)       \
         op = TGSI_OPCODE_##i; \
      else if (type == GLSL_TYPE_UINT) \
         op = TGSI_OPCODE_##u; \
      else \
         op = TGSI_OPCODE_##f; \
      break;

#define casecomp(c, f, i, u, d, i64, ui64)           \
   case TGSI_OPCODE_##c: \
      if (type == GLSL_TYPE_INT64)             \
         op = TGSI_OPCODE_##i64; \
      else if (type == GLSL_TYPE_UINT64)        \
         op = TGSI_OPCODE_##ui64; \
      else if (type == GLSL_TYPE_DOUBLE)       \
         op = TGSI_OPCODE_##d; \
      else if (type == GLSL_TYPE_INT || type == GLSL_TYPE_SUBROUTINE)       \
         op = TGSI_OPCODE_##i; \
      else if (type == GLSL_TYPE_UINT) \
         op = TGSI_OPCODE_##u; \
      else if (native_integers) \
         op = TGSI_OPCODE_##f; \
      else \
         op = TGSI_OPCODE_##c; \
      break;

   switch (op) {
      /* Some instructions are initially selected without considering the type.
       * This fixes the type:
       *
       *    INIT     FLOAT SINT     UINT     DOUBLE   SINT64   UINT64
       */
      case7(ADD,     ADD,  UADD,    UADD,    DADD,    U64ADD,  U64ADD);
      case7(CEIL,    CEIL, LAST,    LAST,    DCEIL,   LAST,    LAST);
      case7(DIV,     DIV,  IDIV,    UDIV,    DDIV,    I64DIV,  U64DIV);
      case7(FMA,     FMA,  UMAD,    UMAD,    DFMA,    LAST,    LAST);
      case7(FLR,     FLR,  LAST,    LAST,    DFLR,    LAST,    LAST);
      case7(FRC,     FRC,  LAST,    LAST,    DFRAC,   LAST,    LAST);
      case7(MUL,     MUL,  UMUL,    UMUL,    DMUL,    U64MUL,  U64MUL);
      case7(MAD,     MAD,  UMAD,    UMAD,    DMAD,    LAST,    LAST);
      case7(MAX,     MAX,  IMAX,    UMAX,    DMAX,    I64MAX,  U64MAX);
      case7(MIN,     MIN,  IMIN,    UMIN,    DMIN,    I64MIN,  U64MIN);
      case7(RCP,     RCP,  LAST,    LAST,    DRCP,    LAST,    LAST);
      case7(ROUND,   ROUND,LAST,    LAST,    DROUND,  LAST,    LAST);
      case7(RSQ,     RSQ,  LAST,    LAST,    DRSQ,    LAST,    LAST);
      case7(SQRT,    SQRT, LAST,    LAST,    DSQRT,   LAST,    LAST);
      case7(SSG,     SSG,  ISSG,    ISSG,    DSSG,    I64SSG,  I64SSG);
      case7(TRUNC,   TRUNC,LAST,    LAST,    DTRUNC,  LAST,    LAST);

      case7(MOD,     LAST, MOD,     UMOD,    LAST,    I64MOD,  U64MOD);
      case7(SHL,     LAST, SHL,     SHL,     LAST,    U64SHL,  U64SHL);
      case7(IBFE,    LAST, IBFE,    UBFE,    LAST,    LAST,    LAST);
      case7(IMSB,    LAST, IMSB,    UMSB,    LAST,    LAST,    LAST);
      case7(IMUL_HI, LAST, IMUL_HI, UMUL_HI, LAST,    LAST,    LAST);
      case7(ISHR,    LAST, ISHR,    USHR,    LAST,    I64SHR,  U64SHR);
      case7(ATOMIMAX,LAST, ATOMIMAX,ATOMUMAX,LAST,    LAST,    LAST);
      case7(ATOMIMIN,LAST, ATOMIMIN,ATOMUMIN,LAST,    LAST,    LAST);
      case7(ATOMUADD,ATOMFADD,ATOMUADD,ATOMUADD,LAST, LAST,    LAST);

      casecomp(SEQ, FSEQ, USEQ, USEQ, DSEQ, U64SEQ, U64SEQ);
      casecomp(SNE, FSNE, USNE, USNE, DSNE, U64SNE, U64SNE);
      casecomp(SGE, FSGE, ISGE, USGE, DSGE, I64SGE, U64SGE);
      casecomp(SLT, FSLT, ISLT, USLT, DSLT, I64SLT, U64SLT);

      default:
         break;
   }

   assert(op != TGSI_OPCODE_LAST);
   return op;
}

glsl_to_tgsi_instruction *
glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir,
                              st_dst_reg dst, st_src_reg src0, st_src_reg src1,
                              unsigned elements)
{
   static const enum tgsi_opcode dot_opcodes[] = {
      TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4
   };

   return emit_asm(ir, dot_opcodes[elements - 2], dst, src0, src1);
}

/**
 * Emits TGSI scalar opcodes to produce unique answers across channels.
 *
 * Some TGSI opcodes are scalar-only, like ARB_fp/vp.  The src X
 * channel determines the result across all channels.  So to do a vec4
 * of this operation, we want to emit a scalar per source channel used
 * to produce dest channels.
 */
void
glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, enum tgsi_opcode op,
                                  st_dst_reg dst,
                                  st_src_reg orig_src0, st_src_reg orig_src1)
{
   int i, j;
   int done_mask = ~dst.writemask;

   /* TGSI RCP is a scalar operation splatting results to all channels,
    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
    * dst channels.
    */
   for (i = 0; i < 4; i++) {
      GLuint this_mask = (1 << i);
      st_src_reg src0 = orig_src0;
      st_src_reg src1 = orig_src1;

      if (done_mask & this_mask)
         continue;

      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
      for (j = i + 1; j < 4; j++) {
         /* If there is another enabled component in the destination that is
          * derived from the same inputs, generate its value on this pass as
          * well.
          */
         if (!(done_mask & (1 << j)) &&
             GET_SWZ(src0.swizzle, j) == src0_swiz &&
             GET_SWZ(src1.swizzle, j) == src1_swiz) {
            this_mask |= (1 << j);
         }
      }
      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
                                   src0_swiz, src0_swiz);
      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
                                   src1_swiz, src1_swiz);

      dst.writemask = this_mask;
      emit_asm(ir, op, dst, src0, src1);
      done_mask |= this_mask;
   }
}

void
glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, enum tgsi_opcode op,
                                  st_dst_reg dst, st_src_reg src0)
{
   st_src_reg undef = undef_src;

   undef.swizzle = SWIZZLE_XXXX;

   emit_scalar(ir, op, dst, src0, undef);
}

void
glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
                               st_dst_reg dst, st_src_reg src0)
{
   enum tgsi_opcode op = TGSI_OPCODE_ARL;

   if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) {
      if (!this->need_uarl && src0.is_legal_tgsi_address_operand())
         return;

      op = TGSI_OPCODE_UARL;
   }

   assert(dst.file == PROGRAM_ADDRESS);
   if (dst.index >= this->num_address_regs)
      this->num_address_regs = dst.index + 1;

   emit_asm(NULL, op, dst, src0);
}

int
glsl_to_tgsi_visitor::add_constant(gl_register_file file,
                                   gl_constant_value values[8], int size,
                                   GLenum datatype,
                                   uint16_t *swizzle_out)
{
   if (file == PROGRAM_CONSTANT) {
      GLuint swizzle = swizzle_out ? *swizzle_out : 0;
      int result = _mesa_add_typed_unnamed_constant(this->prog->Parameters,
                                                    values, size, datatype,
                                                    &swizzle);
      if (swizzle_out)
         *swizzle_out = swizzle;
      return result;
   }

   assert(file == PROGRAM_IMMEDIATE);

   int index = 0;
   immediate_storage *entry;
   int size32 = size * ((datatype == GL_DOUBLE ||
                         datatype == GL_INT64_ARB ||
                         datatype == GL_UNSIGNED_INT64_ARB) ? 2 : 1);
   int i;

   /* Search immediate storage to see if we already have an identical
    * immediate that we can use instead of adding a duplicate entry.
    */
   foreach_in_list(immediate_storage, entry, &this->immediates) {
      immediate_storage *tmp = entry;

      for (i = 0; i * 4 < size32; i++) {
         int slot_size = MIN2(size32 - (i * 4), 4);
         if (tmp->type != datatype || tmp->size32 != slot_size)
            break;
         if (memcmp(tmp->values, &values[i * 4],
                    slot_size * sizeof(gl_constant_value)))
            break;

         /* Everything matches, keep going until the full size is matched */
         tmp = (immediate_storage *)tmp->next;
      }

      /* The full value matched */
      if (i * 4 >= size32)
         return index;

      index++;
   }

   for (i = 0; i * 4 < size32; i++) {
      int slot_size = MIN2(size32 - (i * 4), 4);
      /* Add this immediate to the list. */
      entry = new(mem_ctx) immediate_storage(&values[i * 4],
                                             slot_size, datatype);
      this->immediates.push_tail(entry);
      this->num_immediates++;
   }
   return index;
}

st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_float(float val)
{
   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT);
   union gl_constant_value uval;

   uval.f = val;
   src.index = add_constant(src.file, &uval, 1, GL_FLOAT, &src.swizzle);

   return src;
}

st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_double(double val)
{
   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_DOUBLE);
   union gl_constant_value uval[2];

   memcpy(uval, &val, sizeof(uval));
   src.index = add_constant(src.file, uval, 1, GL_DOUBLE, &src.swizzle);
   src.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_X, SWIZZLE_Y);
   return src;
}

st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_int(int val)
{
   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT);
   union gl_constant_value uval;

   assert(native_integers);

   uval.i = val;
   src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle);

   return src;
}

st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_int64(int64_t val)
{
   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT64);
   union gl_constant_value uval[2];

   memcpy(uval, &val, sizeof(uval));
   src.index = add_constant(src.file, uval, 1, GL_DOUBLE, &src.swizzle);
   src.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_X, SWIZZLE_Y);

   return src;
}

st_src_reg
glsl_to_tgsi_visitor::st_src_reg_for_type(enum glsl_base_type type, int val)
{
   if (native_integers)
      return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) :
                                       st_src_reg_for_int(val);
   else
      return st_src_reg_for_float(val);
}

static int
attrib_type_size(const struct glsl_type *type, bool is_vs_input)
{
   return type->count_attribute_slots(is_vs_input);
}

static int
type_size(const struct glsl_type *type)
{
   return type->count_attribute_slots(false);
}

static void
add_buffer_to_load_and_stores(glsl_to_tgsi_instruction *inst, st_src_reg *buf,
                              exec_list *instructions, ir_constant *access)
{
   /**
    * emit_asm() might have actually split the op into pieces, e.g. for
    * double stores. We have to go back and fix up all the generated ops.
    */
   enum tgsi_opcode op = inst->op;
   do {
      inst->resource = *buf;
      if (access)
         inst->buffer_access = access->value.u[0];

      if (inst == instructions->get_head_raw())
         break;
      inst = (glsl_to_tgsi_instruction *)inst->get_prev();

      if (inst->op == TGSI_OPCODE_UADD) {
         if (inst == instructions->get_head_raw())
            break;
         inst = (glsl_to_tgsi_instruction *)inst->get_prev();
      }
   } while (inst->op == op && inst->resource.file == PROGRAM_UNDEFINED);
}

/**
 * If the given GLSL type is an array or matrix or a structure containing
 * an array/matrix member, return true.  Else return false.
 *
 * This is used to determine which kind of temp storage (PROGRAM_TEMPORARY
 * or PROGRAM_ARRAY) should be used for variables of this type.  Anytime
 * we have an array that might be indexed with a variable, we need to use
 * the later storage type.
 */
static bool
type_has_array_or_matrix(const glsl_type *type)
{
   if (type->is_array() || type->is_matrix())
      return true;

   if (type->is_struct()) {
      for (unsigned i = 0; i < type->length; i++) {
         if (type_has_array_or_matrix(type->fields.structure[i].type)) {
            return true;
         }
      }
   }

   return false;
}


/**
 * In the initial pass of codegen, we assign temporary numbers to
 * intermediate results.  (not SSA -- variable assignments will reuse
 * storage).
 */
st_src_reg
glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
{
   st_src_reg src;

   src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT;
   src.reladdr = NULL;
   src.negate = 0;
   src.abs = 0;

   if (!options->EmitNoIndirectTemp && type_has_array_or_matrix(type)) {
      if (next_array >= max_num_arrays) {
         max_num_arrays += 32;
         array_sizes = (unsigned*)
            realloc(array_sizes, sizeof(array_sizes[0]) * max_num_arrays);
      }

      src.file = PROGRAM_ARRAY;
      src.index = 0;
      src.array_id = next_array + 1;
      array_sizes[next_array] = type_size(type);
      ++next_array;

   } else {
      src.file = PROGRAM_TEMPORARY;
      src.index = next_temp;
      next_temp += type_size(type);
   }

   if (type->is_array() || type->is_struct()) {
      src.swizzle = SWIZZLE_NOOP;
   } else {
      src.swizzle = swizzle_for_size(type->vector_elements);
   }

   return src;
}

variable_storage *
glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var)
{
   struct hash_entry *entry;

   entry = _mesa_hash_table_search(this->variables, var);
   if (!entry)
      return NULL;

   return (variable_storage *)entry->data;
}

void
glsl_to_tgsi_visitor::visit(ir_variable *ir)
{
   if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
      unsigned int i;
      const ir_state_slot *const slots = ir->get_state_slots();
      assert(slots != NULL);

      /* Check if this statevar's setup in the STATE file exactly
       * matches how we'll want to reference it as a
       * struct/array/whatever.  If not, then we need to move it into
       * temporary storage and hope that it'll get copy-propagated
       * out.
       */
      for (i = 0; i < ir->get_num_state_slots(); i++) {
         if (slots[i].swizzle != SWIZZLE_XYZW) {
            break;
         }
      }

      variable_storage *storage;
      st_dst_reg dst;
      if (i == ir->get_num_state_slots()) {
         /* We'll set the index later. */
         storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1);

         _mesa_hash_table_insert(this->variables, ir, storage);

         dst = undef_dst;
      } else {
         /* The variable_storage constructor allocates slots based on the size
          * of the type.  However, this had better match the number of state
          * elements that we're going to copy into the new temporary.
          */
         assert((int) ir->get_num_state_slots() == type_size(ir->type));

         dst = st_dst_reg(get_temp(ir->type));

         storage = new(mem_ctx) variable_storage(ir, dst.file, dst.index,
                                                 dst.array_id);

         _mesa_hash_table_insert(this->variables, ir, storage);
      }


      for (unsigned int i = 0; i < ir->get_num_state_slots(); i++) {
         int index = _mesa_add_state_reference(this->prog->Parameters,
                                               slots[i].tokens);

         if (storage->file == PROGRAM_STATE_VAR) {
            if (storage->index == -1) {
               storage->index = index;
            } else {
               assert(index == storage->index + (int)i);
            }
         } else {
            /* We use GLSL_TYPE_FLOAT here regardless of the actual type of
             * the data being moved since MOV does not care about the type of
             * data it is moving, and we don't want to declare registers with
             * array or struct types.
             */
            st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT);
            src.swizzle = slots[i].swizzle;
            emit_asm(ir, TGSI_OPCODE_MOV, dst, src);
            /* even a float takes up a whole vec4 reg in a struct/array. */
            dst.index++;
         }
      }

      if (storage->file == PROGRAM_TEMPORARY &&
          dst.index != storage->index + (int) ir->get_num_state_slots()) {
         fail_link(this->shader_program,
                  "failed to load builtin uniform `%s'  (%d/%d regs loaded)\n",
                  ir->name, dst.index - storage->index,
                  type_size(ir->type));
      }
   }
}

void
glsl_to_tgsi_visitor::visit(ir_loop *ir)
{
   emit_asm(NULL, TGSI_OPCODE_BGNLOOP);

   visit_exec_list(&ir->body_instructions, this);

   emit_asm(NULL, TGSI_OPCODE_ENDLOOP);
}

void
glsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
{
   switch (ir->mode) {
   case ir_loop_jump::jump_break:
      emit_asm(NULL, TGSI_OPCODE_BRK);
      break;
   case ir_loop_jump::jump_continue:
      emit_asm(NULL, TGSI_OPCODE_CONT);
      break;
   }
}


void
glsl_to_tgsi_visitor::visit(ir_function_signature *ir)
{
   assert(0);
   (void)ir;
}

void
glsl_to_tgsi_visitor::visit(ir_function *ir)
{
   /* Ignore function bodies other than main() -- we shouldn't see calls to
    * them since they should all be inlined before we get to glsl_to_tgsi.
    */
   if (strcmp(ir->name, "main") == 0) {
      const ir_function_signature *sig;
      exec_list empty;

      sig = ir->matching_signature(NULL, &empty, false);

      assert(sig);

      foreach_in_list(ir_instruction, ir, &sig->body) {
         ir->accept(this);
      }
   }
}

bool
glsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
{
   int nonmul_operand = 1 - mul_operand;
   st_src_reg a, b, c;
   st_dst_reg result_dst;

   // there is no TGSI opcode for this
   if (ir->type->is_integer_64())
      return false;

   ir_expression *expr = ir->operands[mul_operand]->as_expression();
   if (!expr || expr->operation != ir_binop_mul)
      return false;

   expr->operands[0]->accept(this);
   a = this->result;
   expr->operands[1]->accept(this);
   b = this->result;
   ir->operands[nonmul_operand]->accept(this);
   c = this->result;

   this->result = get_temp(ir->type);
   result_dst = st_dst_reg(this->result);
   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
   emit_asm(ir, TGSI_OPCODE_MAD, result_dst, a, b, c);

   return true;
}

/**
 * Emit MAD(a, -b, a) instead of AND(a, NOT(b))
 *
 * The logic values are 1.0 for true and 0.0 for false.  Logical-and is
 * implemented using multiplication, and logical-or is implemented using
 * addition.  Logical-not can be implemented as (true - x), or (1.0 - x).
 * As result, the logical expression (a & !b) can be rewritten as:
 *
 *     - a * !b
 *     - a * (1 - b)
 *     - (a * 1) - (a * b)
 *     - a + -(a * b)
 *     - a + (a * -b)
 *
 * This final expression can be implemented as a single MAD(a, -b, a)
 * instruction.
 */
bool
glsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir,
                                               int try_operand)
{
   const int other_operand = 1 - try_operand;
   st_src_reg a, b;

   ir_expression *expr = ir->operands[try_operand]->as_expression();
   if (!expr || expr->operation != ir_unop_logic_not)
      return false;

   ir->operands[other_operand]->accept(this);
   a = this->result;
   expr->operands[0]->accept(this);
   b = this->result;

   b.negate = ~b.negate;

   this->result = get_temp(ir->type);
   emit_asm(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a);

   return true;
}

void
glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir,
                                      st_src_reg *reg, int *num_reladdr)
{
   if (!reg->reladdr && !reg->reladdr2)
      return;

   if (reg->reladdr)
      emit_arl(ir, address_reg, *reg->reladdr);
   if (reg->reladdr2)
      emit_arl(ir, address_reg2, *reg->reladdr2);

   if (*num_reladdr != 1) {
      st_src_reg temp = get_temp(glsl_type::get_instance(reg->type, 4, 1));

      emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg);
      *reg = temp;
   }

   (*num_reladdr)--;
}

void
glsl_to_tgsi_visitor::visit(ir_expression *ir)
{
   st_src_reg op[ARRAY_SIZE(ir->operands)];

   /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c)
    */
   if (!this->precise && ir->operation == ir_binop_add) {
      if (try_emit_mad(ir, 1))
         return;
      if (try_emit_mad(ir, 0))
         return;
   }

   /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b))
    */
   if (!native_integers && ir->operation == ir_binop_logic_and) {
      if (try_emit_mad_for_and_not(ir, 1))
         return;
      if (try_emit_mad_for_and_not(ir, 0))
         return;
   }

   if (ir->operation == ir_quadop_vector)
      assert(!"ir_quadop_vector should have been lowered");

   for (unsigned int operand = 0; operand < ir->num_operands; operand++) {
      this->result.file = PROGRAM_UNDEFINED;
      ir->operands[operand]->accept(this);
      if (this->result.file == PROGRAM_UNDEFINED) {
         printf("Failed to get tree for expression operand:\n");
         ir->operands[operand]->print();
         printf("\n");
         exit(1);
      }
      op[operand] = this->result;

      /* Matrix expression operands should have been broken down to vector
       * operations already.
       */
      assert(!ir->operands[operand]->type->is_matrix());
   }

   visit_expression(ir, op);
}

/* The non-recursive part of the expression visitor lives in a separate
 * function and should be prevented from being inlined, to avoid a stack
 * explosion when deeply nested expressions are visited.
 */
void
glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op)
{
   st_src_reg result_src;
   st_dst_reg result_dst;

   int vector_elements = ir->operands[0]->type->vector_elements;
   if (ir->operands[1] &&
       ir->operation != ir_binop_interpolate_at_offset &&
       ir->operation != ir_binop_interpolate_at_sample) {
      st_src_reg *swz_op = NULL;
      if (vector_elements > ir->operands[1]->type->vector_elements) {
         assert(ir->operands[1]->type->vector_elements == 1);
         swz_op = &op[1];
      } else if (vector_elements < ir->operands[1]->type->vector_elements) {
         assert(ir->operands[0]->type->vector_elements == 1);
         swz_op = &op[0];
      }
      if (swz_op) {
         uint16_t swizzle_x = GET_SWZ(swz_op->swizzle, 0);
         swz_op->swizzle = MAKE_SWIZZLE4(swizzle_x, swizzle_x,
                                         swizzle_x, swizzle_x);
      }
      vector_elements = MAX2(vector_elements,
                             ir->operands[1]->type->vector_elements);
   }
   if (ir->operands[2] &&
       ir->operands[2]->type->vector_elements != vector_elements) {
      /* This can happen with ir_triop_lrp, i.e. glsl mix */
      assert(ir->operands[2]->type->vector_elements == 1);
      uint16_t swizzle_x = GET_SWZ(op[2].swizzle, 0);
      op[2].swizzle = MAKE_SWIZZLE4(swizzle_x, swizzle_x,
                                    swizzle_x, swizzle_x);
   }

   this->result.file = PROGRAM_UNDEFINED;

   /* Storage for our result.  Ideally for an assignment we'd be using
    * the actual storage for the result here, instead.
    */
   result_src = get_temp(ir->type);
   /* convenience for the emit functions below. */
   result_dst = st_dst_reg(result_src);
   /* Limit writes to the channels that will be used by result_src later.
    * This does limit this temp's use as a temporary for multi-instruction
    * sequences.
    */
   result_dst.writemask = (1 << ir->type->vector_elements) - 1;

   switch (ir->operation) {
   case ir_unop_logic_not:
      if (result_dst.type != GLSL_TYPE_FLOAT)
         emit_asm(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
      else {
         /* Previously 'SEQ dst, src, 0.0' was used for this.  However, many
          * older GPUs implement SEQ using multiple instructions (i915 uses two
          * SGE instructions and a MUL instruction).  Since our logic values are
          * 0.0 and 1.0, 1-x also implements !x.
          */
         op[0].negate = ~op[0].negate;
         emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0],
                  st_src_reg_for_float(1.0));
      }
      break;
   case ir_unop_neg:
      if (result_dst.type == GLSL_TYPE_INT64 ||
          result_dst.type == GLSL_TYPE_UINT64)
         emit_asm(ir, TGSI_OPCODE_I64NEG, result_dst, op[0]);
      else if (result_dst.type == GLSL_TYPE_INT ||
               result_dst.type == GLSL_TYPE_UINT)
         emit_asm(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
      else if (result_dst.type == GLSL_TYPE_DOUBLE)
         emit_asm(ir, TGSI_OPCODE_DNEG, result_dst, op[0]);
      else {
         op[0].negate = ~op[0].negate;
         result_src = op[0];
      }
      break;
   case ir_unop_subroutine_to_int:
      emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
      break;
   case ir_unop_abs:
      if (result_dst.type == GLSL_TYPE_FLOAT)
         emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0].get_abs());
      else if (result_dst.type == GLSL_TYPE_DOUBLE)
         emit_asm(ir, TGSI_OPCODE_DABS, result_dst, op[0]);
      else if (result_dst.type == GLSL_TYPE_INT64 ||
               result_dst.type == GLSL_TYPE_UINT64)
         emit_asm(ir, TGSI_OPCODE_I64ABS, result_dst, op[0]);
      else
         emit_asm(ir, TGSI_OPCODE_IABS, result_dst, op[0]);
      break;
   case ir_unop_sign:
      emit_asm(ir, TGSI_OPCODE_SSG, result_dst, op[0]);
      break;
   case ir_unop_rcp:
      emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]);
      break;

   case ir_unop_exp2:
      emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]);
      break;
   case ir_unop_exp:
      assert(!"not reached: should be handled by exp_to_exp2");
      break;
   case ir_unop_log:
      assert(!"not reached: should be handled by log_to_log2");
      break;
   case ir_unop_log2:
      emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]);
      break;
   case ir_unop_sin:
      emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]);
      break;
   case ir_unop_cos:
      emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]);
      break;
   case ir_unop_saturate: {
      glsl_to_tgsi_instruction *inst;
      inst = emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
      inst->saturate = true;
      break;
   }

   case ir_unop_dFdx:
   case ir_unop_dFdx_coarse:
      emit_asm(ir, TGSI_OPCODE_DDX, result_dst, op[0]);
      break;
   case ir_unop_dFdx_fine:
      emit_asm(ir, TGSI_OPCODE_DDX_FINE, result_dst, op[0]);
      break;
   case ir_unop_dFdy:
   case ir_unop_dFdy_coarse:
   case ir_unop_dFdy_fine:
   {
      /* The X component contains 1 or -1 depending on whether the framebuffer
       * is a FBO or the window system buffer, respectively.
       * It is then multiplied with the source operand of DDY.
       */
      static const gl_state_index16 transform_y_state[STATE_LENGTH]
         = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM };

      unsigned transform_y_index =
         _mesa_add_state_reference(this->prog->Parameters,
                                   transform_y_state);

      st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR,
                                          transform_y_index,
                                          glsl_type::vec4_type);
      transform_y.swizzle = SWIZZLE_XXXX;

      st_src_reg temp = get_temp(glsl_type::vec4_type);

      emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]);
      emit_asm(ir, ir->operation == ir_unop_dFdy_fine ?
           TGSI_OPCODE_DDY_FINE : TGSI_OPCODE_DDY, result_dst, temp);
      break;
   }

   case ir_unop_frexp_sig:
      emit_asm(ir, TGSI_OPCODE_DFRACEXP, result_dst, undef_dst, op[0]);
      break;

   case ir_unop_frexp_exp:
      emit_asm(ir, TGSI_OPCODE_DFRACEXP, undef_dst, result_dst, op[0]);
      break;

   case ir_unop_noise: {
      /* At some point, a motivated person could add a better
       * implementation of noise.  Currently not even the nvidia
       * binary drivers do anything more than this.  In any case, the
       * place to do this is in the GL state tracker, not the poor
       * driver.
       */
      emit_asm(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5));
      break;
   }

   case ir_binop_add:
      emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
      break;
   case ir_binop_sub:
      op[1].negate = ~op[1].negate;
      emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
      break;

   case ir_binop_mul:
      emit_asm(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
      break;
   case ir_binop_div:
      emit_asm(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
      break;
   case ir_binop_mod:
      if (result_dst.type == GLSL_TYPE_FLOAT)
         assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
      else
         emit_asm(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]);
      break;

   case ir_binop_less:
      emit_asm(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]);
      break;
   case ir_binop_gequal:
      emit_asm(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]);
      break;
   case ir_binop_equal:
      emit_asm(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
      break;
   case ir_binop_nequal:
      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
      break;
   case ir_binop_all_equal:
      /* "==" operator producing a scalar boolean. */
      if (ir->operands[0]->type->is_vector() ||
          ir->operands[1]->type->is_vector()) {
         st_src_reg temp = get_temp(native_integers ?
                                    glsl_type::uvec4_type :
                                    glsl_type::vec4_type);

         if (native_integers) {
            st_dst_reg temp_dst = st_dst_reg(temp);
            st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);

            if (ir->operands[0]->type->is_boolean() &&
                ir->operands[1]->as_constant() &&
                ir->operands[1]->as_constant()->is_one()) {
               emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), op[0]);
            } else {
               emit_asm(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
            }

            /* Emit 1-3 AND operations to combine the SEQ results. */
            switch (ir->operands[0]->type->vector_elements) {
            case 2:
               break;
            case 3:
               temp_dst.writemask = WRITEMASK_Y;
               temp1.swizzle = SWIZZLE_YYYY;
               temp2.swizzle = SWIZZLE_ZZZZ;
               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
               break;
            case 4:
               temp_dst.writemask = WRITEMASK_X;
               temp1.swizzle = SWIZZLE_XXXX;
               temp2.swizzle = SWIZZLE_YYYY;
               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
               temp_dst.writemask = WRITEMASK_Y;
               temp1.swizzle = SWIZZLE_ZZZZ;
               temp2.swizzle = SWIZZLE_WWWW;
               emit_asm(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
            }

            temp1.swizzle = SWIZZLE_XXXX;
            temp2.swizzle = SWIZZLE_YYYY;
            emit_asm(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2);
         } else {
            emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);

            /* After the dot-product, the value will be an integer on the
             * range [0,4].  Zero becomes 1.0, and positive values become zero.
             */
            emit_dp(ir, result_dst, temp, temp, vector_elements);

            /* Negating the result of the dot-product gives values on the range
             * [-4, 0].  Zero becomes 1.0, and negative values become zero.
             * This is achieved using SGE.
             */
            st_src_reg sge_src = result_src;
            sge_src.negate = ~sge_src.negate;
            emit_asm(ir, TGSI_OPCODE_SGE, result_dst, sge_src,
                     st_src_reg_for_float(0.0));
         }
      } else {
         emit_asm(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
      }
      break;
   case ir_binop_any_nequal:
      /* "!=" operator producing a scalar boolean. */
      if (ir->operands[0]->type->is_vector() ||
          ir->operands[1]->type->is_vector()) {
         st_src_reg temp = get_temp(native_integers ?
                                    glsl_type::uvec4_type :
                                    glsl_type::vec4_type);
         if (ir->operands[0]->type->is_boolean() &&
             ir->operands[1]->as_constant() &&
             ir->operands[1]->as_constant()->is_zero()) {
            emit_asm(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), op[0]);
         } else {
            emit_asm(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
         }

         if (native_integers) {
            st_dst_reg temp_dst = st_dst_reg(temp);
            st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);

            /* Emit 1-3 OR operations to combine the SNE results. */
            switch (ir->operands[0]->type->vector_elements) {
            case 2:
               break;
            case 3:
               temp_dst.writemask = WRITEMASK_Y;
               temp1.swizzle = SWIZZLE_YYYY;
               temp2.swizzle = SWIZZLE_ZZZZ;
               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
               break;
            case 4:
               temp_dst.writemask = WRITEMASK_X;
               temp1.swizzle = SWIZZLE_XXXX;
               temp2.swizzle = SWIZZLE_YYYY;
               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
               temp_dst.writemask = WRITEMASK_Y;
               temp1.swizzle = SWIZZLE_ZZZZ;
               temp2.swizzle = SWIZZLE_WWWW;
               emit_asm(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
            }

            temp1.swizzle = SWIZZLE_XXXX;
            temp2.swizzle = SWIZZLE_YYYY;
            emit_asm(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2);
         } else {
            /* After the dot-product, the value will be an integer on the
             * range [0,4].  Zero stays zero, and positive values become 1.0.
             */
            glsl_to_tgsi_instruction *const dp =
                  emit_dp(ir, result_dst, temp, temp, vector_elements);
            if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
               /* The clamping to [0,1] can be done for free in the fragment
                * shader with a saturate.
                */
               dp->saturate = true;
            } else {
               /* Negating the result of the dot-product gives values on the
                * range [-4, 0].  Zero stays zero, and negative values become
                * 1.0.  This achieved using SLT.
                */
               st_src_reg slt_src = result_src;
               slt_src.negate = ~slt_src.negate;
               emit_asm(ir, TGSI_OPCODE_SLT, result_dst, slt_src,
                        st_src_reg_for_float(0.0));
            }
         }
      } else {
         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
      }
      break;

   case ir_binop_logic_xor:
      if (native_integers)
         emit_asm(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
      else
         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
      break;

   case ir_binop_logic_or: {
      if (native_integers) {
         /* If integers are used as booleans, we can use an actual "or"
          * instruction.
          */
         assert(native_integers);
         emit_asm(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
      } else {
         /* After the addition, the value will be an integer on the
          * range [0,2].  Zero stays zero, and positive values become 1.0.
          */
         glsl_to_tgsi_instruction *add =
            emit_asm(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
         if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
            /* The clamping to [0,1] can be done for free in the fragment
             * shader with a saturate if floats are being used as boolean
             * values.
             */
            add->saturate = true;
         } else {
            /* Negating the result of the addition gives values on the range
             * [-2, 0].  Zero stays zero, and negative values become 1.0
             * This is achieved using SLT.
             */
            st_src_reg slt_src = result_src;
            slt_src.negate = ~slt_src.negate;
            emit_asm(ir, TGSI_OPCODE_SLT, result_dst, slt_src,
                     st_src_reg_for_float(0.0));
         }
      }
      break;
   }

   case ir_binop_logic_and:
      /* If native integers are disabled, the bool args are stored as float 0.0
       * or 1.0, so "mul" gives us "and".  If they're enabled, just use the
       * actual AND opcode.
       */
      if (native_integers)
         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
      else
         emit_asm(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
      break;

   case ir_binop_dot:
      assert(ir->operands[0]->type->is_vector());
      assert(ir->operands[0]->type == ir->operands[1]->type);
      emit_dp(ir, result_dst, op[0], op[1],
              ir->operands[0]->type->vector_elements);
      break;

   case ir_unop_sqrt:
      if (have_sqrt) {
         emit_scalar(ir, TGSI_OPCODE_SQRT, result_dst, op[0]);
      } else {
         /* This is the only instruction sequence that makes the game "Risen"
          * render correctly. ABS is not required for the game, but since GLSL
          * declares negative values as "undefined", allowing us to do whatever
          * we want, I choose to use ABS to match DX9 and pre-GLSL RSQ
          * behavior.
          */
         emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0].get_abs());
         emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, result_src);
      }
      break;
   case ir_unop_rsq:
      emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
      break;
   case ir_unop_i2f:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_I2F, result_dst, op[0]);
         break;
      }
      /* fallthrough to next case otherwise */
   case ir_unop_b2f:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0],
                  st_src_reg_for_float(1.0));
         break;
      }
      /* fallthrough to next case otherwise */
   case ir_unop_i2u:
   case ir_unop_u2i:
   case ir_unop_i642u64:
   case ir_unop_u642i64:
      /* Converting between signed and unsigned integers is a no-op. */
      result_src = op[0];
      result_src.type = result_dst.type;
      break;
   case ir_unop_b2i:
      if (native_integers) {
         /* Booleans are stored as integers using ~0 for true and 0 for false.
          * GLSL requires that int(bool) return 1 for true and 0 for false.
          * This conversion is done with AND, but it could be done with NEG.
          */
         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0],
                  st_src_reg_for_int(1));
      } else {
         /* Booleans and integers are both stored as floats when native
          * integers are disabled.
          */
         result_src = op[0];
      }
      break;
   case ir_unop_f2i:
      if (native_integers)
         emit_asm(ir, TGSI_OPCODE_F2I, result_dst, op[0]);
      else
         emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
      break;
   case ir_unop_f2u:
      if (native_integers)
         emit_asm(ir, TGSI_OPCODE_F2U, result_dst, op[0]);
      else
         emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
      break;
   case ir_unop_bitcast_f2i:
   case ir_unop_bitcast_f2u:
      /* Make sure we don't propagate the negate modifier to integer opcodes. */
      if (op[0].negate || op[0].abs)
         emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
      else
         result_src = op[0];
      result_src.type = ir->operation == ir_unop_bitcast_f2i ? GLSL_TYPE_INT :
                                                               GLSL_TYPE_UINT;
      break;
   case ir_unop_bitcast_i2f:
   case ir_unop_bitcast_u2f:
      result_src = op[0];
      result_src.type = GLSL_TYPE_FLOAT;
      break;
   case ir_unop_f2b:
      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0],
               st_src_reg_for_float(0.0));
      break;
   case ir_unop_d2b:
      emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0],
               st_src_reg_for_double(0.0));
      break;
   case ir_unop_i2b:
      if (native_integers)
         emit_asm(ir, TGSI_OPCODE_USNE, result_dst, op[0],
                  st_src_reg_for_int(0));
      else
         emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0],
                  st_src_reg_for_float(0.0));
      break;
   case ir_unop_bitcast_u642d:
   case ir_unop_bitcast_i642d:
      result_src = op[0];
      result_src.type = GLSL_TYPE_DOUBLE;
      break;
   case ir_unop_bitcast_d2i64:
      result_src = op[0];
      result_src.type = GLSL_TYPE_INT64;
      break;
   case ir_unop_bitcast_d2u64:
      result_src = op[0];
      result_src.type = GLSL_TYPE_UINT64;
      break;
   case ir_unop_trunc:
      emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
      break;
   case ir_unop_ceil:
      emit_asm(ir, TGSI_OPCODE_CEIL, result_dst, op[0]);
      break;
   case ir_unop_floor:
      emit_asm(ir, TGSI_OPCODE_FLR, result_dst, op[0]);
      break;
   case ir_unop_round_even:
      emit_asm(ir, TGSI_OPCODE_ROUND, result_dst, op[0]);
      break;
   case ir_unop_fract:
      emit_asm(ir, TGSI_OPCODE_FRC, result_dst, op[0]);
      break;

   case ir_binop_min:
      emit_asm(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]);
      break;
   case ir_binop_max:
      emit_asm(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]);
      break;
   case ir_binop_pow:
      emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]);
      break;

   case ir_unop_bit_not:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
         break;
      }
   case ir_unop_u2f:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_U2F, result_dst, op[0]);
         break;
      }
   case ir_binop_lshift:
   case ir_binop_rshift:
      if (native_integers) {
         enum tgsi_opcode opcode = ir->operation == ir_binop_lshift
            ? TGSI_OPCODE_SHL : TGSI_OPCODE_ISHR;
         st_src_reg count;

         if (glsl_base_type_is_64bit(op[0].type)) {
            /* GLSL shift operations have 32-bit shift counts, but TGSI uses
             * 64 bits.
             */
            count = get_temp(glsl_type::u64vec(ir->operands[1]
                                               ->type->components()));
            emit_asm(ir, TGSI_OPCODE_U2I64, st_dst_reg(count), op[1]);
         } else {
            count = op[1];
         }

         emit_asm(ir, opcode, result_dst, op[0], count);
         break;
      }
   case ir_binop_bit_and:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
         break;
      }
   case ir_binop_bit_xor:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
         break;
      }
   case ir_binop_bit_or:
      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
         break;
      }

      assert(!"GLSL 1.30 features unsupported");
      break;

   case ir_binop_ubo_load: {
      if (ctx->Const.UseSTD430AsDefaultPacking) {
         ir_rvalue *block = ir->operands[0];
         ir_rvalue *offset = ir->operands[1];
         ir_constant *const_block = block->as_constant();

         st_src_reg cbuf(PROGRAM_CONSTANT,
            (const_block ? const_block->value.u[0] + 1 : 1),
            ir->type->base_type);

         cbuf.has_index2 = true;

         if (!const_block) {
            block->accept(this);
            cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
            *cbuf.reladdr = this->result;
            emit_arl(ir, sampler_reladdr, this->result);
         }

         /* Calculate the surface offset */
         offset->accept(this);
         st_src_reg off = this->result;

         glsl_to_tgsi_instruction *inst =
            emit_asm(ir, TGSI_OPCODE_LOAD, result_dst, off);

         if (result_dst.type == GLSL_TYPE_BOOL)
            emit_asm(ir, TGSI_OPCODE_USNE, result_dst, st_src_reg(result_dst),
                     st_src_reg_for_int(0));

         add_buffer_to_load_and_stores(inst, &cbuf, &this->instructions,
                                       NULL);
      } else {
         ir_constant *const_uniform_block = ir->operands[0]->as_constant();
         ir_constant *const_offset_ir = ir->operands[1]->as_constant();
         unsigned const_offset = const_offset_ir ?
            const_offset_ir->value.u[0] : 0;
         unsigned const_block = const_uniform_block ?
            const_uniform_block->value.u[0] + 1 : 1;
         st_src_reg index_reg = get_temp(glsl_type::uint_type);
         st_src_reg cbuf;

         cbuf.type = ir->type->base_type;
         cbuf.file = PROGRAM_CONSTANT;
         cbuf.index = 0;
         cbuf.reladdr = NULL;
         cbuf.negate = 0;
         cbuf.abs = 0;
         cbuf.index2D = const_block;

         assert(ir->type->is_vector() || ir->type->is_scalar());

         if (const_offset_ir) {
            /* Constant index into constant buffer */
            cbuf.reladdr = NULL;
            cbuf.index = const_offset / 16;
         } else {
            ir_expression *offset_expr = ir->operands[1]->as_expression();
            st_src_reg offset = op[1];

            /* The OpenGL spec is written in such a way that accesses with
             * non-constant offset are almost always vec4-aligned. The only
             * exception to this are members of structs in arrays of structs:
             * each struct in an array of structs is at least vec4-aligned,
             * but single-element and [ui]vec2 members of the struct may be at
             * an offset that is not a multiple of 16 bytes.
             *
             * Here, we extract that offset, relying on previous passes to
             * always generate offset expressions of the form
             * (+ expr constant_offset).
             *
             * Note that the std430 layout, which allows more cases of
             * alignment less than vec4 in arrays, is not supported for
             * uniform blocks, so we do not have to deal with it here.
             */
            if (offset_expr && offset_expr->operation == ir_binop_add) {
               const_offset_ir = offset_expr->operands[1]->as_constant();
               if (const_offset_ir) {
                  const_offset = const_offset_ir->value.u[0];
                  cbuf.index = const_offset / 16;
                  offset_expr->operands[0]->accept(this);
                  offset = this->result;
               }
            }

            /* Relative/variable index into constant buffer */
            emit_asm(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), offset,
                 st_src_reg_for_int(4));
            cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
            *cbuf.reladdr = index_reg;
         }

         if (const_uniform_block) {
            /* Constant constant buffer */
            cbuf.reladdr2 = NULL;
         } else {
            /* Relative/variable constant buffer */
            cbuf.reladdr2 = ralloc(mem_ctx, st_src_reg);
            *cbuf.reladdr2 = op[0];
         }
         cbuf.has_index2 = true;

         cbuf.swizzle = swizzle_for_size(ir->type->vector_elements);
         if (glsl_base_type_is_64bit(cbuf.type))
            cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 8,
                                          const_offset % 16 / 8,
                                          const_offset % 16 / 8,
                                          const_offset % 16 / 8);
         else
            cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 4,
                                          const_offset % 16 / 4,
                                          const_offset % 16 / 4,
                                          const_offset % 16 / 4);

         if (ir->type->is_boolean()) {
            emit_asm(ir, TGSI_OPCODE_USNE, result_dst, cbuf,
                     st_src_reg_for_int(0));
         } else {
            emit_asm(ir, TGSI_OPCODE_MOV, result_dst, cbuf);
         }
      }
      break;
   }
   case ir_triop_lrp:
      /* note: we have to reorder the three args here */
      emit_asm(ir, TGSI_OPCODE_LRP, result_dst, op[2], op[1], op[0]);
      break;
   case ir_triop_csel:
      if (this->ctx->Const.NativeIntegers)
         emit_asm(ir, TGSI_OPCODE_UCMP, result_dst, op[0], op[1], op[2]);
      else {
         op[0].negate = ~op[0].negate;
         emit_asm(ir, TGSI_OPCODE_CMP, result_dst, op[0], op[1], op[2]);
      }
      break;
   case ir_triop_bitfield_extract:
      emit_asm(ir, TGSI_OPCODE_IBFE, result_dst, op[0], op[1], op[2]);
      break;
   case ir_quadop_bitfield_insert:
      emit_asm(ir, TGSI_OPCODE_BFI, result_dst, op[0], op[1], op[2], op[3]);
      break;
   case ir_unop_bitfield_reverse:
      emit_asm(ir, TGSI_OPCODE_BREV, result_dst, op[0]);
      break;
   case ir_unop_bit_count:
      emit_asm(ir, TGSI_OPCODE_POPC, result_dst, op[0]);
      break;
   case ir_unop_find_msb:
      emit_asm(ir, TGSI_OPCODE_IMSB, result_dst, op[0]);
      break;
   case ir_unop_find_lsb:
      emit_asm(ir, TGSI_OPCODE_LSB, result_dst, op[0]);
      break;
   case ir_binop_imul_high:
      emit_asm(ir, TGSI_OPCODE_IMUL_HI, result_dst, op[0], op[1]);
      break;
   case ir_triop_fma:
      /* In theory, MAD is incorrect here. */
      if (have_fma)
         emit_asm(ir, TGSI_OPCODE_FMA, result_dst, op[0], op[1], op[2]);
      else
         emit_asm(ir, TGSI_OPCODE_MAD, result_dst, op[0], op[1], op[2]);
      break;
   case ir_unop_interpolate_at_centroid:
      emit_asm(ir, TGSI_OPCODE_INTERP_CENTROID, result_dst, op[0]);
      break;
   case ir_binop_interpolate_at_offset: {
      /* The y coordinate needs to be flipped for the default fb */
      static const gl_state_index16 transform_y_state[STATE_LENGTH]
         = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM };

      unsigned transform_y_index =
         _mesa_add_state_reference(this->prog->Parameters,
                                   transform_y_state);

      st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR,
                                          transform_y_index,
                                          glsl_type::vec4_type);
      transform_y.swizzle = SWIZZLE_XXXX;

      st_src_reg temp = get_temp(glsl_type::vec2_type);
      st_dst_reg temp_dst = st_dst_reg(temp);

      emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[1]);
      temp_dst.writemask = WRITEMASK_Y;
      emit_asm(ir, TGSI_OPCODE_MUL, temp_dst, transform_y, op[1]);
      emit_asm(ir, TGSI_OPCODE_INTERP_OFFSET, result_dst, op[0], temp);
      break;
   }
   case ir_binop_interpolate_at_sample:
      emit_asm(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]);
      break;

   case ir_unop_d2f:
      emit_asm(ir, TGSI_OPCODE_D2F, result_dst, op[0]);
      break;
   case ir_unop_f2d:
      emit_asm(ir, TGSI_OPCODE_F2D, result_dst, op[0]);
      break;
   case ir_unop_d2i:
      emit_asm(ir, TGSI_OPCODE_D2I, result_dst, op[0]);
      break;
   case ir_unop_i2d:
      emit_asm(ir, TGSI_OPCODE_I2D, result_dst, op[0]);
      break;
   case ir_unop_d2u:
      emit_asm(ir, TGSI_OPCODE_D2U, result_dst, op[0]);
      break;
   case ir_unop_u2d:
      emit_asm(ir, TGSI_OPCODE_U2D, result_dst, op[0]);
      break;
   case ir_unop_unpack_double_2x32:
   case ir_unop_pack_double_2x32:
   case ir_unop_unpack_int_2x32:
   case ir_unop_pack_int_2x32:
   case ir_unop_unpack_uint_2x32:
   case ir_unop_pack_uint_2x32:
   case ir_unop_unpack_sampler_2x32:
   case ir_unop_pack_sampler_2x32:
   case ir_unop_unpack_image_2x32:
   case ir_unop_pack_image_2x32:
      emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
      break;

   case ir_binop_ldexp:
      if (ir->operands[0]->type->is_double()) {
         emit_asm(ir, TGSI_OPCODE_DLDEXP, result_dst, op[0], op[1]);
      } else if (ir->operands[0]->type->is_float()) {
         emit_asm(ir, TGSI_OPCODE_LDEXP, result_dst, op[0], op[1]);
      } else {
         assert(!"Invalid ldexp for non-double opcode in glsl_to_tgsi_visitor::visit()");
      }
      break;

   case ir_unop_pack_half_2x16:
      emit_asm(ir, TGSI_OPCODE_PK2H, result_dst, op[0]);
      break;
   case ir_unop_unpack_half_2x16:
      emit_asm(ir, TGSI_OPCODE_UP2H, result_dst, op[0]);
      break;

   case ir_unop_get_buffer_size: {
      ir_constant *const_offset = ir->operands[0]->as_constant();
      st_src_reg buffer(
            PROGRAM_BUFFER,
            const_offset ? const_offset->value.u[0] : 0,
            GLSL_TYPE_UINT);
      if (!const_offset) {
         buffer.reladdr = ralloc(mem_ctx, st_src_reg);
         *buffer.reladdr = op[0];
         emit_arl(ir, sampler_reladdr, op[0]);
      }
      emit_asm(ir, TGSI_OPCODE_RESQ, result_dst)->resource = buffer;
      break;
   }

   case ir_unop_u2i64:
   case ir_unop_u2u64:
   case ir_unop_b2i64: {
      st_src_reg temp = get_temp(glsl_type::uvec4_type);
      st_dst_reg temp_dst = st_dst_reg(temp);
      unsigned orig_swz = op[0].swizzle;
      /*
       * To convert unsigned to 64-bit:
       * zero Y channel, copy X channel.
       */
      temp_dst.writemask = WRITEMASK_Y;
      if (vector_elements > 1)
         temp_dst.writemask |= WRITEMASK_W;
      emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, st_src_reg_for_int(0));
      temp_dst.writemask = WRITEMASK_X;
      if (vector_elements > 1)
          temp_dst.writemask |= WRITEMASK_Z;
      op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(orig_swz, 0), GET_SWZ(orig_swz, 0),
                                    GET_SWZ(orig_swz, 1), GET_SWZ(orig_swz, 1));
      if (ir->operation == ir_unop_u2i64 || ir->operation == ir_unop_u2u64)
         emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
      else
         emit_asm(ir, TGSI_OPCODE_AND, temp_dst, op[0], st_src_reg_for_int(1));
      result_src = temp;
      result_src.type = GLSL_TYPE_UINT64;
      if (vector_elements > 2) {
         /* Subtle: We rely on the fact that get_temp here returns the next
          * TGSI temporary register directly after the temp register used for
          * the first two components, so that the result gets picked up
          * automatically.
          */
         st_src_reg temp = get_temp(glsl_type::uvec4_type);
         st_dst_reg temp_dst = st_dst_reg(temp);
         temp_dst.writemask = WRITEMASK_Y;
         if (vector_elements > 3)
            temp_dst.writemask |= WRITEMASK_W;
         emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, st_src_reg_for_int(0));

         temp_dst.writemask = WRITEMASK_X;
         if (vector_elements > 3)
            temp_dst.writemask |= WRITEMASK_Z;
         op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(orig_swz, 2),
                                       GET_SWZ(orig_swz, 2),
                                       GET_SWZ(orig_swz, 3),
                                       GET_SWZ(orig_swz, 3));
         if (ir->operation == ir_unop_u2i64 || ir->operation == ir_unop_u2u64)
            emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
         else
            emit_asm(ir, TGSI_OPCODE_AND, temp_dst, op[0],
                     st_src_reg_for_int(1));
      }
      break;
   }
   case ir_unop_i642i:
   case ir_unop_u642i:
   case ir_unop_u642u:
   case ir_unop_i642u: {
      st_src_reg temp = get_temp(glsl_type::uvec4_type);
      st_dst_reg temp_dst = st_dst_reg(temp);
      unsigned orig_swz = op[0].swizzle;
      unsigned orig_idx = op[0].index;
      int el;
      temp_dst.writemask = WRITEMASK_X;

      for (el = 0; el < vector_elements; el++) {
         unsigned swz = GET_SWZ(orig_swz, el);
         if (swz & 1)
            op[0].swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z,
                                          SWIZZLE_Z, SWIZZLE_Z);
         else
            op[0].swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
                                          SWIZZLE_X, SWIZZLE_X);
         if (swz > 2)
            op[0].index = orig_idx + 1;
         op[0].type = GLSL_TYPE_UINT;
         temp_dst.writemask = WRITEMASK_X << el;
         emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
      }
      result_src = temp;
      if (ir->operation == ir_unop_u642u || ir->operation == ir_unop_i642u)
         result_src.type = GLSL_TYPE_UINT;
      else
         result_src.type = GLSL_TYPE_INT;
      break;
   }
   case ir_unop_i642b:
      emit_asm(ir, TGSI_OPCODE_U64SNE, result_dst, op[0],
               st_src_reg_for_int64(0));
      break;
   case ir_unop_i642f:
      emit_asm(ir, TGSI_OPCODE_I642F, result_dst, op[0]);
      break;
   case ir_unop_u642f:
      emit_asm(ir, TGSI_OPCODE_U642F, result_dst, op[0]);
      break;
   case ir_unop_i642d:
      emit_asm(ir, TGSI_OPCODE_I642D, result_dst, op[0]);
      break;
   case ir_unop_u642d:
      emit_asm(ir, TGSI_OPCODE_U642D, result_dst, op[0]);
      break;
   case ir_unop_i2i64:
      emit_asm(ir, TGSI_OPCODE_I2I64, result_dst, op[0]);
      break;
   case ir_unop_f2i64:
      emit_asm(ir, TGSI_OPCODE_F2I64, result_dst, op[0]);
      break;
   case ir_unop_d2i64:
      emit_asm(ir, TGSI_OPCODE_D2I64, result_dst, op[0]);
      break;
   case ir_unop_i2u64:
      emit_asm(ir, TGSI_OPCODE_I2I64, result_dst, op[0]);
      break;
   case ir_unop_f2u64:
      emit_asm(ir, TGSI_OPCODE_F2U64, result_dst, op[0]);
      break;
   case ir_unop_d2u64:
      emit_asm(ir, TGSI_OPCODE_D2U64, result_dst, op[0]);
      break;
      /* these might be needed */
   case ir_unop_pack_snorm_2x16:
   case ir_unop_pack_unorm_2x16:
   case ir_unop_pack_snorm_4x8:
   case ir_unop_pack_unorm_4x8:

   case ir_unop_unpack_snorm_2x16:
   case ir_unop_unpack_unorm_2x16:
   case ir_unop_unpack_snorm_4x8:
   case ir_unop_unpack_unorm_4x8:

   case ir_quadop_vector:
   case ir_binop_vector_extract:
   case ir_triop_vector_insert:
   case ir_binop_carry:
   case ir_binop_borrow:
   case ir_unop_ssbo_unsized_array_length:
   case ir_unop_atan:
   case ir_binop_atan2:
   case ir_unop_clz:
   case ir_binop_add_sat:
   case ir_binop_sub_sat:
   case ir_binop_abs_sub:
   case ir_binop_avg:
   case ir_binop_avg_round:
   case ir_binop_mul_32x16:
      /* This operation is not supported, or should have already been handled.
       */
      assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
      break;
   }

   this->result = result_src;
}


void
glsl_to_tgsi_visitor::visit(ir_swizzle *ir)
{
   st_src_reg src;
   int i;
   int swizzle[4];

   /* Note that this is only swizzles in expressions, not those on the left
    * hand side of an assignment, which do write masking.  See ir_assignment
    * for that.
    */

   ir->val->accept(this);
   src = this->result;
   assert(src.file != PROGRAM_UNDEFINED);
   assert(ir->type->vector_elements > 0);

   for (i = 0; i < 4; i++) {
      if (i < ir->type->vector_elements) {
         switch (i) {
         case 0:
            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x);
            break;
         case 1:
            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y);
            break;
         case 2:
            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z);
            break;
         case 3:
            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w);
            break;
         }
      } else {
         /* If the type is smaller than a vec4, replicate the last
          * channel out.
          */
         swizzle[i] = swizzle[ir->type->vector_elements - 1];
      }
   }

   src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);

   this->result = src;
}

/* Test if the variable is an array. Note that geometry and
 * tessellation shader inputs are outputs are always arrays (except
 * for patch inputs), so only the array element type is considered.
 */
static bool
is_inout_array(unsigned stage, ir_variable *var, bool *remove_array)
{
   const glsl_type *type = var->type;

   *remove_array = false;

   if ((stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_in) ||
       (stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out))
      return false;

   if (((stage == MESA_SHADER_GEOMETRY && var->data.mode == ir_var_shader_in) ||
        (stage == MESA_SHADER_TESS_EVAL && var->data.mode == ir_var_shader_in) ||
        stage == MESA_SHADER_TESS_CTRL) &&
       !var->data.patch) {
      if (!var->type->is_array())
         return false; /* a system value probably */

      type = var->type->fields.array;
      *remove_array = true;
   }

   return type->is_array() || type->is_matrix();
}

static unsigned
st_translate_interp_loc(ir_variable *var)
{
   if (var->data.centroid)
      return TGSI_INTERPOLATE_LOC_CENTROID;
   else if (var->data.sample)
      return TGSI_INTERPOLATE_LOC_SAMPLE;
   else
      return TGSI_INTERPOLATE_LOC_CENTER;
}

void
glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
{
   variable_storage *entry;
   ir_variable *var = ir->var;
   bool remove_array;

   if (handle_bound_deref(ir->as_dereference()))
      return;

   entry = find_variable_storage(ir->var);

   if (!entry) {
      switch (var->data.mode) {
      case ir_var_uniform:
         entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM,
                                               var->data.param_index);
         _mesa_hash_table_insert(this->variables, var, entry);
         break;
      case ir_var_shader_in: {
         /* The linker assigns locations for varyings and attributes,
          * including deprecated builtins (like gl_Color), user-assign
          * generic attributes (glBindVertexLocation), and
          * user-defined varyings.
          */
         assert(var->data.location != -1);

         const glsl_type *type_without_array = var->type->without_array();
         struct inout_decl *decl = &inputs[num_inputs];
         unsigned component = var->data.location_frac;
         unsigned num_components;
         num_inputs++;

         if (type_without_array->is_64bit())
            component = component / 2;
         if (type_without_array->vector_elements)
            num_components = type_without_array->vector_elements;
         else
            num_components = 4;

         decl->mesa_index = var->data.location;
         decl->interp = (glsl_interp_mode) var->data.interpolation;
         decl->interp_loc = st_translate_interp_loc(var);
         decl->base_type = type_without_array->base_type;
         decl->usage_mask = u_bit_consecutive(component, num_components);

         if (is_inout_array(shader->Stage, var, &remove_array)) {
            decl->array_id = num_input_arrays + 1;
            num_input_arrays++;
         } else {
            decl->array_id = 0;
         }

         if (remove_array)
            decl->size = type_size(var->type->fields.array);
         else
            decl->size = type_size(var->type);

         entry = new(mem_ctx) variable_storage(var,
                                               PROGRAM_INPUT,
                                               decl->mesa_index,
                                               decl->array_id);
         entry->component = component;

         _mesa_hash_table_insert(this->variables, var, entry);

         break;
      }
      case ir_var_shader_out: {
         assert(var->data.location != -1);

         const glsl_type *type_without_array = var->type->without_array();
         struct inout_decl *decl = &outputs[num_outputs];
         unsigned component = var->data.location_frac;
         unsigned num_components;
         num_outputs++;

         decl->invariant = var->data.invariant;

         if (type_without_array->is_64bit())
            component = component / 2;
         if (type_without_array->vector_elements)
            num_components = type_without_array->vector_elements;
         else
            num_components = 4;

         decl->mesa_index = var->data.location + FRAG_RESULT_MAX * var->data.index;
         decl->base_type = type_without_array->base_type;
         decl->usage_mask = u_bit_consecutive(component, num_components);
         if (var->data.stream & (1u << 31)) {
            decl->gs_out_streams = var->data.stream & ~(1u << 31);
         } else {
            assert(var->data.stream < 4);
            decl->gs_out_streams = 0;
            for (unsigned i = 0; i < num_components; ++i)
               decl->gs_out_streams |= var->data.stream << (2 * (component + i));
         }

         if (is_inout_array(shader->Stage, var, &remove_array)) {
            decl->array_id = num_output_arrays + 1;
            num_output_arrays++;
         } else {
            decl->array_id = 0;
         }

         if (remove_array)
            decl->size = type_size(var->type->fields.array);
         else
            decl->size = type_size(var->type);

         if (var->data.fb_fetch_output) {
            st_dst_reg dst = st_dst_reg(get_temp(var->type));
            st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
                                        var->type, component, decl->array_id);
            emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
            entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
                                                  dst.array_id);
         } else {
            entry = new(mem_ctx) variable_storage(var,
                                                  PROGRAM_OUTPUT,
                                                  decl->mesa_index,
                                                  decl->array_id);
         }
         entry->component = component;

         _mesa_hash_table_insert(this->variables, var, entry);

         break;
      }
      case ir_var_system_value:
         entry = new(mem_ctx) variable_storage(var,
                                               PROGRAM_SYSTEM_VALUE,
                                               var->data.location);
         break;
      case ir_var_auto:
      case ir_var_temporary:
         st_src_reg src = get_temp(var->type);

         entry = new(mem_ctx) variable_storage(var, src.file, src.index,
                                               src.array_id);
         _mesa_hash_table_insert(this->variables, var, entry);

         break;
      }

      if (!entry) {
         printf("Failed to make storage for %s\n", var->name);
         exit(1);
      }
   }

   this->result = st_src_reg(entry->file, entry->index, var->type,
                             entry->component, entry->array_id);
   if (this->shader->Stage == MESA_SHADER_VERTEX &&
       var->data.mode == ir_var_shader_in &&
       var->type->without_array()->is_double())
      this->result.is_double_vertex_input = true;
   if (!native_integers)
      this->result.type = GLSL_TYPE_FLOAT;
}

static void
shrink_array_declarations(struct inout_decl *decls, unsigned count,
                          GLbitfield64* usage_mask,
                          GLbitfield64 double_usage_mask,
                          GLbitfield* patch_usage_mask)
{
   unsigned i;
   int j;

   /* Fix array declarations by removing unused array elements at both ends
    * of the arrays. For example, mat4[3] where only mat[1] is used.
    */
   for (i = 0; i < count; i++) {
      struct inout_decl *decl = &decls[i];
      if (!decl->array_id)
         continue;

      /* Shrink the beginning. */
      for (j = 0; j < (int)decl->size; j++) {
         if (decl->mesa_index >= VARYING_SLOT_PATCH0) {
            if (*patch_usage_mask &
                BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j))
               break;
         }
         else {
            if (*usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
               break;
            if (double_usage_mask & BITFIELD64_BIT(decl->mesa_index+j-1))
               break;
         }

         decl->mesa_index++;
         decl->size--;
         j--;
      }

      /* Shrink the end. */
      for (j = decl->size-1; j >= 0; j--) {
         if (decl->mesa_index >= VARYING_SLOT_PATCH0) {
            if (*patch_usage_mask &
                BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j))
               break;
         }
         else {
            if (*usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
               break;
            if (double_usage_mask & BITFIELD64_BIT(decl->mesa_index+j-1))
               break;
         }

         decl->size--;
      }

      /* When not all entries of an array are accessed, we mark them as used
       * here anyway, to ensure that the input/output mapping logic doesn't get
       * confused.
       *
       * TODO This happens when an array isn't used via indirect access, which
       * some game ports do (at least eON-based). There is an optimization
       * opportunity here by replacing the array declaration with non-array
       * declarations of those slots that are actually used.
       */
      for (j = 1; j < (int)decl->size; ++j) {
         if (decl->mesa_index >= VARYING_SLOT_PATCH0)
            *patch_usage_mask |= BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j);
         else
            *usage_mask |= BITFIELD64_BIT(decl->mesa_index + j);
      }
   }
}


static void
mark_array_io(struct inout_decl *decls, unsigned count,
              GLbitfield64* usage_mask,
              GLbitfield64 double_usage_mask,
              GLbitfield* patch_usage_mask)
{
   unsigned i;
   int j;

   /* Fix array declarations by removing unused array elements at both ends
    * of the arrays. For example, mat4[3] where only mat[1] is used.
    */
   for (i = 0; i < count; i++) {
      struct inout_decl *decl = &decls[i];
      if (!decl->array_id)
         continue;

      /* When not all entries of an array are accessed, we mark them as used
       * here anyway, to ensure that the input/output mapping logic doesn't get
       * confused.
       *
       * TODO This happens when an array isn't used via indirect access, which
       * some game ports do (at least eON-based). There is an optimization
       * opportunity here by replacing the array declaration with non-array
       * declarations of those slots that are actually used.
       */
      for (j = 0; j < (int)decl->size; ++j) {
         if (decl->mesa_index >= VARYING_SLOT_PATCH0)
            *patch_usage_mask |= BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j);
         else
            *usage_mask |= BITFIELD64_BIT(decl->mesa_index + j);
      }
   }
}

void
glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
{
   ir_constant *index;
   st_src_reg src;
   bool is_2D = false;
   ir_variable *var = ir->variable_referenced();

   if (handle_bound_deref(ir->as_dereference()))
      return;

   /* We only need the logic provided by count_vec4_slots()
    * for arrays of structs. Indirect sampler and image indexing is handled
    * elsewhere.
    */
   int element_size = ir->type->without_array()->is_struct() ?
      ir->type->count_vec4_slots(false, var->data.bindless) :
      type_size(ir->type);

   index = ir->array_index->constant_expression_value(ralloc_parent(ir));

   ir->array->accept(this);
   src = this->result;

   if (!src.has_index2) {
      switch (this->prog->Target) {
      case GL_TESS_CONTROL_PROGRAM_NV:
         is_2D = (src.file == PROGRAM_INPUT || src.file == PROGRAM_OUTPUT) &&
                 !ir->variable_referenced()->data.patch;
         break;
      case GL_TESS_EVALUATION_PROGRAM_NV:
         is_2D = src.file == PROGRAM_INPUT &&
                 !ir->variable_referenced()->data.patch;
         break;
      case GL_GEOMETRY_PROGRAM_NV:
         is_2D = src.file == PROGRAM_INPUT;
         break;
      }
   }

   if (is_2D)
      element_size = 1;

   if (index) {

      if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
          src.file == PROGRAM_INPUT)
         element_size = attrib_type_size(ir->type, true);
      if (is_2D) {
         src.index2D = index->value.i[0];
         src.has_index2 = true;
      } else
         src.index += index->value.i[0] * element_size;
   } else {
      /* Variable index array dereference.  It eats the "vec4" of the
       * base of the array and an index that offsets the TGSI register
       * index.
       */
      ir->array_index->accept(this);

      st_src_reg index_reg;

      if (element_size == 1) {
         index_reg = this->result;
      } else {
         index_reg = get_temp(native_integers ?
                              glsl_type::int_type : glsl_type::float_type);

         emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg),
              this->result, st_src_reg_for_type(index_reg.type, element_size));
      }

      /* If there was already a relative address register involved, add the
       * new and the old together to get the new offset.
       */
      if (!is_2D && src.reladdr != NULL) {
         st_src_reg accum_reg = get_temp(native_integers ?
                                glsl_type::int_type : glsl_type::float_type);

         emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg),
              index_reg, *src.reladdr);

         index_reg = accum_reg;
      }

      if (is_2D) {
         src.reladdr2 = ralloc(mem_ctx, st_src_reg);
         *src.reladdr2 = index_reg;
         src.index2D = 0;
         src.has_index2 = true;
      } else {
         src.reladdr = ralloc(mem_ctx, st_src_reg);
         *src.reladdr = index_reg;
      }
   }

   /* Change the register type to the element type of the array. */
   src.type = ir->type->base_type;

   this->result = src;
}

void
glsl_to_tgsi_visitor::visit(ir_dereference_record *ir)
{
   unsigned int i;
   const glsl_type *struct_type = ir->record->type;
   ir_variable *var = ir->record->variable_referenced();
   int offset = 0;

   if (handle_bound_deref(ir->as_dereference()))
      return;

   ir->record->accept(this);

   assert(ir->field_idx >= 0);
   assert(var);
   for (i = 0; i < struct_type->length; i++) {
      if (i == (unsigned) ir->field_idx)
         break;
      const glsl_type *member_type = struct_type->fields.structure[i].type;
      offset += member_type->count_vec4_slots(false, var->data.bindless);
   }

   /* If the type is smaller than a vec4, replicate the last channel out. */
   if (ir->type->is_scalar() || ir->type->is_vector())
      this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
   else
      this->result.swizzle = SWIZZLE_NOOP;

   this->result.index += offset;
   this->result.type = ir->type->base_type;
}

/**
 * We want to be careful in assignment setup to hit the actual storage
 * instead of potentially using a temporary like we might with the
 * ir_dereference handler.
 */
static st_dst_reg
get_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v, int *component)
{
   /* The LHS must be a dereference.  If the LHS is a variable indexed array
    * access of a vector, it must be separated into a series conditional moves
    * before reaching this point (see ir_vec_index_to_cond_assign).
    */
   assert(ir->as_dereference());
   ir_dereference_array *deref_array = ir->as_dereference_array();
   if (deref_array) {
      assert(!deref_array->array->type->is_vector());
   }

   /* Use the rvalue deref handler for the most part.  We write swizzles using
    * the writemask, but we do extract the base component for enhanced layouts
    * from the source swizzle.
    */
   ir->accept(v);
   *component = GET_SWZ(v->result.swizzle, 0);
   return st_dst_reg(v->result);
}

/**
 * Process the condition of a conditional assignment
 *
 * Examines the condition of a conditional assignment to generate the optimal
 * first operand of a \c CMP instruction.  If the condition is a relational
 * operator with 0 (e.g., \c ir_binop_less), the value being compared will be
 * used as the source for the \c CMP instruction.  Otherwise the comparison
 * is processed to a boolean result, and the boolean result is used as the
 * operand to the CMP instruction.
 */
bool
glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
{
   ir_rvalue *src_ir = ir;
   bool negate = true;
   bool switch_order = false;

   ir_expression *const expr = ir->as_expression();

   if (native_integers) {
      if ((expr != NULL) && (expr->num_operands == 2)) {
         enum glsl_base_type type = expr->operands[0]->type->base_type;
         if (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT ||
             type == GLSL_TYPE_BOOL) {
            if (expr->operation == ir_binop_equal) {
               if (expr->operands[0]->is_zero()) {
                  src_ir = expr->operands[1];
                  switch_order = true;
               }
               else if (expr->operands[1]->is_zero()) {
                  src_ir = expr->operands[0];
                  switch_order = true;
               }
            }
            else if (expr->operation == ir_binop_nequal) {
               if (expr->operands[0]->is_zero()) {
                  src_ir = expr->operands[1];
               }
               else if (expr->operands[1]->is_zero()) {
                  src_ir = expr->operands[0];
               }
            }
         }
      }

      src_ir->accept(this);
      return switch_order;
   }

   if ((expr != NULL) && (expr->num_operands == 2)) {
      bool zero_on_left = false;

      if (expr->operands[0]->is_zero()) {
         src_ir = expr->operands[1];
         zero_on_left = true;
      } else if (expr->operands[1]->is_zero()) {
         src_ir = expr->operands[0];
         zero_on_left = false;
      }

      /*      a is -  0  +            -  0  +
       * (a <  0)  T  F  F  ( a < 0)  T  F  F
       * (0 <  a)  F  F  T  (-a < 0)  F  F  T
       * (a >= 0)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
       * (0 >= a)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
       *
       * Note that exchanging the order of 0 and 'a' in the comparison simply
       * means that the value of 'a' should be negated.
       */
      if (src_ir != ir) {
         switch (expr->operation) {
         case ir_binop_less:
            switch_order = false;
            negate = zero_on_left;
            break;

         case ir_binop_gequal:
            switch_order = true;
            negate = zero_on_left;
            break;

         default:
            /* This isn't the right kind of comparison afterall, so make sure
             * the whole condition is visited.
             */
            src_ir = ir;
            break;
         }
      }
   }

   src_ir->accept(this);

   /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the
    * condition we produced is 0.0 or 1.0.  By flipping the sign, we can
    * choose which value TGSI_OPCODE_CMP produces without an extra instruction
    * computing the condition.
    */
   if (negate)
      this->result.negate = ~this->result.negate;

   return switch_order;
}

void
glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type *type,
                                     st_dst_reg *l, st_src_reg *r,
                                     st_src_reg *cond, bool cond_swap)
{
   if (type->is_struct()) {
      for (unsigned int i = 0; i < type->length; i++) {
         emit_block_mov(ir, type->fields.structure[i].type, l, r,
                        cond, cond_swap);
      }
      return;
   }

   if (type->is_array()) {
      for (unsigned int i = 0; i < type->length; i++) {
         emit_block_mov(ir, type->fields.array, l, r, cond, cond_swap);
      }
      return;
   }

   if (type->is_matrix()) {
      const struct glsl_type *vec_type;

      vec_type = glsl_type::get_instance(type->is_double()
                                         ? GLSL_TYPE_DOUBLE : GLSL_TYPE_FLOAT,
                                         type->vector_elements, 1);

      for (int i = 0; i < type->matrix_columns; i++) {
         emit_block_mov(ir, vec_type, l, r, cond, cond_swap);
      }
      return;
   }

   assert(type->is_scalar() || type->is_vector());

   l->type = type->base_type;
   r->type = type->base_type;
   if (cond) {
      st_src_reg l_src = st_src_reg(*l);

      if (l_src.file == PROGRAM_OUTPUT &&
          this->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
          (l_src.index == FRAG_RESULT_DEPTH ||
           l_src.index == FRAG_RESULT_STENCIL)) {
         /* This is a special case because the source swizzles will be shifted
          * later to account for the difference between GLSL (where they're
          * plain floats) and TGSI (where they're Z and Y components). */
         l_src.swizzle = SWIZZLE_XXXX;
      }

      if (native_integers) {
         emit_asm(ir, TGSI_OPCODE_UCMP, *l, *cond,
              cond_swap ? l_src : *r,
              cond_swap ? *r : l_src);
      } else {
         emit_asm(ir, TGSI_OPCODE_CMP, *l, *cond,
              cond_swap ? l_src : *r,
              cond_swap ? *r : l_src);
      }
   } else {
      emit_asm(ir, TGSI_OPCODE_MOV, *l, *r);
   }
   l->index++;
   r->index++;
   if (type->is_dual_slot()) {
      l->index++;
      if (r->is_double_vertex_input == false)
         r->index++;
   }
}

void
glsl_to_tgsi_visitor::visit(ir_assignment *ir)
{
   int dst_component;
   st_dst_reg l;
   st_src_reg r;

   /* all generated instructions need to be flaged as precise */
   this->precise = is_precise(ir->lhs->variable_referenced());
   ir->rhs->accept(this);
   r = this->result;

   l = get_assignment_lhs(ir->lhs, this, &dst_component);

   {
      int swizzles[4];
      int first_enabled_chan = 0;
      int rhs_chan = 0;
      ir_variable *variable = ir->lhs->variable_referenced();

      if (shader->Stage == MESA_SHADER_FRAGMENT &&
          variable->data.mode == ir_var_shader_out &&
          (variable->data.location == FRAG_RESULT_DEPTH ||
           variable->data.location == FRAG_RESULT_STENCIL)) {
         assert(ir->lhs->type->is_scalar());
         assert(ir->write_mask == WRITEMASK_X);

         if (variable->data.location == FRAG_RESULT_DEPTH)
            l.writemask = WRITEMASK_Z;
         else {
            assert(variable->data.location == FRAG_RESULT_STENCIL);
            l.writemask = WRITEMASK_Y;
         }
      } else if (ir->write_mask == 0) {
         assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());

         unsigned num_elements =
            ir->lhs->type->without_array()->vector_elements;

         if (num_elements) {
            l.writemask = u_bit_consecutive(0, num_elements);
         } else {
            /* The type is a struct or an array of (array of) structs. */
            l.writemask = WRITEMASK_XYZW;
         }
      } else {
         l.writemask = ir->write_mask;
      }

      for (int i = 0; i < 4; i++) {
         if (l.writemask & (1 << i)) {
            first_enabled_chan = GET_SWZ(r.swizzle, i);
            break;
         }
      }

      l.writemask = l.writemask << dst_component;

      /* Swizzle a small RHS vector into the channels being written.
       *
       * glsl ir treats write_mask as dictating how many channels are
       * present on the RHS while TGSI treats write_mask as just
       * showing which channels of the vec4 RHS get written.
       */
      for (int i = 0; i < 4; i++) {
         if (l.writemask & (1 << i))
            swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++);
         else
            swizzles[i] = first_enabled_chan;
      }
      r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1],
                                swizzles[2], swizzles[3]);
   }

   assert(l.file != PROGRAM_UNDEFINED);
   assert(r.file != PROGRAM_UNDEFINED);

   if (ir->condition) {
      const bool switch_order = this->process_move_condition(ir->condition);
      st_src_reg condition = this->result;

      emit_block_mov(ir, ir->lhs->type, &l, &r, &condition, switch_order);
   } else if (ir->rhs->as_expression() &&
              this->instructions.get_tail() &&
              ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir &&
              !((glsl_to_tgsi_instruction *)this->instructions.get_tail())->is_64bit_expanded &&
              type_size(ir->lhs->type) == 1 &&
              l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst[0].writemask) {
      /* To avoid emitting an extra MOV when assigning an expression to a
       * variable, emit the last instruction of the expression again, but
       * replace the destination register with the target of the assignment.
       * Dead code elimination will remove the original instruction.
       */
      glsl_to_tgsi_instruction *inst, *new_inst;
      inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3]);
      new_inst->saturate = inst->saturate;
      new_inst->resource = inst->resource;
      inst->dead_mask = inst->dst[0].writemask;
   } else {
      emit_block_mov(ir, ir->rhs->type, &l, &r, NULL, false);
   }
   this->precise = 0;
}


void
glsl_to_tgsi_visitor::visit(ir_constant *ir)
{
   st_src_reg src;
   GLdouble stack_vals[4] = { 0 };
   gl_constant_value *values = (gl_constant_value *) stack_vals;
   GLenum gl_type = GL_NONE;
   unsigned int i, elements;
   static int in_array = 0;
   gl_register_file file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE;

   /* Unfortunately, 4 floats is all we can get into
    * _mesa_add_typed_unnamed_constant.  So, make a temp to store an
    * aggregate constant and move each constant value into it.  If we
    * get lucky, copy propagation will eliminate the extra moves.
    */
   if (ir->type->is_struct()) {
      st_src_reg temp_base = get_temp(ir->type);
      st_dst_reg temp = st_dst_reg(temp_base);

      for (i = 0; i < ir->type->length; i++) {
         ir_constant *const field_value = ir->get_record_field(i);
         int size = type_size(field_value->type);

         assert(size > 0);

         field_value->accept(this);
         src = this->result;

         for (unsigned j = 0; j < (unsigned int)size; j++) {
            emit_asm(ir, TGSI_OPCODE_MOV, temp, src);

            src.index++;
            temp.index++;
         }
      }
      this->result = temp_base;
      return;
   }

   if (ir->type->is_array()) {
      st_src_reg temp_base = get_temp(ir->type);
      st_dst_reg temp = st_dst_reg(temp_base);
      int size = type_size(ir->type->fields.array);

      assert(size > 0);
      in_array++;

      for (i = 0; i < ir->type->length; i++) {
         ir->const_elements[i]->accept(this);
         src = this->result;
         for (int j = 0; j < size; j++) {
            emit_asm(ir, TGSI_OPCODE_MOV, temp, src);

            src.index++;
            temp.index++;
         }
      }
      this->result = temp_base;
      in_array--;
      return;
   }

   if (ir->type->is_matrix()) {
      st_src_reg mat = get_temp(ir->type);
      st_dst_reg mat_column = st_dst_reg(mat);

      for (i = 0; i < ir->type->matrix_columns; i++) {
         switch (ir->type->base_type) {
         case GLSL_TYPE_FLOAT:
            values = (gl_constant_value *)
               &ir->value.f[i * ir->type->vector_elements];

            src = st_src_reg(file, -1, ir->type->base_type);
            src.index = add_constant(file,
                                     values,
                                     ir->type->vector_elements,
                                     GL_FLOAT,
                                     &src.swizzle);
            emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
            break;
         case GLSL_TYPE_DOUBLE:
            values = (gl_constant_value *)
               &ir->value.d[i * ir->type->vector_elements];
            src = st_src_reg(file, -1, ir->type->base_type);
            src.index = add_constant(file,
                                     values,
                                     ir->type->vector_elements,
                                     GL_DOUBLE,
                                     &src.swizzle);
            if (ir->type->vector_elements >= 2) {
               mat_column.writemask = WRITEMASK_XY;
               src.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
                                           SWIZZLE_X, SWIZZLE_Y);
               emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
            } else {
               mat_column.writemask = WRITEMASK_X;
               src.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
                                           SWIZZLE_X, SWIZZLE_X);
               emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
            }
            src.index++;
            if (ir->type->vector_elements > 2) {
               if (ir->type->vector_elements == 4) {
                  mat_column.writemask = WRITEMASK_ZW;
                  src.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
                                              SWIZZLE_X, SWIZZLE_Y);
                  emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
               } else {
                  mat_column.writemask = WRITEMASK_Z;
                  src.swizzle = MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y,
                                              SWIZZLE_Y, SWIZZLE_Y);
                  emit_asm(ir, TGSI_OPCODE_MOV, mat_column, src);
                  mat_column.writemask = WRITEMASK_XYZW;
                  src.swizzle = SWIZZLE_XYZW;
               }
               mat_column.index++;
            }
            break;
         default:
            unreachable("Illegal matrix constant type.\n");
            break;
         }
         mat_column.index++;
      }
      this->result = mat;
      return;
   }

   elements = ir->type->vector_elements;
   switch (ir->type->base_type) {
   case GLSL_TYPE_FLOAT:
      gl_type = GL_FLOAT;
      for (i = 0; i < ir->type->vector_elements; i++) {
         values[i].f = ir->value.f[i];
      }
      break;
   case GLSL_TYPE_DOUBLE:
      gl_type = GL_DOUBLE;
      for (i = 0; i < ir->type->vector_elements; i++) {
         memcpy(&values[i * 2], &ir->value.d[i], sizeof(double));
      }
      break;
   case GLSL_TYPE_INT64:
      gl_type = GL_INT64_ARB;
      for (i = 0; i < ir->type->vector_elements; i++) {
         memcpy(&values[i * 2], &ir->value.d[i], sizeof(int64_t));
      }
      break;
   case GLSL_TYPE_UINT64:
      gl_type = GL_UNSIGNED_INT64_ARB;
      for (i = 0; i < ir->type->vector_elements; i++) {
         memcpy(&values[i * 2], &ir->value.d[i], sizeof(uint64_t));
      }
      break;
   case GLSL_TYPE_UINT:
      gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT;
      for (i = 0; i < ir->type->vector_elements; i++) {
         if (native_integers)
            values[i].u = ir->value.u[i];
         else
            values[i].f = ir->value.u[i];
      }
      break;
   case GLSL_TYPE_INT:
      gl_type = native_integers ? GL_INT : GL_FLOAT;
      for (i = 0; i < ir->type->vector_elements; i++) {
         if (native_integers)
            values[i].i = ir->value.i[i];
         else
            values[i].f = ir->value.i[i];
      }
      break;
   case GLSL_TYPE_BOOL:
      gl_type = native_integers ? GL_BOOL : GL_FLOAT;
      for (i = 0; i < ir->type->vector_elements; i++) {
         values[i].u = ir->value.b[i] ? ctx->Const.UniformBooleanTrue : 0;
      }
      break;
   case GLSL_TYPE_SAMPLER:
   case GLSL_TYPE_IMAGE:
      gl_type = GL_UNSIGNED_INT;
      elements = 2;
      values[0].u = ir->value.u64[0] & 0xffffffff;
      values[1].u = ir->value.u64[0] >> 32;
      break;
   default:
      assert(!"Non-float/uint/int/bool/sampler/image constant");
   }

   this->result = st_src_reg(file, -1, ir->type);
   this->result.index = add_constant(file,
                                     values,
                                     elements,
                                     gl_type,
                                     &this->result.swizzle);
}

void
glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
{
   exec_node *param = ir->actual_parameters.get_head();
   ir_dereference *deref = static_cast<ir_dereference *>(param);
   ir_variable *location = deref->variable_referenced();
   bool has_hw_atomics = st_context(ctx)->has_hw_atomics;
   /* Calculate the surface offset */
   st_src_reg offset;
   unsigned array_size = 0, base = 0;
   uint16_t index = 0;
   st_src_reg resource;

   get_deref_offsets(deref, &array_size, &base, &index, &offset, false);

   if (has_hw_atomics) {
      variable_storage *entry = find_variable_storage(location);
      st_src_reg buffer(PROGRAM_HW_ATOMIC, 0, GLSL_TYPE_ATOMIC_UINT,
                        location->data.binding);

      if (!entry) {
         entry = new(mem_ctx) variable_storage(location, PROGRAM_HW_ATOMIC,
                                               num_atomics);
         _mesa_hash_table_insert(this->variables, location, entry);

         atomic_info[num_atomics].location = location->data.location;
         atomic_info[num_atomics].binding = location->data.binding;
         atomic_info[num_atomics].size = location->type->arrays_of_arrays_size();
         if (atomic_info[num_atomics].size == 0)
            atomic_info[num_atomics].size = 1;
         atomic_info[num_atomics].array_id = 0;
         num_atomics++;
      }

      if (offset.file != PROGRAM_UNDEFINED) {
         if (atomic_info[entry->index].array_id == 0) {
            num_atomic_arrays++;
            atomic_info[entry->index].array_id = num_atomic_arrays;
         }
         buffer.array_id = atomic_info[entry->index].array_id;
      }

      buffer.index = index;
      buffer.index += location->data.offset / ATOMIC_COUNTER_SIZE;
      buffer.has_index2 = true;

      if (offset.file != PROGRAM_UNDEFINED) {
         buffer.reladdr = ralloc(mem_ctx, st_src_reg);
         *buffer.reladdr = offset;
         emit_arl(ir, sampler_reladdr, offset);
      }
      offset = st_src_reg_for_int(0);

      resource = buffer;
   } else {
      st_src_reg buffer(PROGRAM_BUFFER,
                        prog->info.num_ssbos +
                        location->data.binding,
                        GLSL_TYPE_ATOMIC_UINT);

      if (offset.file != PROGRAM_UNDEFINED) {
         emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(offset),
                  offset, st_src_reg_for_int(ATOMIC_COUNTER_SIZE));
         emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(offset),
                  offset, st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE));
      } else {
         offset = st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE);
      }
      resource = buffer;
   }

   ir->return_deref->accept(this);
   st_dst_reg dst(this->result);
   dst.writemask = WRITEMASK_X;

   glsl_to_tgsi_instruction *inst;

   if (ir->callee->intrinsic_id == ir_intrinsic_atomic_counter_read) {
      inst = emit_asm(ir, TGSI_OPCODE_LOAD, dst, offset);
   } else if (ir->callee->intrinsic_id == ir_intrinsic_atomic_counter_increment) {
      inst = emit_asm(ir, TGSI_OPCODE_ATOMUADD, dst, offset,
                      st_src_reg_for_int(1));
   } else if (ir->callee->intrinsic_id == ir_intrinsic_atomic_counter_predecrement) {
      inst = emit_asm(ir, TGSI_OPCODE_ATOMUADD, dst, offset,
                      st_src_reg_for_int(-1));
      emit_asm(ir, TGSI_OPCODE_ADD, dst, this->result, st_src_reg_for_int(-1));
   } else {
      param = param->get_next();
      ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
      val->accept(this);

      st_src_reg data = this->result, data2 = undef_src;
      enum tgsi_opcode opcode;
      switch (ir->callee->intrinsic_id) {
      case ir_intrinsic_atomic_counter_add:
         opcode = TGSI_OPCODE_ATOMUADD;
         break;
      case ir_intrinsic_atomic_counter_min:
         opcode = TGSI_OPCODE_ATOMIMIN;
         break;
      case ir_intrinsic_atomic_counter_max:
         opcode = TGSI_OPCODE_ATOMIMAX;
         break;
      case ir_intrinsic_atomic_counter_and:
         opcode = TGSI_OPCODE_ATOMAND;
         break;
      case ir_intrinsic_atomic_counter_or:
         opcode = TGSI_OPCODE_ATOMOR;
         break;
      case ir_intrinsic_atomic_counter_xor:
         opcode = TGSI_OPCODE_ATOMXOR;
         break;
      case ir_intrinsic_atomic_counter_exchange:
         opcode = TGSI_OPCODE_ATOMXCHG;
         break;
      case ir_intrinsic_atomic_counter_comp_swap: {
         opcode = TGSI_OPCODE_ATOMCAS;
         param = param->get_next();
         val = ((ir_instruction *)param)->as_rvalue();
         val->accept(this);
         data2 = this->result;
         break;
      }
      default:
         assert(!"Unexpected intrinsic");
         return;
      }

      inst = emit_asm(ir, opcode, dst, offset, data, data2);
   }

   inst->resource = resource;
}

void
glsl_to_tgsi_visitor::visit_ssbo_intrinsic(ir_call *ir)
{
   exec_node *param = ir->actual_parameters.get_head();

   ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();

   param = param->get_next();
   ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();

   ir_constant *const_block = block->as_constant();
   st_src_reg buffer(
         PROGRAM_BUFFER,
         const_block ? const_block->value.u[0] : 0,
         GLSL_TYPE_UINT);

   if (!const_block) {
      block->accept(this);
      buffer.reladdr = ralloc(mem_ctx, st_src_reg);
      *buffer.reladdr = this->result;
      emit_arl(ir, sampler_reladdr, this->result);
   }

   /* Calculate the surface offset */
   offset->accept(this);
   st_src_reg off = this->result;

   st_dst_reg dst = undef_dst;
   if (ir->return_deref) {
      ir->return_deref->accept(this);
      dst = st_dst_reg(this->result);
      dst.writemask = (1 << ir->return_deref->type->vector_elements) - 1;
   }

   glsl_to_tgsi_instruction *inst;

   if (ir->callee->intrinsic_id == ir_intrinsic_ssbo_load) {
      inst = emit_asm(ir, TGSI_OPCODE_LOAD, dst, off);
      if (dst.type == GLSL_TYPE_BOOL)
         emit_asm(ir, TGSI_OPCODE_USNE, dst, st_src_reg(dst),
                  st_src_reg_for_int(0));
   } else if (ir->callee->intrinsic_id == ir_intrinsic_ssbo_store) {
      param = param->get_next();
      ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
      val->accept(this);

      param = param->get_next();
      ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
      assert(write_mask);
      dst.writemask = write_mask->value.u[0];

      dst.type = this->result.type;
      inst = emit_asm(ir, TGSI_OPCODE_STORE, dst, off, this->result);
   } else {
      param = param->get_next();
      ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
      val->accept(this);

      st_src_reg data = this->result, data2 = undef_src;
      enum tgsi_opcode opcode;
      switch (ir->callee->intrinsic_id) {
      case ir_intrinsic_ssbo_atomic_add:
         opcode = TGSI_OPCODE_ATOMUADD;
         break;
      case ir_intrinsic_ssbo_atomic_min:
         opcode = TGSI_OPCODE_ATOMIMIN;
         break;
      case ir_intrinsic_ssbo_atomic_max:
         opcode = TGSI_OPCODE_ATOMIMAX;
         break;
      case ir_intrinsic_ssbo_atomic_and:
         opcode = TGSI_OPCODE_ATOMAND;
         break;
      case ir_intrinsic_ssbo_atomic_or:
         opcode = TGSI_OPCODE_ATOMOR;
         break;
      case ir_intrinsic_ssbo_atomic_xor:
         opcode = TGSI_OPCODE_ATOMXOR;
         break;
      case ir_intrinsic_ssbo_atomic_exchange:
         opcode = TGSI_OPCODE_ATOMXCHG;
         break;
      case ir_intrinsic_ssbo_atomic_comp_swap:
         opcode = TGSI_OPCODE_ATOMCAS;
         param = param->get_next();
         val = ((ir_instruction *)param)->as_rvalue();
         val->accept(this);
         data2 = this->result;
         break;
      default:
         assert(!"Unexpected intrinsic");
         return;
      }

      inst = emit_asm(ir, opcode, dst, off, data, data2);
   }

   param = param->get_next();
   ir_constant *access = NULL;
   if (!param->is_tail_sentinel()) {
      access = ((ir_instruction *)param)->as_constant();
      assert(access);
   }

   add_buffer_to_load_and_stores(inst, &buffer, &this->instructions, access);
}

void
glsl_to_tgsi_visitor::visit_membar_intrinsic(ir_call *ir)
{
   switch (ir->callee->intrinsic_id) {
   case ir_intrinsic_memory_barrier:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_SHADER_BUFFER |
                                  TGSI_MEMBAR_ATOMIC_BUFFER |
                                  TGSI_MEMBAR_SHADER_IMAGE |
                                  TGSI_MEMBAR_SHARED));
      break;
   case ir_intrinsic_memory_barrier_atomic_counter:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_ATOMIC_BUFFER));
      break;
   case ir_intrinsic_memory_barrier_buffer:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_SHADER_BUFFER));
      break;
   case ir_intrinsic_memory_barrier_image:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_SHADER_IMAGE));
      break;
   case ir_intrinsic_memory_barrier_shared:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_SHARED));
      break;
   case ir_intrinsic_group_memory_barrier:
      emit_asm(ir, TGSI_OPCODE_MEMBAR, undef_dst,
               st_src_reg_for_int(TGSI_MEMBAR_SHADER_BUFFER |
                                  TGSI_MEMBAR_ATOMIC_BUFFER |
                                  TGSI_MEMBAR_SHADER_IMAGE |
                                  TGSI_MEMBAR_SHARED |
                                  TGSI_MEMBAR_THREAD_GROUP));
      break;
   default:
      assert(!"Unexpected memory barrier intrinsic");
   }
}

void
glsl_to_tgsi_visitor::visit_shared_intrinsic(ir_call *ir)
{
   exec_node *param = ir->actual_parameters.get_head();

   ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();

   st_src_reg buffer(PROGRAM_MEMORY, 0, GLSL_TYPE_UINT);

   /* Calculate the surface offset */
   offset->accept(this);
   st_src_reg off = this->result;

   st_dst_reg dst = undef_dst;
   if (ir->return_deref) {
      ir->return_deref->accept(this);
      dst = st_dst_reg(this->result);
      dst.writemask = (1 << ir->return_deref->type->vector_elements) - 1;
   }

   glsl_to_tgsi_instruction *inst;

   if (ir->callee->intrinsic_id == ir_intrinsic_shared_load) {
      inst = emit_asm(ir, TGSI_OPCODE_LOAD, dst, off);
      inst->resource = buffer;
   } else if (ir->callee->intrinsic_id == ir_intrinsic_shared_store) {
      param = param->get_next();
      ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
      val->accept(this);

      param = param->get_next();
      ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
      assert(write_mask);
      dst.writemask = write_mask->value.u[0];

      dst.type = this->result.type;
      inst = emit_asm(ir, TGSI_OPCODE_STORE, dst, off, this->result);
      inst->resource = buffer;
   } else {
      param = param->get_next();
      ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
      val->accept(this);

      st_src_reg data = this->result, data2 = undef_src;
      enum tgsi_opcode opcode;
      switch (ir->callee->intrinsic_id) {
      case ir_intrinsic_shared_atomic_add:
         opcode = TGSI_OPCODE_ATOMUADD;
         break;
      case ir_intrinsic_shared_atomic_min:
         opcode = TGSI_OPCODE_ATOMIMIN;
         break;
      case ir_intrinsic_shared_atomic_max:
         opcode = TGSI_OPCODE_ATOMIMAX;
         break;
      case ir_intrinsic_shared_atomic_and:
         opcode = TGSI_OPCODE_ATOMAND;
         break;
      case ir_intrinsic_shared_atomic_or:
         opcode = TGSI_OPCODE_ATOMOR;
         break;
      case ir_intrinsic_shared_atomic_xor:
         opcode = TGSI_OPCODE_ATOMXOR;
         break;
      case ir_intrinsic_shared_atomic_exchange:
         opcode = TGSI_OPCODE_ATOMXCHG;
         break;
      case ir_intrinsic_shared_atomic_comp_swap:
         opcode = TGSI_OPCODE_ATOMCAS;
         param = param->get_next();
         val = ((ir_instruction *)param)->as_rvalue();
         val->accept(this);
         data2 = this->result;
         break;
      default:
         assert(!"Unexpected intrinsic");
         return;
      }

      inst = emit_asm(ir, opcode, dst, off, data, data2);
      inst->resource = buffer;
   }
}

static void
get_image_qualifiers(ir_dereference *ir, const glsl_type **type,
                     bool *memory_coherent, bool *memory_volatile,
                     bool *memory_restrict, bool *memory_read_only,
                     unsigned *image_format)
{

   switch (ir->ir_type) {
   case ir_type_dereference_record: {
      ir_dereference_record *deref_record = ir->as_dereference_record();
      const glsl_type *struct_type = deref_record->record->type;
      int fild_idx = deref_record->field_idx;

      *type = struct_type->fields.structure[fild_idx].type->without_array();
      *memory_coherent =
         struct_type->fields.structure[fild_idx].memory_coherent;
      *memory_volatile =
         struct_type->fields.structure[fild_idx].memory_volatile;
      *memory_restrict =
         struct_type->fields.structure[fild_idx].memory_restrict;
      *memory_read_only =
         struct_type->fields.structure[fild_idx].memory_read_only;
      *image_format =
         struct_type->fields.structure[fild_idx].image_format;
      break;
   }

   case ir_type_dereference_array: {
      ir_dereference_array *deref_arr = ir->as_dereference_array();
      get_image_qualifiers((ir_dereference *)deref_arr->array, type,
                           memory_coherent, memory_volatile, memory_restrict,
                           memory_read_only, image_format);
      break;
   }

   case ir_type_dereference_variable: {
      ir_variable *var = ir->variable_referenced();

      *type = var->type->without_array();
      *memory_coherent = var->data.memory_coherent;
      *memory_volatile = var->data.memory_volatile;
      *memory_restrict = var->data.memory_restrict;
      *memory_read_only = var->data.memory_read_only;
      *image_format = var->data.image_format;
      break;
   }

   default:
      break;
   }
}

void
glsl_to_tgsi_visitor::visit_image_intrinsic(ir_call *ir)
{
   exec_node *param = ir->actual_parameters.get_head();

   ir_dereference *img = (ir_dereference *)param;
   const ir_variable *imgvar = img->variable_referenced();
   unsigned sampler_array_size = 1, sampler_base = 0;
   bool memory_coherent = false, memory_volatile = false,
        memory_restrict = false, memory_read_only = false;
   unsigned image_format = 0;
   const glsl_type *type = NULL;

   get_image_qualifiers(img, &type, &memory_coherent, &memory_volatile,
                        &memory_restrict, &memory_read_only, &image_format);

   st_src_reg reladdr;
   st_src_reg image(PROGRAM_IMAGE, 0, GLSL_TYPE_UINT);
   uint16_t index = 0;
   get_deref_offsets(img, &sampler_array_size, &sampler_base,
                     &index, &reladdr, !imgvar->contains_bindless());

   image.index = index;
   if (reladdr.file != PROGRAM_UNDEFINED) {
      image.reladdr = ralloc(mem_ctx, st_src_reg);
      *image.reladdr = reladdr;
      emit_arl(ir, sampler_reladdr, reladdr);
   }

   st_dst_reg dst = undef_dst;
   if (ir->return_deref) {
      ir->return_deref->accept(this);
      dst = st_dst_reg(this->result);
      dst.writemask = (1 << ir->return_deref->type->vector_elements) - 1;
   }

   glsl_to_tgsi_instruction *inst;

   st_src_reg bindless;
   if (imgvar->contains_bindless()) {
      img->accept(this);
      bindless = this->result;
   }

   if (ir->callee->intrinsic_id == ir_intrinsic_image_size) {
      dst.writemask = WRITEMASK_XYZ;
      inst = emit_asm(ir, TGSI_OPCODE_RESQ, dst);
   } else if (ir->callee->intrinsic_id == ir_intrinsic_image_samples) {
      st_src_reg res = get_temp(glsl_type::ivec4_type);
      st_dst_reg dstres = st_dst_reg(res);
      dstres.writemask = WRITEMASK_W;
      inst = emit_asm(ir, TGSI_OPCODE_RESQ, dstres);
      res.swizzle = SWIZZLE_WWWW;
      emit_asm(ir, TGSI_OPCODE_MOV, dst, res);
   } else {
      st_src_reg arg1 = undef_src, arg2 = undef_src;
      st_src_reg coord;
      st_dst_reg coord_dst;
      coord = get_temp(glsl_type::ivec4_type);
      coord_dst = st_dst_reg(coord);
      coord_dst.writemask = (1 << type->coordinate_components()) - 1;
      param = param->get_next();
      ((ir_dereference *)param)->accept(this);
      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
      coord.swizzle = SWIZZLE_XXXX;
      switch (type->coordinate_components()) {
      case 4: assert(!"unexpected coord count");
      /* fallthrough */
      case 3: coord.swizzle |= SWIZZLE_Z << 6;
      /* fallthrough */
      case 2: coord.swizzle |= SWIZZLE_Y << 3;
      }

      if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
         param = param->get_next();
         ((ir_dereference *)param)->accept(this);
         st_src_reg sample = this->result;
         sample.swizzle = SWIZZLE_XXXX;
         coord_dst.writemask = WRITEMASK_W;
         emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, sample);
         coord.swizzle |= SWIZZLE_W << 9;
      }

      param = param->get_next();
      if (!param->is_tail_sentinel()) {
         ((ir_dereference *)param)->accept(this);
         arg1 = this->result;
         param = param->get_next();
      }

      if (!param->is_tail_sentinel()) {
         ((ir_dereference *)param)->accept(this);
         arg2 = this->result;
         param = param->get_next();
      }

      assert(param->is_tail_sentinel());

      enum tgsi_opcode opcode;
      switch (ir->callee->intrinsic_id) {
      case ir_intrinsic_image_load:
         opcode = TGSI_OPCODE_LOAD;
         break;
      case ir_intrinsic_image_store:
         opcode = TGSI_OPCODE_STORE;
         break;
      case ir_intrinsic_image_atomic_add:
         opcode = TGSI_OPCODE_ATOMUADD;
         break;
      case ir_intrinsic_image_atomic_min:
         opcode = TGSI_OPCODE_ATOMIMIN;
         break;
      case ir_intrinsic_image_atomic_max:
         opcode = TGSI_OPCODE_ATOMIMAX;
         break;
      case ir_intrinsic_image_atomic_and:
         opcode = TGSI_OPCODE_ATOMAND;
         break;
      case ir_intrinsic_image_atomic_or:
         opcode = TGSI_OPCODE_ATOMOR;
         break;
      case ir_intrinsic_image_atomic_xor:
         opcode = TGSI_OPCODE_ATOMXOR;
         break;
      case ir_intrinsic_image_atomic_exchange:
         opcode = TGSI_OPCODE_ATOMXCHG;
         break;
      case ir_intrinsic_image_atomic_comp_swap:
         opcode = TGSI_OPCODE_ATOMCAS;
         break;
      case ir_intrinsic_image_atomic_inc_wrap: {
         /* There's a bit of disagreement between GLSL and the hardware. The
          * hardware wants to wrap after the given wrap value, while GLSL
          * wants to wrap at the value. Subtract 1 to make up the difference.
          */
         st_src_reg wrap = get_temp(glsl_type::uint_type);
         emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(wrap),
                  arg1, st_src_reg_for_int(-1));
         arg1 = wrap;
         opcode = TGSI_OPCODE_ATOMINC_WRAP;
         break;
      }
      case ir_intrinsic_image_atomic_dec_wrap:
         opcode = TGSI_OPCODE_ATOMDEC_WRAP;
         break;
      default:
         assert(!"Unexpected intrinsic");
         return;
      }

      inst = emit_asm(ir, opcode, dst, coord, arg1, arg2);
      if (opcode == TGSI_OPCODE_STORE)
         inst->dst[0].writemask = WRITEMASK_XYZW;
   }

   if (imgvar->contains_bindless()) {
      inst->resource = bindless;
      inst->resource.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
                                             SWIZZLE_X, SWIZZLE_Y);
   } else {
      inst->resource = image;
      inst->sampler_array_size = sampler_array_size;
      inst->sampler_base = sampler_base;
   }

   inst->tex_target = type->sampler_index();
   inst->image_format = st_mesa_format_to_pipe_format(st_context(ctx),
         _mesa_get_shader_image_format(image_format));
   inst->read_only = memory_read_only;

   if (memory_coherent)
      inst->buffer_access |= TGSI_MEMORY_COHERENT;
   if (memory_restrict)
      inst->buffer_access |= TGSI_MEMORY_RESTRICT;
   if (memory_volatile)
      inst->buffer_access |= TGSI_MEMORY_VOLATILE;
}

void
glsl_to_tgsi_visitor::visit_generic_intrinsic(ir_call *ir, enum tgsi_opcode op)
{
   ir->return_deref->accept(this);
   st_dst_reg dst = st_dst_reg(this->result);

   dst.writemask = u_bit_consecutive(0, ir->return_deref->var->type->vector_elements);

   st_src_reg src[4] = { undef_src, undef_src, undef_src, undef_src };
   unsigned num_src = 0;
   foreach_in_list(ir_rvalue, param, &ir->actual_parameters) {
      assert(num_src < ARRAY_SIZE(src));

      this->result.file = PROGRAM_UNDEFINED;
      param->accept(this);
      assert(this->result.file != PROGRAM_UNDEFINED);

      src[num_src] = this->result;
      num_src++;
   }

   emit_asm(ir, op, dst, src[0], src[1], src[2], src[3]);
}

void
glsl_to_tgsi_visitor::visit(ir_call *ir)
{
   ir_function_signature *sig = ir->callee;

   /* Filter out intrinsics */
   switch (sig->intrinsic_id) {
   case ir_intrinsic_atomic_counter_read:
   case ir_intrinsic_atomic_counter_increment:
   case ir_intrinsic_atomic_counter_predecrement:
   case ir_intrinsic_atomic_counter_add:
   case ir_intrinsic_atomic_counter_min:
   case ir_intrinsic_atomic_counter_max:
   case ir_intrinsic_atomic_counter_and:
   case ir_intrinsic_atomic_counter_or:
   case ir_intrinsic_atomic_counter_xor:
   case ir_intrinsic_atomic_counter_exchange:
   case ir_intrinsic_atomic_counter_comp_swap:
      visit_atomic_counter_intrinsic(ir);
      return;

   case ir_intrinsic_ssbo_load:
   case ir_intrinsic_ssbo_store:
   case ir_intrinsic_ssbo_atomic_add:
   case ir_intrinsic_ssbo_atomic_min:
   case ir_intrinsic_ssbo_atomic_max:
   case ir_intrinsic_ssbo_atomic_and:
   case ir_intrinsic_ssbo_atomic_or:
   case ir_intrinsic_ssbo_atomic_xor:
   case ir_intrinsic_ssbo_atomic_exchange:
   case ir_intrinsic_ssbo_atomic_comp_swap:
      visit_ssbo_intrinsic(ir);
      return;

   case ir_intrinsic_memory_barrier:
   case ir_intrinsic_memory_barrier_atomic_counter:
   case ir_intrinsic_memory_barrier_buffer:
   case ir_intrinsic_memory_barrier_image:
   case ir_intrinsic_memory_barrier_shared:
   case ir_intrinsic_group_memory_barrier:
      visit_membar_intrinsic(ir);
      return;

   case ir_intrinsic_shared_load:
   case ir_intrinsic_shared_store:
   case ir_intrinsic_shared_atomic_add:
   case ir_intrinsic_shared_atomic_min:
   case ir_intrinsic_shared_atomic_max:
   case ir_intrinsic_shared_atomic_and:
   case ir_intrinsic_shared_atomic_or:
   case ir_intrinsic_shared_atomic_xor:
   case ir_intrinsic_shared_atomic_exchange:
   case ir_intrinsic_shared_atomic_comp_swap:
      visit_shared_intrinsic(ir);
      return;

   case ir_intrinsic_image_load:
   case ir_intrinsic_image_store:
   case ir_intrinsic_image_atomic_add:
   case ir_intrinsic_image_atomic_min:
   case ir_intrinsic_image_atomic_max:
   case ir_intrinsic_image_atomic_and:
   case ir_intrinsic_image_atomic_or:
   case ir_intrinsic_image_atomic_xor:
   case ir_intrinsic_image_atomic_exchange:
   case ir_intrinsic_image_atomic_comp_swap:
   case ir_intrinsic_image_size:
   case ir_intrinsic_image_samples:
   case ir_intrinsic_image_atomic_inc_wrap:
   case ir_intrinsic_image_atomic_dec_wrap:
      visit_image_intrinsic(ir);
      return;

   case ir_intrinsic_shader_clock:
      visit_generic_intrinsic(ir, TGSI_OPCODE_CLOCK);
      return;

   case ir_intrinsic_vote_all:
      visit_generic_intrinsic(ir, TGSI_OPCODE_VOTE_ALL);
      return;
   case ir_intrinsic_vote_any:
      visit_generic_intrinsic(ir, TGSI_OPCODE_VOTE_ANY);
      return;
   case ir_intrinsic_vote_eq:
      visit_generic_intrinsic(ir, TGSI_OPCODE_VOTE_EQ);
      return;
   case ir_intrinsic_ballot:
      visit_generic_intrinsic(ir, TGSI_OPCODE_BALLOT);
      return;
   case ir_intrinsic_read_first_invocation:
      visit_generic_intrinsic(ir, TGSI_OPCODE_READ_FIRST);
      return;
   case ir_intrinsic_read_invocation:
      visit_generic_intrinsic(ir, TGSI_OPCODE_READ_INVOC);
      return;

   case ir_intrinsic_helper_invocation:
      visit_generic_intrinsic(ir, TGSI_OPCODE_READ_HELPER);
      return;

   case ir_intrinsic_invalid:
   case ir_intrinsic_generic_load:
   case ir_intrinsic_generic_store:
   case ir_intrinsic_generic_atomic_add:
   case ir_intrinsic_generic_atomic_and:
   case ir_intrinsic_generic_atomic_or:
   case ir_intrinsic_generic_atomic_xor:
   case ir_intrinsic_generic_atomic_min:
   case ir_intrinsic_generic_atomic_max:
   case ir_intrinsic_generic_atomic_exchange:
   case ir_intrinsic_generic_atomic_comp_swap:
   case ir_intrinsic_begin_invocation_interlock:
   case ir_intrinsic_end_invocation_interlock:
      unreachable("Invalid intrinsic");
   }
}

void
glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
                                         unsigned *array_elements,
                                         uint16_t *index,
                                         st_src_reg *indirect,
                                         unsigned *location)
{
   switch (tail->ir_type) {
   case ir_type_dereference_record: {
      ir_dereference_record *deref_record = tail->as_dereference_record();
      const glsl_type *struct_type = deref_record->record->type;
      int field_index = deref_record->field_idx;

      calc_deref_offsets(deref_record->record->as_dereference(), array_elements, index, indirect, location);

      assert(field_index >= 0);
      *location += struct_type->struct_location_offset(field_index);
      break;
   }

   case ir_type_dereference_array: {
      ir_dereference_array *deref_arr = tail->as_dereference_array();

      void *mem_ctx = ralloc_parent(deref_arr);
      ir_constant *array_index =
         deref_arr->array_index->constant_expression_value(mem_ctx);

      if (!array_index) {
         st_src_reg temp_reg;
         st_dst_reg temp_dst;

         temp_reg = get_temp(glsl_type::uint_type);
         temp_dst = st_dst_reg(temp_reg);
         temp_dst.writemask = 1;

         deref_arr->array_index->accept(this);
         if (*array_elements != 1)
            emit_asm(NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
         else
            emit_asm(NULL, TGSI_OPCODE_MOV, temp_dst, this->result);

         if (indirect->file == PROGRAM_UNDEFINED)
            *indirect = temp_reg;
         else {
            temp_dst = st_dst_reg(*indirect);
            temp_dst.writemask = 1;
            emit_asm(NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
         }
      } else
         *index += array_index->value.u[0] * *array_elements;

      *array_elements *= deref_arr->array->type->length;

      calc_deref_offsets(deref_arr->array->as_dereference(), array_elements, index, indirect, location);
      break;
   }
   default:
      break;
   }
}

void
glsl_to_tgsi_visitor::get_deref_offsets(ir_dereference *ir,
                                        unsigned *array_size,
                                        unsigned *base,
                                        uint16_t *index,
                                        st_src_reg *reladdr,
                                        bool opaque)
{
   GLuint shader = _mesa_program_enum_to_shader_stage(this->prog->Target);
   unsigned location = 0;
   ir_variable *var = ir->variable_referenced();

   reladdr->reset();

   *base = 0;
   *array_size = 1;

   assert(var);
   location = var->data.location;
   calc_deref_offsets(ir, array_size, index, reladdr, &location);

   /*
    * If we end up with no indirect then adjust the base to the index,
    * and set the array size to 1.
    */
   if (reladdr->file == PROGRAM_UNDEFINED) {
      *base = *index;
      *array_size = 1;
   }

   if (opaque) {
      assert(location != 0xffffffff);
      *base += this->shader_program->data->UniformStorage[location].opaque[shader].index;
      *index += this->shader_program->data->UniformStorage[location].opaque[shader].index;
   }
}

st_src_reg
glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
{
   if (offset.reladdr || offset.reladdr2 ||
       offset.has_index2 ||
       offset.file == PROGRAM_UNIFORM ||
       offset.file == PROGRAM_CONSTANT ||
       offset.file == PROGRAM_STATE_VAR) {
      st_src_reg tmp = get_temp(glsl_type::ivec2_type);
      st_dst_reg tmp_dst = st_dst_reg(tmp);
      tmp_dst.writemask = WRITEMASK_XY;
      emit_asm(NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
      return tmp;
   }

   return offset;
}
 
bool
glsl_to_tgsi_visitor::handle_bound_deref(ir_dereference *ir)
{
   ir_variable *var = ir->variable_referenced();

   if (!var || var->data.mode != ir_var_uniform || var->data.bindless ||
       !(ir->type->is_image() || ir->type->is_sampler()))
      return false;

   /* Convert from bound sampler/image to bindless handle. */
   bool is_image = ir->type->is_image();
   st_src_reg resource(is_image ? PROGRAM_IMAGE : PROGRAM_SAMPLER, 0, GLSL_TYPE_UINT);
   uint16_t index = 0;
   unsigned array_size = 1, base = 0;
   st_src_reg reladdr;
   get_deref_offsets(ir, &array_size, &base, &index, &reladdr, true);

   resource.index = index;
   if (reladdr.file != PROGRAM_UNDEFINED) {
      resource.reladdr = ralloc(mem_ctx, st_src_reg);
      *resource.reladdr = reladdr;
      emit_arl(ir, sampler_reladdr, reladdr);
   }

   this->result = get_temp(glsl_type::uvec2_type);
   st_dst_reg dst(this->result);
   dst.writemask = WRITEMASK_XY;

   glsl_to_tgsi_instruction *inst = emit_asm(
      ir, is_image ? TGSI_OPCODE_IMG2HND : TGSI_OPCODE_SAMP2HND, dst);

   inst->tex_target = ir->type->sampler_index();
   inst->resource = resource;
   inst->sampler_array_size = array_size;
   inst->sampler_base = base;

   return true;
}

void
glsl_to_tgsi_visitor::visit(ir_texture *ir)
{
   st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy;
   st_src_reg offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, component;
   st_src_reg levels_src, reladdr;
   st_dst_reg result_dst, coord_dst, cube_sc_dst;
   glsl_to_tgsi_instruction *inst = NULL;
   enum tgsi_opcode opcode = TGSI_OPCODE_NOP;
   const glsl_type *sampler_type = ir->sampler->type;
   unsigned sampler_array_size = 1, sampler_base = 0;
   bool is_cube_array = false, is_cube_shadow = false;
   ir_variable *var = ir->sampler->variable_referenced();
   unsigned i;

   /* if we are a cube array sampler or a cube shadow */
   if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
      is_cube_array = sampler_type->sampler_array;
      is_cube_shadow = sampler_type->sampler_shadow;
   }

   if (ir->coordinate) {
      ir->coordinate->accept(this);

      /* Put our coords in a temp.  We'll need to modify them for shadow,
       * projection, or LOD, so the only case we'd use it as-is is if
       * we're doing plain old texturing.  The optimization passes on
       * glsl_to_tgsi_visitor should handle cleaning up our mess in that case.
       */
      coord = get_temp(glsl_type::vec4_type);
      coord_dst = st_dst_reg(coord);
      coord_dst.writemask = (1 << ir->coordinate->type->vector_elements) - 1;
      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
   }

   if (ir->projector) {
      ir->projector->accept(this);
      projector = this->result;
   }

   /* Storage for our result.  Ideally for an assignment we'd be using
    * the actual storage for the result here, instead.
    */
   result_src = get_temp(ir->type);
   result_dst = st_dst_reg(result_src);
   result_dst.writemask = (1 << ir->type->vector_elements) - 1;

   switch (ir->op) {
   case ir_tex:
      opcode = (is_cube_array && ir->shadow_comparator) ? TGSI_OPCODE_TEX2 : TGSI_OPCODE_TEX;
      if (ir->offset) {
         ir->offset->accept(this);
         offset[0] = this->result;
      }
      break;
   case ir_txb:
      if (is_cube_array || is_cube_shadow) {
         opcode = TGSI_OPCODE_TXB2;
      }
      else {
         opcode = TGSI_OPCODE_TXB;
      }
      ir->lod_info.bias->accept(this);
      lod_info = this->result;
      if (ir->offset) {
         ir->offset->accept(this);
         offset[0] = this->result;
      }
      break;
   case ir_txl:
      if (this->has_tex_txf_lz && ir->lod_info.lod->is_zero()) {
         opcode = TGSI_OPCODE_TEX_LZ;
      } else {
         opcode = is_cube_array ? TGSI_OPCODE_TXL2 : TGSI_OPCODE_TXL;
         ir->lod_info.lod->accept(this);
         lod_info = this->result;
      }
      if (ir->offset) {
         ir->offset->accept(this);
         offset[0] = this->result;
      }
      break;
   case ir_txd:
      opcode = TGSI_OPCODE_TXD;
      ir->lod_info.grad.dPdx->accept(this);
      dx = this->result;
      ir->lod_info.grad.dPdy->accept(this);
      dy = this->result;
      if (ir->offset) {
         ir->offset->accept(this);
         offset[0] = this->result;
      }
      break;
   case ir_txs:
      opcode = TGSI_OPCODE_TXQ;
      ir->lod_info.lod->accept(this);
      lod_info = this->result;
      break;
   case ir_query_levels:
      opcode = TGSI_OPCODE_TXQ;
      lod_info = undef_src;
      levels_src = get_temp(ir->type);
      break;
   case ir_txf:
      if (this->has_tex_txf_lz && ir->lod_info.lod->is_zero()) {
         opcode = TGSI_OPCODE_TXF_LZ;
      } else {
         opcode = TGSI_OPCODE_TXF;
         ir->lod_info.lod->accept(this);
         lod_info = this->result;
      }
      if (ir->offset) {
         ir->offset->accept(this);
         offset[0] = this->result;
      }
      break;
   case ir_txf_ms:
      opcode = TGSI_OPCODE_TXF;
      ir->lod_info.sample_index->accept(this);
      sample_index = this->result;
      break;
   case ir_tg4:
      opcode = TGSI_OPCODE_TG4;
      ir->lod_info.component->accept(this);
      component = this->result;
      if (ir->offset) {
         ir->offset->accept(this);
         if (ir->offset->type->is_array()) {
            const glsl_type *elt_type = ir->offset->type->fields.array;
            for (i = 0; i < ir->offset->type->length; i++) {
               offset[i] = this->result;
               offset[i].index += i * type_size(elt_type);
               offset[i].type = elt_type->base_type;
               offset[i].swizzle = swizzle_for_size(elt_type->vector_elements);
               offset[i] = canonicalize_gather_offset(offset[i]);
            }
         } else {
            offset[0] = canonicalize_gather_offset(this->result);
         }
      }
      break;
   case ir_lod:
      opcode = TGSI_OPCODE_LODQ;
      break;
   case ir_texture_samples:
      opcode = TGSI_OPCODE_TXQS;
      break;
   case ir_samples_identical:
      unreachable("Unexpected ir_samples_identical opcode");
   }

   if (ir->projector) {
      if (opcode == TGSI_OPCODE_TEX) {
         /* Slot the projector in as the last component of the coord. */
         coord_dst.writemask = WRITEMASK_W;
         emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, projector);
         coord_dst.writemask = WRITEMASK_XYZW;
         opcode = TGSI_OPCODE_TXP;
      } else {
         st_src_reg coord_w = coord;
         coord_w.swizzle = SWIZZLE_WWWW;

         /* For the other TEX opcodes there's no projective version
          * since the last slot is taken up by LOD info.  Do the
          * projective divide now.
          */
         coord_dst.writemask = WRITEMASK_W;
         emit_asm(ir, TGSI_OPCODE_RCP, coord_dst, projector);

         /* In the case where we have to project the coordinates "by hand,"
          * the shadow comparator value must also be projected.
          */
         st_src_reg tmp_src = coord;
         if (ir->shadow_comparator) {
            /* Slot the shadow value in as the second to last component of the
             * coord.
             */
            ir->shadow_comparator->accept(this);

            tmp_src = get_temp(glsl_type::vec4_type);
            st_dst_reg tmp_dst = st_dst_reg(tmp_src);

            /* Projective division not allowed for array samplers. */
            assert(!sampler_type->sampler_array);

            tmp_dst.writemask = WRITEMASK_Z;
            emit_asm(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);

            tmp_dst.writemask = WRITEMASK_XY;
            emit_asm(ir, TGSI_OPCODE_MOV, tmp_dst, coord);
         }

         coord_dst.writemask = WRITEMASK_XYZ;
         emit_asm(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w);

         coord_dst.writemask = WRITEMASK_XYZW;
         coord.swizzle = SWIZZLE_XYZW;
      }
   }

   /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the
    * shadow comparator was put in the correct place (and projected) by the
    * code, above, that handles by-hand projection.
    */
   if (ir->shadow_comparator && (!ir->projector || opcode == TGSI_OPCODE_TXP)) {
      /* Slot the shadow value in as the second to last component of the
       * coord.
       */
      ir->shadow_comparator->accept(this);

      if (is_cube_array) {
         cube_sc = get_temp(glsl_type::float_type);
         cube_sc_dst = st_dst_reg(cube_sc);
         cube_sc_dst.writemask = WRITEMASK_X;
         emit_asm(ir, TGSI_OPCODE_MOV, cube_sc_dst, this->result);
         cube_sc_dst.writemask = WRITEMASK_X;
      }
      else {
         if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
              sampler_type->sampler_array) ||
             sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
            coord_dst.writemask = WRITEMASK_W;
         } else {
            coord_dst.writemask = WRITEMASK_Z;
         }
         emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
         coord_dst.writemask = WRITEMASK_XYZW;
      }
   }

   if (ir->op == ir_txf_ms) {
      coord_dst.writemask = WRITEMASK_W;
      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, sample_index);
      coord_dst.writemask = WRITEMASK_XYZW;
   } else if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB ||
       opcode == TGSI_OPCODE_TXF) {
      /* TGSI stores LOD or LOD bias in the last channel of the coords. */
      coord_dst.writemask = WRITEMASK_W;
      emit_asm(ir, TGSI_OPCODE_MOV, coord_dst, lod_info);
      coord_dst.writemask = WRITEMASK_XYZW;
   }

   st_src_reg sampler(PROGRAM_SAMPLER, 0, GLSL_TYPE_UINT);

   uint16_t index = 0;
   get_deref_offsets(ir->sampler, &sampler_array_size, &sampler_base,
                     &index, &reladdr, !var->contains_bindless());

   sampler.index = index;
   if (reladdr.file != PROGRAM_UNDEFINED) {
      sampler.reladdr = ralloc(mem_ctx, st_src_reg);
      *sampler.reladdr = reladdr;
      emit_arl(ir, sampler_reladdr, reladdr);
   }

   st_src_reg bindless;
   if (var->contains_bindless()) {
      ir->sampler->accept(this);
      bindless = this->result;
   }

   if (opcode == TGSI_OPCODE_TXD)
      inst = emit_asm(ir, opcode, result_dst, coord, dx, dy);
   else if (opcode == TGSI_OPCODE_TXQ) {
      if (ir->op == ir_query_levels) {
         /* the level is stored in W */
         inst = emit_asm(ir, opcode, st_dst_reg(levels_src), lod_info);
         result_dst.writemask = WRITEMASK_X;
         levels_src.swizzle = SWIZZLE_WWWW;
         emit_asm(ir, TGSI_OPCODE_MOV, result_dst, levels_src);
      } else
         inst = emit_asm(ir, opcode, result_dst, lod_info);
   } else if (opcode == TGSI_OPCODE_TXQS) {
      inst = emit_asm(ir, opcode, result_dst);
   } else if (opcode == TGSI_OPCODE_TXL2 || opcode == TGSI_OPCODE_TXB2) {
      inst = emit_asm(ir, opcode, result_dst, coord, lod_info);
   } else if (opcode == TGSI_OPCODE_TEX2) {
      inst = emit_asm(ir, opcode, result_dst, coord, cube_sc);
   } else if (opcode == TGSI_OPCODE_TG4) {
      if (is_cube_array && ir->shadow_comparator) {
         inst = emit_asm(ir, opcode, result_dst, coord, cube_sc);
      } else {
         if (this->tg4_component_in_swizzle) {
            inst = emit_asm(ir, opcode, result_dst, coord);
            int idx = 0;
            foreach_in_list(immediate_storage, entry, &this->immediates) {
               if (component.index == idx) {
                  gl_constant_value value = entry->values[component.swizzle];
                  inst->gather_component = value.i;
                  break;
               }
               idx++;
            }
         } else {
            inst = emit_asm(ir, opcode, result_dst, coord, component);
         }
      }
   } else
      inst = emit_asm(ir, opcode, result_dst, coord);

   if (ir->shadow_comparator)
      inst->tex_shadow = GL_TRUE;

   if (var->contains_bindless()) {
      inst->resource = bindless;
      inst->resource.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
                                             SWIZZLE_X, SWIZZLE_Y);
   } else {
      inst->resource = sampler;
      inst->sampler_array_size = sampler_array_size;
      inst->sampler_base = sampler_base;
   }

   if (ir->offset) {
      if (!inst->tex_offsets)
         inst->tex_offsets = rzalloc_array(inst, st_src_reg,
                                           MAX_GLSL_TEXTURE_OFFSET);

      for (i = 0; i < MAX_GLSL_TEXTURE_OFFSET &&
                  offset[i].file != PROGRAM_UNDEFINED; i++)
         inst->tex_offsets[i] = offset[i];
      inst->tex_offset_num_offset = i;
   }

   inst->tex_target = sampler_type->sampler_index();
   inst->tex_type = ir->type->base_type;

   this->result = result_src;
}

void
glsl_to_tgsi_visitor::visit(ir_return *ir)
{
   assert(!ir->get_value());

   emit_asm(ir, TGSI_OPCODE_RET);
}

void
glsl_to_tgsi_visitor::visit(ir_discard *ir)
{
   if (ir->condition) {
      ir->condition->accept(this);
      st_src_reg condition = this->result;

      /* Convert the bool condition to a float so we can negate. */
      if (native_integers) {
         st_src_reg temp = get_temp(ir->condition->type);
         emit_asm(ir, TGSI_OPCODE_AND, st_dst_reg(temp),
              condition, st_src_reg_for_float(1.0));
         condition = temp;
      }

      condition.negate = ~condition.negate;
      emit_asm(ir, TGSI_OPCODE_KILL_IF, undef_dst, condition);
   } else {
      /* unconditional kil */
      emit_asm(ir, TGSI_OPCODE_KILL);
   }
}

void
glsl_to_tgsi_visitor::visit(ir_demote *ir)
{
   emit_asm(ir, TGSI_OPCODE_DEMOTE);
}

void
glsl_to_tgsi_visitor::visit(ir_if *ir)
{
   enum tgsi_opcode if_opcode;
   glsl_to_tgsi_instruction *if_inst;

   ir->condition->accept(this);
   assert(this->result.file != PROGRAM_UNDEFINED);

   if_opcode = native_integers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF;

   if_inst = emit_asm(ir->condition, if_opcode, undef_dst, this->result);

   this->instructions.push_tail(if_inst);

   visit_exec_list(&ir->then_instructions, this);

   if (!ir->else_instructions.is_empty()) {
      emit_asm(ir->condition, TGSI_OPCODE_ELSE);
      visit_exec_list(&ir->else_instructions, this);
   }

   if_inst = emit_asm(ir->condition, TGSI_OPCODE_ENDIF);
}


void
glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
{
   assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);

   ir->stream->accept(this);
   emit_asm(ir, TGSI_OPCODE_EMIT, undef_dst, this->result);
}

void
glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
{
   assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);

   ir->stream->accept(this);
   emit_asm(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result);
}

void
glsl_to_tgsi_visitor::visit(ir_barrier *ir)
{
   assert(this->prog->Target == GL_TESS_CONTROL_PROGRAM_NV ||
          this->prog->Target == GL_COMPUTE_PROGRAM_NV);

   emit_asm(ir, TGSI_OPCODE_BARRIER);
}

glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
{
   STATIC_ASSERT(sizeof(samplers_used) * 8 >= PIPE_MAX_SAMPLERS);

   result.file = PROGRAM_UNDEFINED;
   next_temp = 1;
   array_sizes = NULL;
   max_num_arrays = 0;
   next_array = 0;
   num_inputs = 0;
   num_outputs = 0;
   num_input_arrays = 0;
   num_output_arrays = 0;
   num_atomics = 0;
   num_atomic_arrays = 0;
   num_immediates = 0;
   num_address_regs = 0;
   samplers_used = 0;
   images_used = 0;
   indirect_addr_consts = false;
   wpos_transform_const = -1;
   native_integers = false;
   mem_ctx = ralloc_context(NULL);
   ctx = NULL;
   prog = NULL;
   precise = 0;
   need_uarl = false;
   tg4_component_in_swizzle = false;
   shader_program = NULL;
   shader = NULL;
   options = NULL;
   have_sqrt = false;
   have_fma = false;
   use_shared_memory = false;
   has_tex_txf_lz = false;
   variables = NULL;
}

static void var_destroy(struct hash_entry *entry)
{
   variable_storage *storage = (variable_storage *)entry->data;

   delete storage;
}

glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
{
   _mesa_hash_table_destroy(variables, var_destroy);
   free(array_sizes);
   ralloc_free(mem_ctx);
}

extern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v)
{
   delete v;
}


/**
 * Count resources used by the given gpu program (number of texture
 * samplers, etc).
 */
static void
count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
{
   v->samplers_used = 0;
   v->images_used = 0;
   prog->info.textures_used_by_txf = 0;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) {
      if (inst->info->is_tex) {
         for (int i = 0; i < inst->sampler_array_size; i++) {
            unsigned idx = inst->sampler_base + i;
            v->samplers_used |= 1u << idx;

            debug_assert(idx < (int)ARRAY_SIZE(v->sampler_types));
            v->sampler_types[idx] = inst->tex_type;
            v->sampler_targets[idx] =
               st_translate_texture_target(inst->tex_target, inst->tex_shadow);

            if (inst->op == TGSI_OPCODE_TXF || inst->op == TGSI_OPCODE_TXF_LZ) {
               prog->info.textures_used_by_txf |= 1u << idx;
            }
         }
      }

      if (inst->tex_target == TEXTURE_EXTERNAL_INDEX)
         prog->ExternalSamplersUsed |= 1 << inst->resource.index;

      if (inst->resource.file != PROGRAM_UNDEFINED && (
                is_resource_instruction(inst->op) ||
                inst->op == TGSI_OPCODE_STORE)) {
         if (inst->resource.file == PROGRAM_MEMORY) {
            v->use_shared_memory = true;
         } else if (inst->resource.file == PROGRAM_IMAGE) {
            for (int i = 0; i < inst->sampler_array_size; i++) {
               unsigned idx = inst->sampler_base + i;
               v->images_used |= 1 << idx;
               v->image_targets[idx] =
                  st_translate_texture_target(inst->tex_target, false);
               v->image_formats[idx] = inst->image_format;
               v->image_wr[idx] = !inst->read_only;
            }
         }
      }
   }
   prog->SamplersUsed = v->samplers_used;

   if (v->shader_program != NULL)
      _mesa_update_shader_textures_used(v->shader_program, prog);
}

/**
 * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which
 * are read from the given src in this instruction
 */
static int
get_src_arg_mask(st_dst_reg dst, st_src_reg src)
{
   int read_mask = 0, comp;

   /* Now, given the src swizzle and the written channels, find which
    * components are actually read
    */
   for (comp = 0; comp < 4; ++comp) {
      const unsigned coord = GET_SWZ(src.swizzle, comp);
      assert(coord < 4);
      if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W)
         read_mask |= 1 << coord;
   }

   return read_mask;
}

/**
 * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP
 * instruction is the first instruction to write to register T0.  There are
 * several lowering passes done in GLSL IR (e.g. branches and
 * relative addressing) that create a large number of conditional assignments
 * that ir_to_mesa converts to CMP instructions like the one mentioned above.
 *
 * Here is why this conversion is safe:
 * CMP T0, T1 T2 T0 can be expanded to:
 * if (T1 < 0.0)
 *   MOV T0, T2;
 * else
 *   MOV T0, T0;
 *
 * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same
 * as the original program.  If (T1 < 0.0) evaluates to false, executing
 * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized.
 * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2
 * because any instruction that was going to read from T0 after this was going
 * to read a garbage value anyway.
 */
void
glsl_to_tgsi_visitor::simplify_cmp(void)
{
   int tempWritesSize = 0;
   unsigned *tempWrites = NULL;
   unsigned outputWrites[VARYING_SLOT_TESS_MAX];

   memset(outputWrites, 0, sizeof(outputWrites));

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      unsigned prevWriteMask = 0;

      /* Give up if we encounter relative addressing or flow control. */
      if (inst->dst[0].reladdr || inst->dst[0].reladdr2 ||
          inst->dst[1].reladdr || inst->dst[1].reladdr2 ||
          inst->info->is_branch ||
          inst->op == TGSI_OPCODE_CONT ||
          inst->op == TGSI_OPCODE_END ||
          inst->op == TGSI_OPCODE_RET) {
         break;
      }

      if (inst->dst[0].file == PROGRAM_OUTPUT) {
         assert(inst->dst[0].index < (signed)ARRAY_SIZE(outputWrites));
         prevWriteMask = outputWrites[inst->dst[0].index];
         outputWrites[inst->dst[0].index] |= inst->dst[0].writemask;
      } else if (inst->dst[0].file == PROGRAM_TEMPORARY) {
         if (inst->dst[0].index >= tempWritesSize) {
            const int inc = 4096;

            tempWrites = (unsigned*)
                         realloc(tempWrites,
                                 (tempWritesSize + inc) * sizeof(unsigned));
            if (!tempWrites)
               return;

            memset(tempWrites + tempWritesSize, 0, inc * sizeof(unsigned));
            tempWritesSize += inc;
         }

         prevWriteMask = tempWrites[inst->dst[0].index];
         tempWrites[inst->dst[0].index] |= inst->dst[0].writemask;
      } else
         continue;

      /* For a CMP to be considered a conditional write, the destination
       * register and source register two must be the same. */
      if (inst->op == TGSI_OPCODE_CMP
          && !(inst->dst[0].writemask & prevWriteMask)
          && inst->src[2].file == inst->dst[0].file
          && inst->src[2].index == inst->dst[0].index
          && inst->dst[0].writemask ==
             get_src_arg_mask(inst->dst[0], inst->src[2])) {

         inst->op = TGSI_OPCODE_MOV;
         inst->info = tgsi_get_opcode_info(inst->op);
         inst->src[0] = inst->src[1];
      }
   }

   free(tempWrites);
}

static void
rename_temp_handle_src(struct rename_reg_pair *renames, st_src_reg *src)
{
   if (src && src->file == PROGRAM_TEMPORARY) {
      int old_idx = src->index;
      if (renames[old_idx].valid)
         src->index = renames[old_idx].new_reg;
   }
}

/* Replaces all references to a temporary register index with another index. */
void
glsl_to_tgsi_visitor::rename_temp_registers(struct rename_reg_pair *renames)
{
   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      unsigned j;
      for (j = 0; j < num_inst_src_regs(inst); j++) {
         rename_temp_handle_src(renames, &inst->src[j]);
         rename_temp_handle_src(renames, inst->src[j].reladdr);
         rename_temp_handle_src(renames, inst->src[j].reladdr2);
      }

      for (j = 0; j < inst->tex_offset_num_offset; j++) {
         rename_temp_handle_src(renames, &inst->tex_offsets[j]);
         rename_temp_handle_src(renames, inst->tex_offsets[j].reladdr);
         rename_temp_handle_src(renames, inst->tex_offsets[j].reladdr2);
      }

      rename_temp_handle_src(renames, &inst->resource);
      rename_temp_handle_src(renames, inst->resource.reladdr);
      rename_temp_handle_src(renames, inst->resource.reladdr2);

      for (j = 0; j < num_inst_dst_regs(inst); j++) {
         if (inst->dst[j].file == PROGRAM_TEMPORARY) {
            int old_idx = inst->dst[j].index;
            if (renames[old_idx].valid)
               inst->dst[j].index = renames[old_idx].new_reg;
         }
         rename_temp_handle_src(renames, inst->dst[j].reladdr);
         rename_temp_handle_src(renames, inst->dst[j].reladdr2);
      }
   }
}

void
glsl_to_tgsi_visitor::get_first_temp_write(int *first_writes)
{
   int depth = 0; /* loop depth */
   int loop_start = -1; /* index of the first active BGNLOOP (if any) */
   unsigned i = 0, j;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      for (j = 0; j < num_inst_dst_regs(inst); j++) {
         if (inst->dst[j].file == PROGRAM_TEMPORARY) {
            if (first_writes[inst->dst[j].index] == -1)
                first_writes[inst->dst[j].index] = (depth == 0) ? i : loop_start;
         }
      }

      if (inst->op == TGSI_OPCODE_BGNLOOP) {
         if (depth++ == 0)
            loop_start = i;
      } else if (inst->op == TGSI_OPCODE_ENDLOOP) {
         if (--depth == 0)
            loop_start = -1;
      }
      assert(depth >= 0);
      i++;
   }
}

void
glsl_to_tgsi_visitor::get_first_temp_read(int *first_reads)
{
   int depth = 0; /* loop depth */
   int loop_start = -1; /* index of the first active BGNLOOP (if any) */
   unsigned i = 0, j;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      for (j = 0; j < num_inst_src_regs(inst); j++) {
         if (inst->src[j].file == PROGRAM_TEMPORARY) {
            if (first_reads[inst->src[j].index] == -1)
                first_reads[inst->src[j].index] = (depth == 0) ? i : loop_start;
         }
      }
      for (j = 0; j < inst->tex_offset_num_offset; j++) {
         if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY) {
            if (first_reads[inst->tex_offsets[j].index] == -1)
               first_reads[inst->tex_offsets[j].index] = (depth == 0) ? i : loop_start;
         }
      }
      if (inst->op == TGSI_OPCODE_BGNLOOP) {
         if (depth++ == 0)
            loop_start = i;
      } else if (inst->op == TGSI_OPCODE_ENDLOOP) {
         if (--depth == 0)
            loop_start = -1;
      }
      assert(depth >= 0);
      i++;
   }
}

void
glsl_to_tgsi_visitor::get_last_temp_read_first_temp_write(int *last_reads, int *first_writes)
{
   int depth = 0; /* loop depth */
   int loop_start = -1; /* index of the first active BGNLOOP (if any) */
   unsigned i = 0, j;
   int k;
   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      for (j = 0; j < num_inst_src_regs(inst); j++) {
         if (inst->src[j].file == PROGRAM_TEMPORARY)
            last_reads[inst->src[j].index] = (depth == 0) ? i : -2;
      }
      for (j = 0; j < num_inst_dst_regs(inst); j++) {
         if (inst->dst[j].file == PROGRAM_TEMPORARY) {
            if (first_writes[inst->dst[j].index] == -1)
               first_writes[inst->dst[j].index] = (depth == 0) ? i : loop_start;
            last_reads[inst->dst[j].index] = (depth == 0) ? i : -2;
         }
      }
      for (j = 0; j < inst->tex_offset_num_offset; j++) {
         if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY)
            last_reads[inst->tex_offsets[j].index] = (depth == 0) ? i : -2;
      }
      if (inst->op == TGSI_OPCODE_BGNLOOP) {
         if (depth++ == 0)
            loop_start = i;
      } else if (inst->op == TGSI_OPCODE_ENDLOOP) {
         if (--depth == 0) {
            loop_start = -1;
            for (k = 0; k < this->next_temp; k++) {
               if (last_reads[k] == -2) {
                  last_reads[k] = i;
               }
            }
         }
      }
      assert(depth >= 0);
      i++;
   }
}

void
glsl_to_tgsi_visitor::get_last_temp_write(int *last_writes)
{
   int depth = 0; /* loop depth */
   int i = 0, k;
   unsigned j;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      for (j = 0; j < num_inst_dst_regs(inst); j++) {
         if (inst->dst[j].file == PROGRAM_TEMPORARY)
            last_writes[inst->dst[j].index] = (depth == 0) ? i : -2;
      }

      if (inst->op == TGSI_OPCODE_BGNLOOP)
         depth++;
      else if (inst->op == TGSI_OPCODE_ENDLOOP)
         if (--depth == 0) {
            for (k = 0; k < this->next_temp; k++) {
               if (last_writes[k] == -2) {
                  last_writes[k] = i;
               }
            }
         }
      assert(depth >= 0);
      i++;
   }
}

/*
 * On a basic block basis, tracks available PROGRAM_TEMPORARY register
 * channels for copy propagation and updates following instructions to
 * use the original versions.
 *
 * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
 * will occur.  As an example, a TXP production before this pass:
 *
 * 0: MOV TEMP[1], INPUT[4].xyyy;
 * 1: MOV TEMP[1].w, INPUT[4].wwww;
 * 2: TXP TEMP[2], TEMP[1], texture[0], 2D;
 *
 * and after:
 *
 * 0: MOV TEMP[1], INPUT[4].xyyy;
 * 1: MOV TEMP[1].w, INPUT[4].wwww;
 * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
 *
 * which allows for dead code elimination on TEMP[1]'s writes.
 */
void
glsl_to_tgsi_visitor::copy_propagate(void)
{
   glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx,
                                                  glsl_to_tgsi_instruction *,
                                                  this->next_temp * 4);
   int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
   int level = 0;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      assert(inst->dst[0].file != PROGRAM_TEMPORARY
             || inst->dst[0].index < this->next_temp);

      /* First, do any copy propagation possible into the src regs. */
      for (int r = 0; r < 3; r++) {
         glsl_to_tgsi_instruction *first = NULL;
         bool good = true;
         int acp_base = inst->src[r].index * 4;

         if (inst->src[r].file != PROGRAM_TEMPORARY ||
             inst->src[r].reladdr ||
             inst->src[r].reladdr2)
            continue;

         /* See if we can find entries in the ACP consisting of MOVs
          * from the same src register for all the swizzled channels
          * of this src register reference.
          */
         for (int i = 0; i < 4; i++) {
            int src_chan = GET_SWZ(inst->src[r].swizzle, i);
            glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan];

            if (!copy_chan) {
               good = false;
               break;
            }

            assert(acp_level[acp_base + src_chan] <= level);

            if (!first) {
               first = copy_chan;
            } else {
               if (first->src[0].file != copy_chan->src[0].file ||
                   first->src[0].index != copy_chan->src[0].index ||
                   first->src[0].double_reg2 != copy_chan->src[0].double_reg2 ||
                   first->src[0].index2D != copy_chan->src[0].index2D) {
                  good = false;
                  break;
               }
            }
         }

         if (good) {
            /* We've now validated that we can copy-propagate to
             * replace this src register reference.  Do it.
             */
            inst->src[r].file = first->src[0].file;
            inst->src[r].index = first->src[0].index;
            inst->src[r].index2D = first->src[0].index2D;
            inst->src[r].has_index2 = first->src[0].has_index2;
            inst->src[r].double_reg2 = first->src[0].double_reg2;
            inst->src[r].array_id = first->src[0].array_id;

            int swizzle = 0;
            for (int i = 0; i < 4; i++) {
               int src_chan = GET_SWZ(inst->src[r].swizzle, i);
               glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan];
               swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << (3 * i));
            }
            inst->src[r].swizzle = swizzle;
         }
      }

      switch (inst->op) {
      case TGSI_OPCODE_BGNLOOP:
      case TGSI_OPCODE_ENDLOOP:
         /* End of a basic block, clear the ACP entirely. */
         memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
         break;

      case TGSI_OPCODE_IF:
      case TGSI_OPCODE_UIF:
         ++level;
         break;

      case TGSI_OPCODE_ENDIF:
      case TGSI_OPCODE_ELSE:
         /* Clear all channels written inside the block from the ACP, but
          * leaving those that were not touched.
          */
         for (int r = 0; r < this->next_temp; r++) {
            for (int c = 0; c < 4; c++) {
               if (!acp[4 * r + c])
                  continue;

               if (acp_level[4 * r + c] >= level)
                  acp[4 * r + c] = NULL;
            }
         }
         if (inst->op == TGSI_OPCODE_ENDIF)
            --level;
         break;

      default:
         /* Continuing the block, clear any written channels from
          * the ACP.
          */
         for (int d = 0; d < 2; d++) {
            if (inst->dst[d].file == PROGRAM_TEMPORARY && inst->dst[d].reladdr) {
               /* Any temporary might be written, so no copy propagation
                * across this instruction.
                */
               memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
            } else if (inst->dst[d].file == PROGRAM_OUTPUT &&
                       inst->dst[d].reladdr) {
               /* Any output might be written, so no copy propagation
                * from outputs across this instruction.
                */
               for (int r = 0; r < this->next_temp; r++) {
                  for (int c = 0; c < 4; c++) {
                     if (!acp[4 * r + c])
                        continue;

                     if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT)
                        acp[4 * r + c] = NULL;
                  }
               }
            } else if (inst->dst[d].file == PROGRAM_TEMPORARY ||
                       inst->dst[d].file == PROGRAM_OUTPUT) {
               /* Clear where it's used as dst. */
               if (inst->dst[d].file == PROGRAM_TEMPORARY) {
                  for (int c = 0; c < 4; c++) {
                     if (inst->dst[d].writemask & (1 << c))
                        acp[4 * inst->dst[d].index + c] = NULL;
                  }
               }

               /* Clear where it's used as src. */
               for (int r = 0; r < this->next_temp; r++) {
                  for (int c = 0; c < 4; c++) {
                     if (!acp[4 * r + c])
                        continue;

                     int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c);

                     if (acp[4 * r + c]->src[0].file == inst->dst[d].file &&
                         acp[4 * r + c]->src[0].index == inst->dst[d].index &&
                         inst->dst[d].writemask & (1 << src_chan)) {
                        acp[4 * r + c] = NULL;
                     }
                  }
               }
            }
         }
         break;
      }

      /* If this is a copy, add it to the ACP. */
      if (inst->op == TGSI_OPCODE_MOV &&
          inst->dst[0].file == PROGRAM_TEMPORARY &&
          !(inst->dst[0].file == inst->src[0].file &&
             inst->dst[0].index == inst->src[0].index) &&
          !inst->dst[0].reladdr &&
          !inst->dst[0].reladdr2 &&
          !inst->saturate &&
          inst->src[0].file != PROGRAM_ARRAY &&
          (inst->src[0].file != PROGRAM_OUTPUT ||
           this->shader->Stage != MESA_SHADER_TESS_CTRL) &&
          !inst->src[0].reladdr &&
          !inst->src[0].reladdr2 &&
          !inst->src[0].negate &&
          !inst->src[0].abs) {
         for (int i = 0; i < 4; i++) {
            if (inst->dst[0].writemask & (1 << i)) {
               acp[4 * inst->dst[0].index + i] = inst;
               acp_level[4 * inst->dst[0].index + i] = level;
            }
         }
      }
   }

   ralloc_free(acp_level);
   ralloc_free(acp);
}

static void
dead_code_handle_reladdr(glsl_to_tgsi_instruction **writes, st_src_reg *reladdr)
{
   if (reladdr && reladdr->file == PROGRAM_TEMPORARY) {
      /* Clear where it's used as src. */
      int swz = GET_SWZ(reladdr->swizzle, 0);
      writes[4 * reladdr->index + swz] = NULL;
   }
}

/*
 * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead
 * code elimination.
 *
 * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
 * will occur.  As an example, a TXP production after copy propagation but
 * before this pass:
 *
 * 0: MOV TEMP[1], INPUT[4].xyyy;
 * 1: MOV TEMP[1].w, INPUT[4].wwww;
 * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
 *
 * and after this pass:
 *
 * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
 */
int
glsl_to_tgsi_visitor::eliminate_dead_code(void)
{
   glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx,
                                                     glsl_to_tgsi_instruction *,
                                                     this->next_temp * 4);
   int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
   int level = 0;
   int removed = 0;

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      assert(inst->dst[0].file != PROGRAM_TEMPORARY
             || inst->dst[0].index < this->next_temp);

      switch (inst->op) {
      case TGSI_OPCODE_BGNLOOP:
      case TGSI_OPCODE_ENDLOOP:
      case TGSI_OPCODE_CONT:
      case TGSI_OPCODE_BRK:
         /* End of a basic block, clear the write array entirely.
          *
          * This keeps us from killing dead code when the writes are
          * on either side of a loop, even when the register isn't touched
          * inside the loop.  However, glsl_to_tgsi_visitor doesn't seem to emit
          * dead code of this type, so it shouldn't make a difference as long as
          * the dead code elimination pass in the GLSL compiler does its job.
          */
         memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
         break;

      case TGSI_OPCODE_ENDIF:
      case TGSI_OPCODE_ELSE:
         /* Promote the recorded level of all channels written inside the
          * preceding if or else block to the level above the if/else block.
          */
         for (int r = 0; r < this->next_temp; r++) {
            for (int c = 0; c < 4; c++) {
               if (!writes[4 * r + c])
                  continue;

               if (write_level[4 * r + c] == level)
                  write_level[4 * r + c] = level-1;
            }
         }
         if (inst->op == TGSI_OPCODE_ENDIF)
            --level;
         break;

      case TGSI_OPCODE_IF:
      case TGSI_OPCODE_UIF:
         ++level;
         /* fallthrough to default case to mark the condition as read */
      default:
         /* Continuing the block, clear any channels from the write array that
          * are read by this instruction.
          */
         for (unsigned i = 0; i < ARRAY_SIZE(inst->src); i++) {
            if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){
               /* Any temporary might be read, so no dead code elimination
                * across this instruction.
                */
               memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
            } else if (inst->src[i].file == PROGRAM_TEMPORARY) {
               /* Clear where it's used as src. */
               int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0);
               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1);
               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2);
               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3);

               for (int c = 0; c < 4; c++) {
                  if (src_chans & (1 << c))
                     writes[4 * inst->src[i].index + c] = NULL;
               }
            }
            dead_code_handle_reladdr(writes, inst->src[i].reladdr);
            dead_code_handle_reladdr(writes, inst->src[i].reladdr2);
         }
         for (unsigned i = 0; i < inst->tex_offset_num_offset; i++) {
            if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY && inst->tex_offsets[i].reladdr){
               /* Any temporary might be read, so no dead code elimination
                * across this instruction.
                */
               memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
            } else if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY) {
               /* Clear where it's used as src. */
               int src_chans = 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 0);
               src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 1);
               src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 2);
               src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 3);

               for (int c = 0; c < 4; c++) {
                  if (src_chans & (1 << c))
                     writes[4 * inst->tex_offsets[i].index + c] = NULL;
               }
            }
            dead_code_handle_reladdr(writes, inst->tex_offsets[i].reladdr);
            dead_code_handle_reladdr(writes, inst->tex_offsets[i].reladdr2);
         }

         if (inst->resource.file == PROGRAM_TEMPORARY) {
            int src_chans;

            src_chans  = 1 << GET_SWZ(inst->resource.swizzle, 0);
            src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 1);
            src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 2);
            src_chans |= 1 << GET_SWZ(inst->resource.swizzle, 3);

            for (int c = 0; c < 4; c++) {
               if (src_chans & (1 << c))
                  writes[4 * inst->resource.index + c] = NULL;
            }
         }
         dead_code_handle_reladdr(writes, inst->resource.reladdr);
         dead_code_handle_reladdr(writes, inst->resource.reladdr2);

         for (unsigned i = 0; i < ARRAY_SIZE(inst->dst); i++) {
            dead_code_handle_reladdr(writes, inst->dst[i].reladdr);
            dead_code_handle_reladdr(writes, inst->dst[i].reladdr2);
         }
         break;
      }

      /* If this instruction writes to a temporary, add it to the write array.
       * If there is already an instruction in the write array for one or more
       * of the channels, flag that channel write as dead.
       */
      for (unsigned i = 0; i < ARRAY_SIZE(inst->dst); i++) {
         if (inst->dst[i].file == PROGRAM_TEMPORARY &&
             !inst->dst[i].reladdr) {
            for (int c = 0; c < 4; c++) {
               if (inst->dst[i].writemask & (1 << c)) {
                  if (writes[4 * inst->dst[i].index + c]) {
                     if (write_level[4 * inst->dst[i].index + c] < level)
                        continue;
                     else
                        writes[4 * inst->dst[i].index + c]->dead_mask |= (1 << c);
                  }
                  writes[4 * inst->dst[i].index + c] = inst;
                  write_level[4 * inst->dst[i].index + c] = level;
               }
            }
         }
      }
   }

   /* Anything still in the write array at this point is dead code. */
   for (int r = 0; r < this->next_temp; r++) {
      for (int c = 0; c < 4; c++) {
         glsl_to_tgsi_instruction *inst = writes[4 * r + c];
         if (inst)
            inst->dead_mask |= (1 << c);
      }
   }

   /* Now actually remove the instructions that are completely dead and update
    * the writemask of other instructions with dead channels.
    */
   foreach_in_list_safe(glsl_to_tgsi_instruction, inst, &this->instructions) {
      if (!inst->dead_mask || !inst->dst[0].writemask)
         continue;
      /* No amount of dead masks should remove memory stores */
      if (inst->info->is_store)
         continue;

      if ((inst->dst[0].writemask & ~inst->dead_mask) == 0) {
         inst->remove();
         delete inst;
         removed++;
      } else {
         if (glsl_base_type_is_64bit(inst->dst[0].type)) {
            if (inst->dead_mask == WRITEMASK_XY ||
                inst->dead_mask == WRITEMASK_ZW)
               inst->dst[0].writemask &= ~(inst->dead_mask);
         } else
            inst->dst[0].writemask &= ~(inst->dead_mask);
      }
   }

   ralloc_free(write_level);
   ralloc_free(writes);

   return removed;
}

/* merge DFRACEXP instructions into one. */
void
glsl_to_tgsi_visitor::merge_two_dsts(void)
{
   /* We never delete inst, but we may delete its successor. */
   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      glsl_to_tgsi_instruction *inst2;
      unsigned defined;

      if (num_inst_dst_regs(inst) != 2)
         continue;

      if (inst->dst[0].file != PROGRAM_UNDEFINED &&
          inst->dst[1].file != PROGRAM_UNDEFINED)
         continue;

      assert(inst->dst[0].file != PROGRAM_UNDEFINED ||
             inst->dst[1].file != PROGRAM_UNDEFINED);

      if (inst->dst[0].file == PROGRAM_UNDEFINED)
         defined = 1;
      else
         defined = 0;

      inst2 = (glsl_to_tgsi_instruction *) inst->next;
      while (!inst2->is_tail_sentinel()) {
         if (inst->op == inst2->op &&
             inst2->dst[defined].file == PROGRAM_UNDEFINED &&
             inst->src[0].file == inst2->src[0].file &&
             inst->src[0].index == inst2->src[0].index &&
             inst->src[0].type == inst2->src[0].type &&
             inst->src[0].swizzle == inst2->src[0].swizzle)
            break;
         inst2 = (glsl_to_tgsi_instruction *) inst2->next;
      }

      if (inst2->is_tail_sentinel()) {
         /* Undefined destinations are not allowed, substitute with an unused
          * temporary register.
          */
         st_src_reg tmp = get_temp(glsl_type::vec4_type);
         inst->dst[defined ^ 1] = st_dst_reg(tmp);
         inst->dst[defined ^ 1].writemask = 0;
         continue;
      }

      inst->dst[defined ^ 1] = inst2->dst[defined ^ 1];
      inst2->remove();
      delete inst2;
   }
}

template <typename st_reg>
void test_indirect_access(const st_reg& reg, bool *has_indirect_access)
{
   if (reg.file == PROGRAM_ARRAY) {
      if (reg.reladdr || reg.reladdr2 || reg.has_index2) {
	 has_indirect_access[reg.array_id] = true;
	 if (reg.reladdr)
	    test_indirect_access(*reg.reladdr, has_indirect_access);
	 if (reg.reladdr2)
	    test_indirect_access(*reg.reladdr2, has_indirect_access);
      }
   }
}

template <typename st_reg>
void remap_array(st_reg& reg, const int *array_remap_info,
		 const bool *has_indirect_access)
{
   if (reg.file == PROGRAM_ARRAY) {
      if (!has_indirect_access[reg.array_id]) {
	 reg.file = PROGRAM_TEMPORARY;
	 reg.index = reg.index + array_remap_info[reg.array_id];
	 reg.array_id = 0;
      } else {
	 reg.array_id = array_remap_info[reg.array_id];
      }

      if (reg.reladdr)
	 remap_array(*reg.reladdr, array_remap_info, has_indirect_access);

      if (reg.reladdr2)
	 remap_array(*reg.reladdr2, array_remap_info, has_indirect_access);
   }
}

/* One-dimensional arrays whose elements are only accessed directly are
 * replaced by an according set of temporary registers that then can become
 * subject to further optimization steps like copy propagation and
 * register merging.
 */
void
glsl_to_tgsi_visitor::split_arrays(void)
{
   if (!next_array)
      return;

   bool *has_indirect_access = rzalloc_array(mem_ctx, bool, next_array + 1);

   foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
      for (unsigned j = 0; j < num_inst_src_regs(inst); j++)
	 test_indirect_access(inst->src[j], has_indirect_access);

      for (unsigned j = 0; j < inst->tex_offset_num_offset; j++)
	 test_indirect_access(inst->tex_offsets[j], has_indirect_access);

      for (unsigned j = 0; j < num_inst_dst_regs(inst); j++)
	 test_indirect_access(inst->dst[j], has_indirect_access);

      test_indirect_access(inst->resource, has_indirect_access);
   }

   unsigned array_offset = 0;
   unsigned n_remaining_arrays = 0;

   /* Double use: For arrays that get split this value will contain
    * the base index of the temporary registers this array is replaced
    * with. For arrays that remain it contains the new array ID.
    */
   int *array_remap_info = rzalloc_array(has_indirect_access, int,
					 next_array + 1);

   for (unsigned i = 1; i <= next_array; ++i) {
      if (!has_indirect_access[i]) {
	 array_remap_info[i] = this->next_temp + array_offset;
	 array_offset += array_sizes[i - 1];
      } else {
	 array_sizes[n_remaining_arrays] = array_sizes[i-1];
	 array_remap_info[i] = ++n_remaining_arrays;
      }
   }

   if (next_array !=  n_remaining_arrays) {
      foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
	 for (unsigned j = 0; j < num_inst_src_regs(inst); j++)
	    remap_array(inst->src[j], array_remap_info, has_indirect_access);

	 for (unsigned j = 0; j < inst->tex_offset_num_offset; j++)
	    remap_array(inst->tex_offsets[j], array_remap_info, has_indirect_access);

	 for (unsigned j = 0; j < num_inst_dst_regs(inst); j++) {
	    remap_array(inst->dst[j], array_remap_info, has_indirect_access);
	 }
	 remap_array(inst->resource, array_remap_info, has_indirect_access);
      }
   }

   ralloc_free(has_indirect_access);
   this->next_temp += array_offset;
   next_array = n_remaining_arrays;
}

/* Merges temporary registers together where possible to reduce the number of
 * registers needed to run a program.
 *
 * Produces optimal code only after copy propagation and dead code elimination
 * have been run. */
void
glsl_to_tgsi_visitor::merge_registers(void)
{
   class array_live_range *arr_live_ranges = NULL;

   struct register_live_range *reg_live_ranges =
	 rzalloc_array(mem_ctx, struct register_live_range, this->next_temp);

   if (this->next_array > 0) {
      arr_live_ranges = new array_live_range[this->next_array];
      for (unsigned i = 0; i < this->next_array; ++i)
         arr_live_ranges[i] = array_live_range(i+1, this->array_sizes[i]);
   }


   if (get_temp_registers_required_live_ranges(reg_live_ranges, &this->instructions,
					       this->next_temp, reg_live_ranges,
					       this->next_array, arr_live_ranges)) {
      struct rename_reg_pair *renames =
	    rzalloc_array(reg_live_ranges, struct rename_reg_pair, this->next_temp);
      get_temp_registers_remapping(reg_live_ranges, this->next_temp,
				   reg_live_ranges, renames);
      rename_temp_registers(renames);

      this->next_array =  merge_arrays(this->next_array, this->array_sizes,
				       &this->instructions, arr_live_ranges);
   }

   if (arr_live_ranges)
      delete[] arr_live_ranges;

   ralloc_free(reg_live_ranges);
}

/* Reassign indices to temporary registers by reusing unused indices created
 * by optimization passes. */
void
glsl_to_tgsi_visitor::renumber_registers(void)
{
   int i = 0;
   int new_index = 0;
   int *first_writes = ralloc_array(mem_ctx, int, this->next_temp);
   struct rename_reg_pair *renames = rzalloc_array(mem_ctx, struct rename_reg_pair, this->next_temp);

   for (i = 0; i < this->next_temp; i++) {
      first_writes[i] = -1;
   }
   get_first_temp_write(first_writes);

   for (i = 0; i < this->next_temp; i++) {
      if (first_writes[i] < 0) continue;
      if (i != new_index) {
         renames[i].new_reg = new_index;
         renames[i].valid = true;
      }
      new_index++;
   }

   rename_temp_registers(renames);
   this->next_temp = new_index;
   ralloc_free(renames);
   ralloc_free(first_writes);
}

#ifndef NDEBUG
void glsl_to_tgsi_visitor::print_stats()
{
   int narray_registers = 0;
   for (unsigned i = 0; i < this->next_array; ++i)
      narray_registers += this->array_sizes[i];

   int ninstructions = 0;
   foreach_in_list(glsl_to_tgsi_instruction, inst, &instructions) {
      ++ninstructions;
   }

   simple_mtx_lock(&print_stats_mutex);
   stats_log << next_array << ", "
	     << next_temp << ", "
	     << narray_registers << ", "
	     << next_temp + narray_registers << ", "
	     << ninstructions << "\n";
   simple_mtx_unlock(&print_stats_mutex);
}
#endif
/* ------------------------- TGSI conversion stuff -------------------------- */

/**
 * Intermediate state used during shader translation.
 */
struct st_translate {
   struct ureg_program *ureg;

   unsigned temps_size;
   struct ureg_dst *temps;

   struct ureg_dst *arrays;
   unsigned num_temp_arrays;
   struct ureg_src *constants;
   int num_constants;
   struct ureg_src *immediates;
   int num_immediates;
   struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
   struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
   struct ureg_dst address[3];
   struct ureg_src samplers[PIPE_MAX_SAMPLERS];
   struct ureg_src buffers[PIPE_MAX_SHADER_BUFFERS];
   struct ureg_src images[PIPE_MAX_SHADER_IMAGES];
   struct ureg_src systemValues[SYSTEM_VALUE_MAX];
   struct ureg_src hw_atomics[PIPE_MAX_HW_ATOMIC_BUFFERS];
   struct ureg_src shared_memory;
   unsigned *array_sizes;
   struct inout_decl *input_decls;
   unsigned num_input_decls;
   struct inout_decl *output_decls;
   unsigned num_output_decls;

   const ubyte *inputMapping;
   const ubyte *outputMapping;

   enum pipe_shader_type procType;  /**< PIPE_SHADER_VERTEX/FRAGMENT */
   bool need_uarl;
   bool tg4_component_in_swizzle;
};

/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
enum tgsi_semantic
_mesa_sysval_to_semantic(unsigned sysval)
{
   switch (sysval) {
   /* Vertex shader */
   case SYSTEM_VALUE_VERTEX_ID:
      return TGSI_SEMANTIC_VERTEXID;
   case SYSTEM_VALUE_INSTANCE_ID:
      return TGSI_SEMANTIC_INSTANCEID;
   case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
      return TGSI_SEMANTIC_VERTEXID_NOBASE;
   case SYSTEM_VALUE_BASE_VERTEX:
      return TGSI_SEMANTIC_BASEVERTEX;
   case SYSTEM_VALUE_BASE_INSTANCE:
      return TGSI_SEMANTIC_BASEINSTANCE;
   case SYSTEM_VALUE_DRAW_ID:
      return TGSI_SEMANTIC_DRAWID;

   /* Geometry shader */
   case SYSTEM_VALUE_INVOCATION_ID:
      return TGSI_SEMANTIC_INVOCATIONID;

   /* Fragment shader */
   case SYSTEM_VALUE_FRAG_COORD:
      return TGSI_SEMANTIC_POSITION;
   case SYSTEM_VALUE_POINT_COORD:
      return TGSI_SEMANTIC_PCOORD;
   case SYSTEM_VALUE_FRONT_FACE:
      return TGSI_SEMANTIC_FACE;
   case SYSTEM_VALUE_SAMPLE_ID:
      return TGSI_SEMANTIC_SAMPLEID;
   case SYSTEM_VALUE_SAMPLE_POS:
      return TGSI_SEMANTIC_SAMPLEPOS;
   case SYSTEM_VALUE_SAMPLE_MASK_IN:
      return TGSI_SEMANTIC_SAMPLEMASK;
   case SYSTEM_VALUE_HELPER_INVOCATION:
      return TGSI_SEMANTIC_HELPER_INVOCATION;

   /* Tessellation shader */
   case SYSTEM_VALUE_TESS_COORD:
      return TGSI_SEMANTIC_TESSCOORD;
   case SYSTEM_VALUE_VERTICES_IN:
      return TGSI_SEMANTIC_VERTICESIN;
   case SYSTEM_VALUE_PRIMITIVE_ID:
      return TGSI_SEMANTIC_PRIMID;
   case SYSTEM_VALUE_TESS_LEVEL_OUTER:
      return TGSI_SEMANTIC_TESSOUTER;
   case SYSTEM_VALUE_TESS_LEVEL_INNER:
      return TGSI_SEMANTIC_TESSINNER;

   /* Compute shader */
   case SYSTEM_VALUE_LOCAL_INVOCATION_ID:
      return TGSI_SEMANTIC_THREAD_ID;
   case SYSTEM_VALUE_WORK_GROUP_ID:
      return TGSI_SEMANTIC_BLOCK_ID;
   case SYSTEM_VALUE_NUM_WORK_GROUPS:
      return TGSI_SEMANTIC_GRID_SIZE;
   case SYSTEM_VALUE_LOCAL_GROUP_SIZE:
      return TGSI_SEMANTIC_BLOCK_SIZE;

   /* ARB_shader_ballot */
   case SYSTEM_VALUE_SUBGROUP_SIZE:
      return TGSI_SEMANTIC_SUBGROUP_SIZE;
   case SYSTEM_VALUE_SUBGROUP_INVOCATION:
      return TGSI_SEMANTIC_SUBGROUP_INVOCATION;
   case SYSTEM_VALUE_SUBGROUP_EQ_MASK:
      return TGSI_SEMANTIC_SUBGROUP_EQ_MASK;
   case SYSTEM_VALUE_SUBGROUP_GE_MASK:
      return TGSI_SEMANTIC_SUBGROUP_GE_MASK;
   case SYSTEM_VALUE_SUBGROUP_GT_MASK:
      return TGSI_SEMANTIC_SUBGROUP_GT_MASK;
   case SYSTEM_VALUE_SUBGROUP_LE_MASK:
      return TGSI_SEMANTIC_SUBGROUP_LE_MASK;
   case SYSTEM_VALUE_SUBGROUP_LT_MASK:
      return TGSI_SEMANTIC_SUBGROUP_LT_MASK;

   /* Unhandled */
   case SYSTEM_VALUE_LOCAL_INVOCATION_INDEX:
   case SYSTEM_VALUE_GLOBAL_INVOCATION_ID:
   case SYSTEM_VALUE_VERTEX_CNT:
   case SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL:
   case SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE:
   case SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID:
   case SYSTEM_VALUE_BARYCENTRIC_PERSP_SIZE:
   default:
      assert(!"Unexpected SYSTEM_VALUE_ enum");
      return TGSI_SEMANTIC_COUNT;
   }
}

/**
 * Map a glsl_to_tgsi constant/immediate to a TGSI immediate.
 */
static struct ureg_src
emit_immediate(struct st_translate *t,
               gl_constant_value values[4],
               GLenum type, int size)
{
   struct ureg_program *ureg = t->ureg;

   switch (type) {
   case GL_FLOAT:
      return ureg_DECL_immediate(ureg, &values[0].f, size);
   case GL_DOUBLE:
      return ureg_DECL_immediate_f64(ureg, (double *)&values[0].f, size);
   case GL_INT64_ARB:
      return ureg_DECL_immediate_int64(ureg, (int64_t *)&values[0].f, size);
   case GL_UNSIGNED_INT64_ARB:
      return ureg_DECL_immediate_uint64(ureg, (uint64_t *)&values[0].f, size);
   case GL_INT:
      return ureg_DECL_immediate_int(ureg, &values[0].i, size);
   case GL_UNSIGNED_INT:
   case GL_BOOL:
      return ureg_DECL_immediate_uint(ureg, &values[0].u, size);
   default:
      assert(!"should not get here - type must be float, int, uint, or bool");
      return ureg_src_undef();
   }
}

/**
 * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register.
 */
static struct ureg_dst
dst_register(struct st_translate *t, gl_register_file file, unsigned index,
             unsigned array_id)
{
   unsigned array;

   switch (file) {
   case PROGRAM_UNDEFINED:
      return ureg_dst_undef();

   case PROGRAM_TEMPORARY:
      /* Allocate space for temporaries on demand. */
      if (index >= t->temps_size) {
         const int inc = align(index - t->temps_size + 1, 4096);

         t->temps = (struct ureg_dst*)
                    realloc(t->temps,
                            (t->temps_size + inc) * sizeof(struct ureg_dst));
         if (!t->temps)
            return ureg_dst_undef();

         memset(t->temps + t->temps_size, 0, inc * sizeof(struct ureg_dst));
         t->temps_size += inc;
      }

      if (ureg_dst_is_undef(t->temps[index]))
         t->temps[index] = ureg_DECL_local_temporary(t->ureg);

      return t->temps[index];

   case PROGRAM_ARRAY:
      assert(array_id && array_id <= t->num_temp_arrays);
      array = array_id - 1;

      if (ureg_dst_is_undef(t->arrays[array]))
         t->arrays[array] = ureg_DECL_array_temporary(
            t->ureg, t->array_sizes[array], TRUE);

      return ureg_dst_array_offset(t->arrays[array], index);

   case PROGRAM_OUTPUT:
      if (!array_id) {
         if (t->procType == PIPE_SHADER_FRAGMENT)
            assert(index < 2 * FRAG_RESULT_MAX);
         else if (t->procType == PIPE_SHADER_TESS_CTRL ||
                  t->procType == PIPE_SHADER_TESS_EVAL)
            assert(index < VARYING_SLOT_TESS_MAX);
         else
            assert(index < VARYING_SLOT_MAX);

         assert(t->outputMapping[index] < ARRAY_SIZE(t->outputs));
         assert(t->outputs[t->outputMapping[index]].File != TGSI_FILE_NULL);
         return t->outputs[t->outputMapping[index]];
      }
      else {
         struct inout_decl *decl =
            find_inout_array(t->output_decls,
                             t->num_output_decls, array_id);
         unsigned mesa_index = decl->mesa_index;
         int slot = t->outputMapping[mesa_index];

         assert(slot != -1 && t->outputs[slot].File == TGSI_FILE_OUTPUT);

         struct ureg_dst dst = t->outputs[slot];
         dst.ArrayID = array_id;
         return ureg_dst_array_offset(dst, index - mesa_index);
      }

   case PROGRAM_ADDRESS:
      return t->address[index];

   default:
      assert(!"unknown dst register file");
      return ureg_dst_undef();
   }
}

static struct ureg_src
translate_src(struct st_translate *t, const st_src_reg *src_reg);

static struct ureg_src
translate_addr(struct st_translate *t, const st_src_reg *reladdr,
               unsigned addr_index)
{
   if (t->need_uarl || !reladdr->is_legal_tgsi_address_operand())
      return ureg_src(t->address[addr_index]);

   return translate_src(t, reladdr);
}

/**
 * Create a TGSI ureg_dst register from an st_dst_reg.
 */
static struct ureg_dst
translate_dst(struct st_translate *t,
              const st_dst_reg *dst_reg,
              bool saturate)
{
   struct ureg_dst dst = dst_register(t, dst_reg->file, dst_reg->index,
                                      dst_reg->array_id);

   if (dst.File == TGSI_FILE_NULL)
      return dst;

   dst = ureg_writemask(dst, dst_reg->writemask);

   if (saturate)
      dst = ureg_saturate(dst);

   if (dst_reg->reladdr != NULL) {
      assert(dst_reg->file != PROGRAM_TEMPORARY);
      dst = ureg_dst_indirect(dst, translate_addr(t, dst_reg->reladdr, 0));
   }

   if (dst_reg->has_index2) {
      if (dst_reg->reladdr2)
         dst = ureg_dst_dimension_indirect(dst,
                                           translate_addr(t, dst_reg->reladdr2, 1),
                                           dst_reg->index2D);
      else
         dst = ureg_dst_dimension(dst, dst_reg->index2D);
   }

   return dst;
}

/**
 * Create a TGSI ureg_src register from an st_src_reg.
 */
static struct ureg_src
translate_src(struct st_translate *t, const st_src_reg *src_reg)
{
   struct ureg_src src;
   int index = src_reg->index;
   int double_reg2 = src_reg->double_reg2 ? 1 : 0;

   switch (src_reg->file) {
   case PROGRAM_UNDEFINED:
      src = ureg_imm4f(t->ureg, 0, 0, 0, 0);
      break;

   case PROGRAM_TEMPORARY:
   case PROGRAM_ARRAY:
      src = ureg_src(dst_register(t, src_reg->file, src_reg->index,
                                  src_reg->array_id));
      break;

   case PROGRAM_OUTPUT: {
      struct ureg_dst dst = dst_register(t, src_reg->file, src_reg->index,
                                         src_reg->array_id);
      assert(dst.WriteMask != 0);
      unsigned shift = ffs(dst.WriteMask) - 1;
      src = ureg_swizzle(ureg_src(dst),
                         shift,
                         MIN2(shift + 1, 3),
                         MIN2(shift + 2, 3),
                         MIN2(shift + 3, 3));
      break;
   }

   case PROGRAM_UNIFORM:
      assert(src_reg->index >= 0);
      src = src_reg->index < t->num_constants ?
               t->constants[src_reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
      break;
   case PROGRAM_STATE_VAR:
   case PROGRAM_CONSTANT:       /* ie, immediate */
      if (src_reg->has_index2)
         src = ureg_src_register(TGSI_FILE_CONSTANT, src_reg->index);
      else
         src = src_reg->index >= 0 && src_reg->index < t->num_constants ?
                  t->constants[src_reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
      break;

   case PROGRAM_IMMEDIATE:
      assert(src_reg->index >= 0 && src_reg->index < t->num_immediates);
      src = t->immediates[src_reg->index];
      break;

   case PROGRAM_INPUT:
      /* GLSL inputs are 64-bit containers, so we have to
       * map back to the original index and add the offset after
       * mapping. */
      index -= double_reg2;
      if (!src_reg->array_id) {
         assert(t->inputMapping[index] < ARRAY_SIZE(t->inputs));
         assert(t->inputs[t->inputMapping[index]].File != TGSI_FILE_NULL);
         src = t->inputs[t->inputMapping[index] + double_reg2];
      }
      else {
         struct inout_decl *decl = find_inout_array(t->input_decls,
                                                    t->num_input_decls,
                                                    src_reg->array_id);
         unsigned mesa_index = decl->mesa_index;
         int slot = t->inputMapping[mesa_index];

         assert(slot != -1 && t->inputs[slot].File == TGSI_FILE_INPUT);

         src = t->inputs[slot];
         src.ArrayID = src_reg->array_id;
         src = ureg_src_array_offset(src, index + double_reg2 - mesa_index);
      }
      break;

   case PROGRAM_ADDRESS:
      src = ureg_src(t->address[src_reg->index]);
      break;

   case PROGRAM_SYSTEM_VALUE:
      assert(src_reg->index < (int) ARRAY_SIZE(t->systemValues));
      src = t->systemValues[src_reg->index];
      break;

   case PROGRAM_HW_ATOMIC:
      src = ureg_src_array_register(TGSI_FILE_HW_ATOMIC, src_reg->index,
                                    src_reg->array_id);
      break;

   default:
      assert(!"unknown src register file");
      return ureg_src_undef();
   }

   if (src_reg->has_index2) {
      /* 2D indexes occur with geometry shader inputs (attrib, vertex)
       * and UBO constant buffers (buffer, position).
       */
      if (src_reg->reladdr2)
         src = ureg_src_dimension_indirect(src,
                                           translate_addr(t, src_reg->reladdr2, 1),
                                           src_reg->index2D);
      else
         src = ureg_src_dimension(src, src_reg->index2D);
   }

   src = ureg_swizzle(src,
                      GET_SWZ(src_reg->swizzle, 0) & 0x3,
                      GET_SWZ(src_reg->swizzle, 1) & 0x3,
                      GET_SWZ(src_reg->swizzle, 2) & 0x3,
                      GET_SWZ(src_reg->swizzle, 3) & 0x3);

   if (src_reg->abs)
      src = ureg_abs(src);

   if ((src_reg->negate & 0xf) == NEGATE_XYZW)
      src = ureg_negate(src);

   if (src_reg->reladdr != NULL) {
      assert(src_reg->file != PROGRAM_TEMPORARY);
      src = ureg_src_indirect(src, translate_addr(t, src_reg->reladdr, 0));
   }

   return src;
}

static struct tgsi_texture_offset
translate_tex_offset(struct st_translate *t,
                     const st_src_reg *in_offset)
{
   struct tgsi_texture_offset offset;
   struct ureg_src src = translate_src(t, in_offset);

   offset.File = src.File;
   offset.Index = src.Index;
   offset.SwizzleX = src.SwizzleX;
   offset.SwizzleY = src.SwizzleY;
   offset.SwizzleZ = src.SwizzleZ;
   offset.Padding = 0;

   assert(!src.Indirect);
   assert(!src.DimIndirect);
   assert(!src.Dimension);
   assert(!src.Absolute); /* those shouldn't be used with integers anyway */
   assert(!src.Negate);

   return offset;
}

static void
compile_tgsi_instruction(struct st_translate *t,
                         const glsl_to_tgsi_instruction *inst)
{
   struct ureg_program *ureg = t->ureg;
   int i;
   struct ureg_dst dst[2];
   struct ureg_src src[4];
   struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET];

   int num_dst;
   int num_src;
   enum tgsi_texture_type tex_target = TGSI_TEXTURE_BUFFER;

   num_dst = num_inst_dst_regs(inst);
   num_src = num_inst_src_regs(inst);

   for (i = 0; i < num_dst; i++)
      dst[i] = translate_dst(t,
                             &inst->dst[i],
                             inst->saturate);

   for (i = 0; i < num_src; i++)
      src[i] = translate_src(t, &inst->src[i]);

   switch (inst->op) {
   case TGSI_OPCODE_BGNLOOP:
   case TGSI_OPCODE_ELSE:
   case TGSI_OPCODE_ENDLOOP:
   case TGSI_OPCODE_IF:
   case TGSI_OPCODE_UIF:
      assert(num_dst == 0);
      ureg_insn(ureg, inst->op, NULL, 0, src, num_src, inst->precise);
      return;

   case TGSI_OPCODE_TEX:
   case TGSI_OPCODE_TEX_LZ:
   case TGSI_OPCODE_TXB:
   case TGSI_OPCODE_TXD:
   case TGSI_OPCODE_TXL:
   case TGSI_OPCODE_TXP:
   case TGSI_OPCODE_TXQ:
   case TGSI_OPCODE_TXQS:
   case TGSI_OPCODE_TXF:
   case TGSI_OPCODE_TXF_LZ:
   case TGSI_OPCODE_TEX2:
   case TGSI_OPCODE_TXB2:
   case TGSI_OPCODE_TXL2:
   case TGSI_OPCODE_TG4:
   case TGSI_OPCODE_LODQ:
   case TGSI_OPCODE_SAMP2HND:
      if (inst->resource.file == PROGRAM_SAMPLER) {
         src[num_src] = t->samplers[inst->resource.index];
         if (t->tg4_component_in_swizzle && inst->op == TGSI_OPCODE_TG4)
            src[num_src].SwizzleX = inst->gather_component;
      } else {
         /* Bindless samplers. */
         src[num_src] = translate_src(t, &inst->resource);
      }
      assert(src[num_src].File != TGSI_FILE_NULL);
      if (inst->resource.reladdr)
         src[num_src] =
            ureg_src_indirect(src[num_src],
                              translate_addr(t, inst->resource.reladdr, 2));
      num_src++;
      for (i = 0; i < (int)inst->tex_offset_num_offset; i++) {
         texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
      }
      tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);

      ureg_tex_insn(ureg,
                    inst->op,
                    dst, num_dst,
                    tex_target,
                    st_translate_texture_type(inst->tex_type),
                    texoffsets, inst->tex_offset_num_offset,
                    src, num_src);
      return;

   case TGSI_OPCODE_RESQ:
   case TGSI_OPCODE_LOAD:
   case TGSI_OPCODE_ATOMUADD:
   case TGSI_OPCODE_ATOMXCHG:
   case TGSI_OPCODE_ATOMCAS:
   case TGSI_OPCODE_ATOMAND:
   case TGSI_OPCODE_ATOMOR:
   case TGSI_OPCODE_ATOMXOR:
   case TGSI_OPCODE_ATOMUMIN:
   case TGSI_OPCODE_ATOMUMAX:
   case TGSI_OPCODE_ATOMIMIN:
   case TGSI_OPCODE_ATOMIMAX:
   case TGSI_OPCODE_ATOMFADD:
   case TGSI_OPCODE_IMG2HND:
   case TGSI_OPCODE_ATOMINC_WRAP:
   case TGSI_OPCODE_ATOMDEC_WRAP:
      for (i = num_src - 1; i >= 0; i--)
         src[i + 1] = src[i];
      num_src++;
      if (inst->resource.file == PROGRAM_MEMORY) {
         src[0] = t->shared_memory;
      } else if (inst->resource.file == PROGRAM_BUFFER) {
         src[0] = t->buffers[inst->resource.index];
      } else if (inst->resource.file == PROGRAM_HW_ATOMIC) {
         src[0] = translate_src(t, &inst->resource);
      } else if (inst->resource.file == PROGRAM_CONSTANT) {
         assert(inst->resource.has_index2);
         src[0] = ureg_src_register(TGSI_FILE_CONSTBUF, inst->resource.index);
      } else {
         assert(inst->resource.file != PROGRAM_UNDEFINED);
         if (inst->resource.file == PROGRAM_IMAGE) {
            src[0] = t->images[inst->resource.index];
         } else {
            /* Bindless images. */
            src[0] = translate_src(t, &inst->resource);
         }
         tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
      }
      if (inst->resource.reladdr)
         src[0] = ureg_src_indirect(src[0],
                                    translate_addr(t, inst->resource.reladdr, 2));
      assert(src[0].File != TGSI_FILE_NULL);
      ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                       inst->buffer_access,
                       tex_target, inst->image_format);
      break;

   case TGSI_OPCODE_STORE:
      if (inst->resource.file == PROGRAM_MEMORY) {
         dst[0] = ureg_dst(t->shared_memory);
      } else if (inst->resource.file == PROGRAM_BUFFER) {
         dst[0] = ureg_dst(t->buffers[inst->resource.index]);
      } else {
         if (inst->resource.file == PROGRAM_IMAGE) {
            dst[0] = ureg_dst(t->images[inst->resource.index]);
         } else {
            /* Bindless images. */
            dst[0] = ureg_dst(translate_src(t, &inst->resource));
         }
         tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
      }
      dst[0] = ureg_writemask(dst[0], inst->dst[0].writemask);
      if (inst->resource.reladdr)
         dst[0] = ureg_dst_indirect(dst[0],
                                    translate_addr(t, inst->resource.reladdr, 2));
      assert(dst[0].File != TGSI_FILE_NULL);
      ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
                       inst->buffer_access,
                       tex_target, inst->image_format);
      break;

   default:
      ureg_insn(ureg,
                inst->op,
                dst, num_dst,
                src, num_src, inst->precise);
      break;
   }
}

/* Invert SamplePos.y when rendering to the default framebuffer. */
static void
emit_samplepos_adjustment(struct st_translate *t, int wpos_y_transform)
{
   struct ureg_program *ureg = t->ureg;

   assert(wpos_y_transform >= 0);
   struct ureg_src trans_const = ureg_DECL_constant(ureg, wpos_y_transform);
   struct ureg_src samplepos_sysval = t->systemValues[SYSTEM_VALUE_SAMPLE_POS];
   struct ureg_dst samplepos_flipped = ureg_DECL_temporary(ureg);
   struct ureg_dst is_fbo = ureg_DECL_temporary(ureg);

   ureg_ADD(ureg, ureg_writemask(samplepos_flipped, TGSI_WRITEMASK_Y),
            ureg_imm1f(ureg, 1), ureg_negate(samplepos_sysval));

   /* If trans.x == 1, use samplepos.y, else use 1 - samplepos.y. */
   ureg_FSEQ(ureg, ureg_writemask(is_fbo, TGSI_WRITEMASK_Y),
             ureg_scalar(trans_const, TGSI_SWIZZLE_X), ureg_imm1f(ureg, 1));
   ureg_UCMP(ureg, ureg_writemask(samplepos_flipped, TGSI_WRITEMASK_Y),
             ureg_src(is_fbo), samplepos_sysval, ureg_src(samplepos_flipped));
   ureg_MOV(ureg, ureg_writemask(samplepos_flipped, TGSI_WRITEMASK_X),
            samplepos_sysval);

   /* Use the result in place of the system value. */
   t->systemValues[SYSTEM_VALUE_SAMPLE_POS] = ureg_src(samplepos_flipped);
}


/**
 * Emit the TGSI instructions for inverting and adjusting WPOS.
 * This code is unavoidable because it also depends on whether
 * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
 */
static void
emit_wpos_adjustment(struct gl_context *ctx,
                     struct st_translate *t,
                     int wpos_transform_const,
                     boolean invert,
                     GLfloat adjX, GLfloat adjY[2])
{
   struct ureg_program *ureg = t->ureg;

   assert(wpos_transform_const >= 0);

   /* Fragment program uses fragment position input.
    * Need to replace instances of INPUT[WPOS] with temp T
    * where T = INPUT[WPOS] is inverted by Y.
    */
   struct ureg_src wpostrans = ureg_DECL_constant(ureg, wpos_transform_const);
   struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
   struct ureg_src *wpos =
      ctx->Const.GLSLFragCoordIsSysVal ?
         &t->systemValues[SYSTEM_VALUE_FRAG_COORD] :
         &t->inputs[t->inputMapping[VARYING_SLOT_POS]];
   struct ureg_src wpos_input = *wpos;

   /* First, apply the coordinate shift: */
   if (adjX || adjY[0] || adjY[1]) {
      if (adjY[0] != adjY[1]) {
         /* Adjust the y coordinate by adjY[1] or adjY[0] respectively
          * depending on whether inversion is actually going to be applied
          * or not, which is determined by testing against the inversion
          * state variable used below, which will be either +1 or -1.
          */
         struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg);

         ureg_CMP(ureg, adj_temp,
                  ureg_scalar(wpostrans, invert ? 2 : 0),
                  ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f),
                  ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f));
         ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp));
      } else {
         ureg_ADD(ureg, wpos_temp, wpos_input,
                  ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f));
      }
      wpos_input = ureg_src(wpos_temp);
   } else {
      /* MOV wpos_temp, input[wpos]
       */
      ureg_MOV(ureg, wpos_temp, wpos_input);
   }

   /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be
    * inversion/identity, or the other way around if we're drawing to an FBO.
    */
   if (invert) {
      /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
       */
      ureg_MAD(ureg,
               ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
               wpos_input,
               ureg_scalar(wpostrans, 0),
               ureg_scalar(wpostrans, 1));
   } else {
      /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
       */
      ureg_MAD(ureg,
               ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y),
               wpos_input,
               ureg_scalar(wpostrans, 2),
               ureg_scalar(wpostrans, 3));
   }

   /* Use wpos_temp as position input from here on:
    */
   *wpos = ureg_src(wpos_temp);
}


/**
 * Emit fragment position/ooordinate code.
 */
static void
emit_wpos(struct st_context *st,
          struct st_translate *t,
          const struct gl_program *program,
          struct ureg_program *ureg,
          int wpos_transform_const)
{
   struct pipe_screen *pscreen = st->pipe->screen;
   GLfloat adjX = 0.0f;
   GLfloat adjY[2] = { 0.0f, 0.0f };
   boolean invert = FALSE;

   /* Query the pixel center conventions supported by the pipe driver and set
    * adjX, adjY to help out if it cannot handle the requested one internally.
    *
    * The bias of the y-coordinate depends on whether y-inversion takes place
    * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are
    * drawing to an FBO (causes additional inversion), and whether the pipe
    * driver origin and the requested origin differ (the latter condition is
    * stored in the 'invert' variable).
    *
    * For height = 100 (i = integer, h = half-integer, l = lower, u = upper):
    *
    * center shift only:
    * i -> h: +0.5
    * h -> i: -0.5
    *
    * inversion only:
    * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99
    * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5
    * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0
    * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5
    *
    * inversion and center shift:
    * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5
    * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99
    * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
    * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
    */
   if (program->info.fs.origin_upper_left) {
      /* Fragment shader wants origin in upper-left */
      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
         /* the driver supports upper-left origin */
      }
      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) {
         /* the driver supports lower-left origin, need to invert Y */
         ureg_property(ureg, TGSI_PROPERTY_FS_COORD_ORIGIN,
                       TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
         invert = TRUE;
      }
      else
         assert(0);
   }
   else {
      /* Fragment shader wants origin in lower-left */
      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT))
         /* the driver supports lower-left origin */
         ureg_property(ureg, TGSI_PROPERTY_FS_COORD_ORIGIN,
                       TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT))
         /* the driver supports upper-left origin, need to invert Y */
         invert = TRUE;
      else
         assert(0);
   }

   if (program->info.fs.pixel_center_integer) {
      /* Fragment shader wants pixel center integer */
      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
         /* the driver supports pixel center integer */
         adjY[1] = 1.0f;
         ureg_property(ureg, TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
                       TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
      }
      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
         /* the driver supports pixel center half integer, need to bias X,Y */
         adjX = -0.5f;
         adjY[0] = -0.5f;
         adjY[1] = 0.5f;
      }
      else
         assert(0);
   }
   else {
      /* Fragment shader wants pixel center half integer */
      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
         /* the driver supports pixel center half integer */
      }
      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
         /* the driver supports pixel center integer, need to bias X,Y */
         adjX = adjY[0] = adjY[1] = 0.5f;
         ureg_property(ureg, TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
                       TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
      }
      else
         assert(0);
   }

   /* we invert after adjustment so that we avoid the MOV to temporary,
    * and reuse the adjustment ADD instead */
   emit_wpos_adjustment(st->ctx, t, wpos_transform_const, invert, adjX, adjY);
}

/**
 * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
 * TGSI uses +1 for front, -1 for back.
 * This function converts the TGSI value to the GL value.  Simply clamping/
 * saturating the value to [0,1] does the job.
 */
static void
emit_face_var(struct gl_context *ctx, struct st_translate *t)
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_dst face_temp = ureg_DECL_temporary(ureg);
   struct ureg_src face_input = t->inputs[t->inputMapping[VARYING_SLOT_FACE]];

   if (ctx->Const.NativeIntegers) {
      ureg_FSGE(ureg, face_temp, face_input, ureg_imm1f(ureg, 0));
   }
   else {
      /* MOV_SAT face_temp, input[face] */
      ureg_MOV(ureg, ureg_saturate(face_temp), face_input);
   }

   /* Use face_temp as face input from here on: */
   t->inputs[t->inputMapping[VARYING_SLOT_FACE]] = ureg_src(face_temp);
}

static void
emit_compute_block_size(const struct gl_program *prog,
                        struct ureg_program *ureg) {
   ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH,
                 prog->info.cs.local_size[0]);
   ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT,
                 prog->info.cs.local_size[1]);
   ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH,
                 prog->info.cs.local_size[2]);
}

struct sort_inout_decls {
   bool operator()(const struct inout_decl &a, const struct inout_decl &b) const {
      return mapping[a.mesa_index] < mapping[b.mesa_index];
   }

   const ubyte *mapping;
};

/* Sort the given array of decls by the corresponding slot (TGSI file index).
 *
 * This is for the benefit of older drivers which are broken when the
 * declarations aren't sorted in this way.
 */
static void
sort_inout_decls_by_slot(struct inout_decl *decls,
                         unsigned count,
                         const ubyte mapping[])
{
   sort_inout_decls sorter;
   sorter.mapping = mapping;
   std::sort(decls, decls + count, sorter);
}

static enum tgsi_interpolate_mode
st_translate_interp(enum glsl_interp_mode glsl_qual, GLuint varying)
{
   switch (glsl_qual) {
   case INTERP_MODE_NONE:
      if (varying == VARYING_SLOT_COL0 || varying == VARYING_SLOT_COL1)
         return TGSI_INTERPOLATE_COLOR;
      return TGSI_INTERPOLATE_PERSPECTIVE;
   case INTERP_MODE_SMOOTH:
      return TGSI_INTERPOLATE_PERSPECTIVE;
   case INTERP_MODE_FLAT:
      return TGSI_INTERPOLATE_CONSTANT;
   case INTERP_MODE_NOPERSPECTIVE:
      return TGSI_INTERPOLATE_LINEAR;
   default:
      assert(0 && "unexpected interp mode in st_translate_interp()");
      return TGSI_INTERPOLATE_PERSPECTIVE;
   }
}

/**
 * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format.
 * \param program  the program to translate
 * \param numInputs  number of input registers used
 * \param inputMapping  maps Mesa fragment program inputs to TGSI generic
 *                      input indexes
 * \param inputSemanticName  the TGSI_SEMANTIC flag for each input
 * \param inputSemanticIndex  the semantic index (ex: which texcoord) for
 *                            each input
 * \param interpMode  the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
 * \param numOutputs  number of output registers used
 * \param outputMapping  maps Mesa fragment program outputs to TGSI
 *                       generic outputs
 * \param outputSemanticName  the TGSI_SEMANTIC flag for each output
 * \param outputSemanticIndex  the semantic index (ex: which texcoord) for
 *                             each output
 *
 * \return  PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY
 */
extern "C" enum pipe_error
st_translate_program(
   struct gl_context *ctx,
   enum pipe_shader_type procType,
   struct ureg_program *ureg,
   glsl_to_tgsi_visitor *program,
   const struct gl_program *proginfo,
   GLuint numInputs,
   const ubyte inputMapping[],
   const ubyte inputSlotToAttr[],
   const ubyte inputSemanticName[],
   const ubyte inputSemanticIndex[],
   const ubyte interpMode[],
   GLuint numOutputs,
   const ubyte outputMapping[],
   const ubyte outputSemanticName[],
   const ubyte outputSemanticIndex[])
{
   struct pipe_screen *screen = st_context(ctx)->pipe->screen;
   struct st_translate *t;
   unsigned i;
   struct gl_program_constants *frag_const =
      &ctx->Const.Program[MESA_SHADER_FRAGMENT];
   enum pipe_error ret = PIPE_OK;

   assert(numInputs <= ARRAY_SIZE(t->inputs));
   assert(numOutputs <= ARRAY_SIZE(t->outputs));

   ASSERT_BITFIELD_SIZE(st_src_reg, type, GLSL_TYPE_ERROR);
   ASSERT_BITFIELD_SIZE(st_dst_reg, type, GLSL_TYPE_ERROR);
   ASSERT_BITFIELD_SIZE(glsl_to_tgsi_instruction, tex_type, GLSL_TYPE_ERROR);
   ASSERT_BITFIELD_SIZE(glsl_to_tgsi_instruction, image_format, PIPE_FORMAT_COUNT);
   ASSERT_BITFIELD_SIZE(glsl_to_tgsi_instruction, tex_target,
                        (gl_texture_index) (NUM_TEXTURE_TARGETS - 1));
   ASSERT_BITFIELD_SIZE(glsl_to_tgsi_instruction, image_format,
                        (enum pipe_format) (PIPE_FORMAT_COUNT - 1));
   ASSERT_BITFIELD_SIZE(glsl_to_tgsi_instruction, op,
                        (enum tgsi_opcode) (TGSI_OPCODE_LAST - 1));

   t = CALLOC_STRUCT(st_translate);
   if (!t) {
      ret = PIPE_ERROR_OUT_OF_MEMORY;
      goto out;
   }

   t->procType = procType;
   t->need_uarl = !screen->get_param(screen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
   t->tg4_component_in_swizzle = screen->get_param(screen, PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE);
   t->inputMapping = inputMapping;
   t->outputMapping = outputMapping;
   t->ureg = ureg;
   t->num_temp_arrays = program->next_array;
   if (t->num_temp_arrays)
      t->arrays = (struct ureg_dst*)
                  calloc(t->num_temp_arrays, sizeof(t->arrays[0]));

   /*
    * Declare input attributes.
    */
   switch (procType) {
   case PIPE_SHADER_FRAGMENT:
   case PIPE_SHADER_GEOMETRY:
   case PIPE_SHADER_TESS_EVAL:
   case PIPE_SHADER_TESS_CTRL:
      sort_inout_decls_by_slot(program->inputs, program->num_inputs, inputMapping);

      for (i = 0; i < program->num_inputs; ++i) {
         struct inout_decl *decl = &program->inputs[i];
         unsigned slot = inputMapping[decl->mesa_index];
         struct ureg_src src;
         ubyte tgsi_usage_mask = decl->usage_mask;

         if (glsl_base_type_is_64bit(decl->base_type)) {
            if (tgsi_usage_mask == 1)
               tgsi_usage_mask = TGSI_WRITEMASK_XY;
            else if (tgsi_usage_mask == 2)
               tgsi_usage_mask = TGSI_WRITEMASK_ZW;
            else
               tgsi_usage_mask = TGSI_WRITEMASK_XYZW;
         }

         enum tgsi_interpolate_mode interp_mode = TGSI_INTERPOLATE_CONSTANT;
         enum tgsi_interpolate_loc interp_location = TGSI_INTERPOLATE_LOC_CENTER;
         if (procType == PIPE_SHADER_FRAGMENT) {
            assert(interpMode);
            interp_mode = interpMode[slot] != TGSI_INTERPOLATE_COUNT ?
               (enum tgsi_interpolate_mode) interpMode[slot] :
               st_translate_interp(decl->interp, inputSlotToAttr[slot]);

            interp_location = (enum tgsi_interpolate_loc) decl->interp_loc;
         }

         src = ureg_DECL_fs_input_cyl_centroid_layout(ureg,
                  (enum tgsi_semantic) inputSemanticName[slot],
                  inputSemanticIndex[slot],
                  interp_mode, 0, interp_location, slot, tgsi_usage_mask,
                  decl->array_id, decl->size);

         for (unsigned j = 0; j < decl->size; ++j) {
            if (t->inputs[slot + j].File != TGSI_FILE_INPUT) {
               /* The ArrayID is set up in dst_register */
               t->inputs[slot + j] = src;
               t->inputs[slot + j].ArrayID = 0;
               t->inputs[slot + j].Index += j;
            }
         }
      }
      break;
   case PIPE_SHADER_VERTEX:
      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
      }
      break;
   case PIPE_SHADER_COMPUTE:
      break;
   default:
      assert(0);
   }

   /*
    * Declare output attributes.
    */
   switch (procType) {
   case PIPE_SHADER_FRAGMENT:
   case PIPE_SHADER_COMPUTE:
      break;
   case PIPE_SHADER_GEOMETRY:
   case PIPE_SHADER_TESS_EVAL:
   case PIPE_SHADER_TESS_CTRL:
   case PIPE_SHADER_VERTEX:
      sort_inout_decls_by_slot(program->outputs, program->num_outputs, outputMapping);

      for (i = 0; i < program->num_outputs; ++i) {
         struct inout_decl *decl = &program->outputs[i];
         unsigned slot = outputMapping[decl->mesa_index];
         struct ureg_dst dst;
         ubyte tgsi_usage_mask = decl->usage_mask;

         if (glsl_base_type_is_64bit(decl->base_type)) {
            if (tgsi_usage_mask == 1)
               tgsi_usage_mask = TGSI_WRITEMASK_XY;
            else if (tgsi_usage_mask == 2)
               tgsi_usage_mask = TGSI_WRITEMASK_ZW;
            else
               tgsi_usage_mask = TGSI_WRITEMASK_XYZW;
         }

         dst = ureg_DECL_output_layout(ureg,
                     (enum tgsi_semantic) outputSemanticName[slot],
                     outputSemanticIndex[slot],
                     decl->gs_out_streams,
                     slot, tgsi_usage_mask, decl->array_id, decl->size, decl->invariant);
         dst.Invariant = decl->invariant;
         for (unsigned j = 0; j < decl->size; ++j) {
            if (t->outputs[slot + j].File != TGSI_FILE_OUTPUT) {
               /* The ArrayID is set up in dst_register */
               t->outputs[slot + j] = dst;
               t->outputs[slot + j].ArrayID = 0;
               t->outputs[slot + j].Index += j;
               t->outputs[slot + j].Invariant = decl->invariant;
            }
         }
      }
      break;
   default:
      assert(0);
   }

   if (procType == PIPE_SHADER_FRAGMENT) {
      if (program->shader->Program->info.fs.early_fragment_tests ||
          program->shader->Program->info.fs.post_depth_coverage) {
         ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1);

         if (program->shader->Program->info.fs.post_depth_coverage)
            ureg_property(ureg, TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE, 1);
      }

      if (proginfo->info.inputs_read & VARYING_BIT_POS) {
          /* Must do this after setting up t->inputs. */
          emit_wpos(st_context(ctx), t, proginfo, ureg,
                    program->wpos_transform_const);
      }

      if (proginfo->info.inputs_read & VARYING_BIT_FACE)
         emit_face_var(ctx, t);

      for (i = 0; i < numOutputs; i++) {
         switch (outputSemanticName[i]) {
         case TGSI_SEMANTIC_POSITION:
            t->outputs[i] = ureg_DECL_output(ureg,
                                             TGSI_SEMANTIC_POSITION, /* Z/Depth */
                                             outputSemanticIndex[i]);
            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Z);
            break;
         case TGSI_SEMANTIC_STENCIL:
            t->outputs[i] = ureg_DECL_output(ureg,
                                             TGSI_SEMANTIC_STENCIL, /* Stencil */
                                             outputSemanticIndex[i]);
            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Y);
            break;
         case TGSI_SEMANTIC_COLOR:
            t->outputs[i] = ureg_DECL_output(ureg,
                                             TGSI_SEMANTIC_COLOR,
                                             outputSemanticIndex[i]);
            break;
         case TGSI_SEMANTIC_SAMPLEMASK:
            t->outputs[i] = ureg_DECL_output(ureg,
                                             TGSI_SEMANTIC_SAMPLEMASK,
                                             outputSemanticIndex[i]);
            /* TODO: If we ever support more than 32 samples, this will have
             * to become an array.
             */
            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
            break;
         default:
            assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR");
            ret = PIPE_ERROR_BAD_INPUT;
            goto out;
         }
      }
   }
   else if (procType == PIPE_SHADER_VERTEX) {
      for (i = 0; i < numOutputs; i++) {
         if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) {
            /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */
            ureg_MOV(ureg,
                     ureg_writemask(t->outputs[i], TGSI_WRITEMASK_YZW),
                     ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f));
            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
         }
      }
   }

   if (procType == PIPE_SHADER_COMPUTE) {
      emit_compute_block_size(proginfo, ureg);
   }

   /* Declare address register.
    */
   if (program->num_address_regs > 0) {
      assert(program->num_address_regs <= 3);
      for (int i = 0; i < program->num_address_regs; i++)
         t->address[i] = ureg_DECL_address(ureg);
   }

   /* Declare misc input registers
    */
   {
      GLbitfield64 sysInputs = proginfo->info.system_values_read;

      for (i = 0; sysInputs; i++) {
         if (sysInputs & (1ull << i)) {
            enum tgsi_semantic semName = _mesa_sysval_to_semantic(i);

            t->systemValues[i] = ureg_DECL_system_value(ureg, semName, 0);

            if (semName == TGSI_SEMANTIC_INSTANCEID ||
                semName == TGSI_SEMANTIC_VERTEXID) {
               /* From Gallium perspective, these system values are always
                * integer, and require native integer support.  However, if
                * native integer is supported on the vertex stage but not the
                * pixel stage (e.g, i915g + draw), Mesa will generate IR that
                * assumes these system values are floats. To resolve the
                * inconsistency, we insert a U2F.
                */
               struct st_context *st = st_context(ctx);
               struct pipe_screen *pscreen = st->pipe->screen;
               assert(procType == PIPE_SHADER_VERTEX);
               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
               (void) pscreen;
               if (!ctx->Const.NativeIntegers) {
                  struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg);
                  ureg_U2F(t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X),
                           t->systemValues[i]);
                  t->systemValues[i] = ureg_scalar(ureg_src(temp), 0);
               }
            }

            if (procType == PIPE_SHADER_FRAGMENT &&
                semName == TGSI_SEMANTIC_POSITION)
               emit_wpos(st_context(ctx), t, proginfo, ureg,
                         program->wpos_transform_const);

            if (procType == PIPE_SHADER_FRAGMENT &&
                semName == TGSI_SEMANTIC_SAMPLEPOS)
               emit_samplepos_adjustment(t, program->wpos_transform_const);

            sysInputs &= ~(1ull << i);
         }
      }
   }

   t->array_sizes = program->array_sizes;
   t->input_decls = program->inputs;
   t->num_input_decls = program->num_inputs;
   t->output_decls = program->outputs;
   t->num_output_decls = program->num_outputs;

   /* Emit constants and uniforms.  TGSI uses a single index space for these,
    * so we put all the translated regs in t->constants.
    */
   if (proginfo->Parameters) {
      t->constants = (struct ureg_src *)
         calloc(proginfo->Parameters->NumParameters, sizeof(t->constants[0]));
      if (t->constants == NULL) {
         ret = PIPE_ERROR_OUT_OF_MEMORY;
         goto out;
      }
      t->num_constants = proginfo->Parameters->NumParameters;

      for (i = 0; i < proginfo->Parameters->NumParameters; i++) {
         unsigned pvo = proginfo->Parameters->ParameterValueOffset[i];

         switch (proginfo->Parameters->Parameters[i].Type) {
         case PROGRAM_STATE_VAR:
         case PROGRAM_UNIFORM:
            t->constants[i] = ureg_DECL_constant(ureg, i);
            break;

         /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect
          * addressing of the const buffer.
          * FIXME: Be smarter and recognize param arrays:
          * indirect addressing is only valid within the referenced
          * array.
          */
         case PROGRAM_CONSTANT:
            if (program->indirect_addr_consts)
               t->constants[i] = ureg_DECL_constant(ureg, i);
            else
               t->constants[i] = emit_immediate(t,
                                                proginfo->Parameters->ParameterValues + pvo,
                                                proginfo->Parameters->Parameters[i].DataType,
                                                4);
            break;
         default:
            break;
         }
      }
   }

   for (i = 0; i < proginfo->info.num_ubos; i++) {
      unsigned size = proginfo->sh.UniformBlocks[i]->UniformBufferSize;
      unsigned num_const_vecs = (size + 15) / 16;
      unsigned first, last;
      assert(num_const_vecs > 0);
      first = 0;
      last = num_const_vecs > 0 ? num_const_vecs - 1 : 0;
      ureg_DECL_constant2D(t->ureg, first, last, i + 1);
   }

   /* Emit immediate values.
    */
   t->immediates = (struct ureg_src *)
      calloc(program->num_immediates, sizeof(struct ureg_src));
   if (t->immediates == NULL) {
      ret = PIPE_ERROR_OUT_OF_MEMORY;
      goto out;
   }
   t->num_immediates = program->num_immediates;

   i = 0;
   foreach_in_list(immediate_storage, imm, &program->immediates) {
      assert(i < program->num_immediates);
      t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size32);
   }
   assert(i == program->num_immediates);

   /* texture samplers */
   for (i = 0; i < frag_const->MaxTextureImageUnits; i++) {
      if (program->samplers_used & (1u << i)) {
         enum tgsi_return_type type =
            st_translate_texture_type(program->sampler_types[i]);

         t->samplers[i] = ureg_DECL_sampler(ureg, i);

         ureg_DECL_sampler_view(ureg, i, program->sampler_targets[i],
                                type, type, type, type);
      }
   }

   /* Declare atomic and shader storage buffers. */
   {
      struct gl_program *prog = program->prog;

      if (!st_context(ctx)->has_hw_atomics) {
         for (i = 0; i < prog->info.num_abos; i++) {
            unsigned index = (prog->info.num_ssbos +
                              prog->sh.AtomicBuffers[i]->Binding);
            assert(prog->sh.AtomicBuffers[i]->Binding <
                   frag_const->MaxAtomicBuffers);
            t->buffers[index] = ureg_DECL_buffer(ureg, index, true);
         }
      } else {
         for (i = 0; i < program->num_atomics; i++) {
            struct hwatomic_decl *ainfo = &program->atomic_info[i];
            gl_uniform_storage *uni_storage = &prog->sh.data->UniformStorage[ainfo->location];
            int base = uni_storage->offset / ATOMIC_COUNTER_SIZE;
            ureg_DECL_hw_atomic(ureg, base, base + ainfo->size - 1, ainfo->binding,
                                ainfo->array_id);
         }
      }

      assert(prog->info.num_ssbos <= frag_const->MaxShaderStorageBlocks);
      for (i = 0; i < prog->info.num_ssbos; i++) {
         t->buffers[i] = ureg_DECL_buffer(ureg, i, false);
      }
   }

   if (program->use_shared_memory)
      t->shared_memory = ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED);

   for (i = 0; i < program->shader->Program->info.num_images; i++) {
      if (program->images_used & (1 << i)) {
         t->images[i] = ureg_DECL_image(ureg, i,
                                        program->image_targets[i],
                                        program->image_formats[i],
                                        program->image_wr[i],
                                        false);
      }
   }

   /* Emit each instruction in turn:
    */
   foreach_in_list(glsl_to_tgsi_instruction, inst, &program->instructions)
      compile_tgsi_instruction(t, inst);

   /* Set the next shader stage hint for VS and TES. */
   switch (procType) {
   case PIPE_SHADER_VERTEX:
   case PIPE_SHADER_TESS_EVAL:
      if (program->shader_program->SeparateShader)
         break;

      for (i = program->shader->Stage+1; i <= MESA_SHADER_FRAGMENT; i++) {
         if (program->shader_program->_LinkedShaders[i]) {
            ureg_set_next_shader_processor(
                  ureg, pipe_shader_type_from_mesa((gl_shader_stage)i));
            break;
         }
      }
      break;
   default:
      ; /* nothing - silence compiler warning */
   }

out:
   if (t) {
      free(t->arrays);
      free(t->temps);
      free(t->constants);
      t->num_constants = 0;
      free(t->immediates);
      t->num_immediates = 0;
      FREE(t);
   }

   return ret;
}
/* ----------------------------- End TGSI code ------------------------------ */


/**
 * Convert a shader's GLSL IR into a Mesa gl_program, although without
 * generating Mesa IR.
 */
static struct gl_program *
get_mesa_program_tgsi(struct gl_context *ctx,
                      struct gl_shader_program *shader_program,
                      struct gl_linked_shader *shader)
{
   glsl_to_tgsi_visitor* v;
   struct gl_program *prog;
   struct gl_shader_compiler_options *options =
         &ctx->Const.ShaderCompilerOptions[shader->Stage];
   struct pipe_screen *pscreen = ctx->st->pipe->screen;
   enum pipe_shader_type ptarget = pipe_shader_type_from_mesa(shader->Stage);
   unsigned skip_merge_registers;

   validate_ir_tree(shader->ir);

   prog = shader->Program;

   prog->Parameters = _mesa_new_parameter_list();
   v = new glsl_to_tgsi_visitor();
   v->ctx = ctx;
   v->prog = prog;
   v->shader_program = shader_program;
   v->shader = shader;
   v->options = options;
   v->native_integers = ctx->Const.NativeIntegers;

   v->have_sqrt = pscreen->get_shader_param(pscreen, ptarget,
                                            PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED);
   v->have_fma = pscreen->get_shader_param(pscreen, ptarget,
                                           PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED);
   v->has_tex_txf_lz = pscreen->get_param(pscreen,
                                          PIPE_CAP_TGSI_TEX_TXF_LZ);
   v->need_uarl = !pscreen->get_param(pscreen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);

   v->tg4_component_in_swizzle = pscreen->get_param(pscreen, PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE);
   v->variables = _mesa_hash_table_create(v->mem_ctx, _mesa_hash_pointer,
                                          _mesa_key_pointer_equal);
   skip_merge_registers =
      pscreen->get_shader_param(pscreen, ptarget,
                                PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS);

   _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
                                               prog->Parameters);

   /* Remove reads from output registers. */
   if (!pscreen->get_param(pscreen, PIPE_CAP_TGSI_CAN_READ_OUTPUTS))
      lower_output_reads(shader->Stage, shader->ir);

   /* Emit intermediate IR for main(). */
   visit_exec_list(shader->ir, v);

#if 0
   /* Print out some information (for debugging purposes) used by the
    * optimization passes. */
   {
      int i;
      int *first_writes = ralloc_array(v->mem_ctx, int, v->next_temp);
      int *first_reads = ralloc_array(v->mem_ctx, int, v->next_temp);
      int *last_writes = ralloc_array(v->mem_ctx, int, v->next_temp);
      int *last_reads = ralloc_array(v->mem_ctx, int, v->next_temp);

      for (i = 0; i < v->next_temp; i++) {
         first_writes[i] = -1;
         first_reads[i] = -1;
         last_writes[i] = -1;
         last_reads[i] = -1;
      }
      v->get_first_temp_read(first_reads);
      v->get_last_temp_read_first_temp_write(last_reads, first_writes);
      v->get_last_temp_write(last_writes);
      for (i = 0; i < v->next_temp; i++)
         printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, first_reads[i],
                first_writes[i],
                last_reads[i],
                last_writes[i]);
      ralloc_free(first_writes);
      ralloc_free(first_reads);
      ralloc_free(last_writes);
      ralloc_free(last_reads);
   }
#endif

   /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */
   v->simplify_cmp();
   v->copy_propagate();

   while (v->eliminate_dead_code());

   v->merge_two_dsts();

   if (!skip_merge_registers) {
      v->split_arrays();
      v->copy_propagate();
      while (v->eliminate_dead_code());

      v->merge_registers();
      v->copy_propagate();
      while (v->eliminate_dead_code());
   }

   v->renumber_registers();

   /* Write the END instruction. */
   v->emit_asm(NULL, TGSI_OPCODE_END);

   if (ctx->_Shader->Flags & GLSL_DUMP) {
      _mesa_log("\n");
      _mesa_log("GLSL IR for linked %s program %d:\n",
             _mesa_shader_stage_to_string(shader->Stage),
             shader_program->Name);
      _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL);
      _mesa_log("\n\n");
   }

   do_set_program_inouts(shader->ir, prog, shader->Stage);

   _mesa_copy_linked_program_data(shader_program, shader);

   if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_SKIP_SHRINK_IO_ARRAYS)) {
      mark_array_io(v->inputs, v->num_inputs,
                    &prog->info.inputs_read,
                    prog->DualSlotInputs,
                    &prog->info.patch_inputs_read);

      mark_array_io(v->outputs, v->num_outputs,
                    &prog->info.outputs_written, 0ULL,
                    &prog->info.patch_outputs_written);
   } else  {
      shrink_array_declarations(v->inputs, v->num_inputs,
                                &prog->info.inputs_read,
                                prog->DualSlotInputs,
                                &prog->info.patch_inputs_read);
      shrink_array_declarations(v->outputs, v->num_outputs,
                                &prog->info.outputs_written, 0ULL,
                                &prog->info.patch_outputs_written);
   }

   count_resources(v, prog);

   /* The GLSL IR won't be needed anymore. */
   ralloc_free(shader->ir);
   shader->ir = NULL;

   /* This must be done before the uniform storage is associated. */
   if (shader->Stage == MESA_SHADER_FRAGMENT &&
       (prog->info.inputs_read & VARYING_BIT_POS ||
        prog->info.system_values_read & (1ull << SYSTEM_VALUE_FRAG_COORD) ||
        prog->info.system_values_read & (1ull << SYSTEM_VALUE_SAMPLE_POS))) {
      static const gl_state_index16 wposTransformState[STATE_LENGTH] = {
         STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM
      };

      v->wpos_transform_const = _mesa_add_state_reference(prog->Parameters,
                                                          wposTransformState);
   }

   /* Avoid reallocation of the program parameter list, because the uniform
    * storage is only associated with the original parameter list.
    * This should be enough for Bitmap and DrawPixels constants.
    */
   _mesa_reserve_parameter_storage(prog->Parameters, 8);

   /* This has to be done last.  Any operation the can cause
    * prog->ParameterValues to get reallocated (e.g., anything that adds a
    * program constant) has to happen before creating this linkage.
    */
   _mesa_associate_uniform_storage(ctx, shader_program, prog);
   if (!shader_program->data->LinkStatus) {
      free_glsl_to_tgsi_visitor(v);
      _mesa_reference_program(ctx, &shader->Program, NULL);
      return NULL;
   }

   st_program(prog)->glsl_to_tgsi = v;

   PRINT_STATS(v->print_stats());

   return prog;
}

/* See if there are unsupported control flow statements. */
class ir_control_flow_info_visitor : public ir_hierarchical_visitor {
private:
   const struct gl_shader_compiler_options *options;
public:
   ir_control_flow_info_visitor(const struct gl_shader_compiler_options *options)
      : options(options),
        unsupported(false)
   {
   }

   virtual ir_visitor_status visit_enter(ir_function *ir)
   {
      /* Other functions are skipped (same as glsl_to_tgsi). */
      if (strcmp(ir->name, "main") == 0)
         return visit_continue;

      return visit_continue_with_parent;
   }

   virtual ir_visitor_status visit_enter(ir_call *ir)
   {
      if (!ir->callee->is_intrinsic()) {
         unsupported = true; /* it's a function call */
         return visit_stop;
      }
      return visit_continue;
   }

   virtual ir_visitor_status visit_enter(ir_return *ir)
   {
      if (options->EmitNoMainReturn) {
         unsupported = true;
         return visit_stop;
      }
      return visit_continue;
   }

   bool unsupported;
};

static bool
has_unsupported_control_flow(exec_list *ir,
                             const struct gl_shader_compiler_options *options)
{
   ir_control_flow_info_visitor visitor(options);
   visit_list_elements(&visitor, ir);
   return visitor.unsupported;
}

/**
 * Link a shader.
 * This actually involves converting GLSL IR into an intermediate TGSI-like IR
 * with code lowering and other optimizations.
 */
GLboolean
st_link_tgsi(struct gl_context *ctx, struct gl_shader_program *prog)
{
   struct pipe_screen *pscreen = ctx->st->pipe->screen;

   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
      struct gl_linked_shader *shader = prog->_LinkedShaders[i];
      if (shader == NULL)
         continue;

      exec_list *ir = shader->ir;
      gl_shader_stage stage = shader->Stage;
      enum pipe_shader_type ptarget = pipe_shader_type_from_mesa(stage);
      const struct gl_shader_compiler_options *options =
            &ctx->Const.ShaderCompilerOptions[stage];

      unsigned if_threshold = pscreen->get_shader_param(pscreen, ptarget,
                                                        PIPE_SHADER_CAP_LOWER_IF_THRESHOLD);
      if (ctx->Const.GLSLOptimizeConservatively) {
         /* Do it once and repeat only if there's unsupported control flow. */
         do {
            do_common_optimization(ir, true, true, options,
                                   ctx->Const.NativeIntegers);
            lower_if_to_cond_assign((gl_shader_stage)i, ir,
                                    options->MaxIfDepth, if_threshold);
         } while (has_unsupported_control_flow(ir, options));
      } else {
         /* Repeat it until it stops making changes. */
         bool progress;
         do {
            progress = do_common_optimization(ir, true, true, options,
                                              ctx->Const.NativeIntegers);
            progress |= lower_if_to_cond_assign((gl_shader_stage)i, ir,
                                                options->MaxIfDepth, if_threshold);
         } while (progress);
      }

      /* Do this again to lower ir_binop_vector_extract introduced
       * by optimization passes.
       */
      do_vec_index_to_cond_assign(ir);

      validate_ir_tree(ir);

      struct gl_program *linked_prog =
         get_mesa_program_tgsi(ctx, prog, shader);
      st_set_prog_affected_state_flags(linked_prog);

      if (linked_prog) {
         if (!ctx->Driver.ProgramStringNotify(ctx,
                                              _mesa_shader_stage_to_program(i),
                                              linked_prog)) {
            _mesa_reference_program(ctx, &shader->Program, NULL);
            return GL_FALSE;
         }
      }
   }

   return GL_TRUE;
}
