/**************************************************************************
 * 
 * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 * 
 * 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, sub license, 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 NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
 * 
 **************************************************************************/

/*
 * \author
 * Michal Krol,
 * Keith Whitwell
 */

#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "st_context.h"
#include "program/prog_instruction.h"
#include "program/prog_parameter.h"
#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"


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


struct label {
   unsigned branch_target;
   unsigned token;
};


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

   struct ureg_dst temps[MAX_PROGRAM_TEMPS];
   struct ureg_src *constants;
   struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
   struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
   struct ureg_dst address[1];
   struct ureg_src samplers[PIPE_MAX_SAMPLERS];
   struct ureg_src systemValues[SYSTEM_VALUE_MAX];

   const GLuint *inputMapping;
   const GLuint *outputMapping;

   /* For every instruction that contains a label (eg CALL), keep
    * details so that we can go back afterwards and emit the correct
    * tgsi instruction number for each label.
    */
   struct label *labels;
   unsigned labels_size;
   unsigned labels_count;

   /* Keep a record of the tgsi instruction number that each mesa
    * instruction starts at, will be used to fix up labels after
    * translation.
    */
   unsigned *insn;
   unsigned insn_size;
   unsigned insn_count;

   unsigned procType;  /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */

   boolean error;
};


/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = {
   TGSI_SEMANTIC_FACE,
   TGSI_SEMANTIC_VERTEXID,
   TGSI_SEMANTIC_INSTANCEID
};


/**
 * Make note of a branch to a label in the TGSI code.
 * After we've emitted all instructions, we'll go over the list
 * of labels built here and patch the TGSI code with the actual
 * location of each label.
 */
static unsigned *get_label( struct st_translate *t,
                            unsigned branch_target )
{
   unsigned i;

   if (t->labels_count + 1 >= t->labels_size) {
      t->labels_size = 1 << (util_logbase2(t->labels_size) + 1);
      t->labels = realloc(t->labels, t->labels_size * sizeof t->labels[0]);
      if (t->labels == NULL) {
         static unsigned dummy;
         t->error = TRUE;
         return &dummy;
      }
   }

   i = t->labels_count++;
   t->labels[i].branch_target = branch_target;
   return &t->labels[i].token;
}


/**
 * Called prior to emitting the TGSI code for each Mesa instruction.
 * Allocate additional space for instructions if needed.
 * Update the insn[] array so the next Mesa instruction points to
 * the next TGSI instruction.
 */
static void set_insn_start( struct st_translate *t,
                            unsigned start )
{
   if (t->insn_count + 1 >= t->insn_size) {
      t->insn_size = 1 << (util_logbase2(t->insn_size) + 1);
      t->insn = realloc(t->insn, t->insn_size * sizeof t->insn[0]);
      if (t->insn == NULL) {
         t->error = TRUE;
         return;
      }
   }

   t->insn[t->insn_count++] = start;
}


/**
 * Map a Mesa dst register to a TGSI ureg_dst register.
 */
static struct ureg_dst
dst_register( struct st_translate *t,
              gl_register_file file,
              GLuint index )
{
   switch( file ) {
   case PROGRAM_UNDEFINED:
      return ureg_dst_undef();

   case PROGRAM_TEMPORARY:
      if (ureg_dst_is_undef(t->temps[index]))
         t->temps[index] = ureg_DECL_temporary( t->ureg );

      return t->temps[index];

   case PROGRAM_OUTPUT:
      if (t->procType == TGSI_PROCESSOR_VERTEX)
         assert(index < VERT_RESULT_MAX);
      else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
         assert(index < FRAG_RESULT_MAX);
      else
         assert(index < GEOM_RESULT_MAX);

      assert(t->outputMapping[index] < Elements(t->outputs));

      return t->outputs[t->outputMapping[index]];

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

   default:
      debug_assert( 0 );
      return ureg_dst_undef();
   }
}


/**
 * Map a Mesa src register to a TGSI ureg_src register.
 */
static struct ureg_src
src_register( struct st_translate *t,
              gl_register_file file,
              GLint index )
{
   switch( file ) {
   case PROGRAM_UNDEFINED:
      return ureg_src_undef();

   case PROGRAM_TEMPORARY:
      assert(index >= 0);
      assert(index < Elements(t->temps));
      if (ureg_dst_is_undef(t->temps[index]))
         t->temps[index] = ureg_DECL_temporary( t->ureg );
      return ureg_src(t->temps[index]);

   case PROGRAM_NAMED_PARAM:
   case PROGRAM_ENV_PARAM:
   case PROGRAM_LOCAL_PARAM:
   case PROGRAM_UNIFORM:
      assert(index >= 0);
      return t->constants[index];
   case PROGRAM_STATE_VAR:
   case PROGRAM_CONSTANT:       /* ie, immediate */
      if (index < 0)
         return ureg_DECL_constant( t->ureg, 0 );
      else
         return t->constants[index];

   case PROGRAM_INPUT:
      assert(t->inputMapping[index] < Elements(t->inputs));
      return t->inputs[t->inputMapping[index]];

   case PROGRAM_OUTPUT:
      assert(t->outputMapping[index] < Elements(t->outputs));
      return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */

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

   case PROGRAM_SYSTEM_VALUE:
      assert(index < Elements(t->systemValues));
      return t->systemValues[index];

   default:
      debug_assert( 0 );
      return ureg_src_undef();
   }
}


/**
 * Map mesa texture target to TGSI texture target.
 */
unsigned
st_translate_texture_target( GLuint textarget,
                          GLboolean shadow )
{
   if (shadow) {
      switch( textarget ) {
      case TEXTURE_1D_INDEX:   return TGSI_TEXTURE_SHADOW1D;
      case TEXTURE_2D_INDEX:   return TGSI_TEXTURE_SHADOW2D;
      case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT;
      case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY;
      case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY;
      case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_SHADOWCUBE;
      default: break;
      }
   }

   switch( textarget ) {
   case TEXTURE_1D_INDEX:   return TGSI_TEXTURE_1D;
   case TEXTURE_2D_INDEX:   return TGSI_TEXTURE_2D;
   case TEXTURE_3D_INDEX:   return TGSI_TEXTURE_3D;
   case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE;
   case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT;
   case TEXTURE_1D_ARRAY_INDEX:   return TGSI_TEXTURE_1D_ARRAY;
   case TEXTURE_2D_ARRAY_INDEX:   return TGSI_TEXTURE_2D_ARRAY;
   case TEXTURE_EXTERNAL_INDEX:   return TGSI_TEXTURE_2D;
   default:
      debug_assert( 0 );
      return TGSI_TEXTURE_1D;
   }
}


/**
 * Create a TGSI ureg_dst register from a Mesa dest register.
 */
static struct ureg_dst
translate_dst( struct st_translate *t,
               const struct prog_dst_register *DstReg,
               boolean saturate,
               boolean clamp_color)
{
   struct ureg_dst dst = dst_register( t, 
                                       DstReg->File,
                                       DstReg->Index );

   dst = ureg_writemask( dst, 
                         DstReg->WriteMask );
   
   if (saturate)
      dst = ureg_saturate( dst );
   else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) {
      /* Clamp colors for ARB_color_buffer_float. */
      switch (t->procType) {
      case TGSI_PROCESSOR_VERTEX:
         /* XXX if the geometry shader is present, this must be done there
          * instead of here. */
         if (DstReg->Index == VERT_RESULT_COL0 ||
             DstReg->Index == VERT_RESULT_COL1 ||
             DstReg->Index == VERT_RESULT_BFC0 ||
             DstReg->Index == VERT_RESULT_BFC1) {
            dst = ureg_saturate(dst);
         }
         break;

      case TGSI_PROCESSOR_FRAGMENT:
         if (DstReg->Index >= FRAG_RESULT_COLOR) {
            dst = ureg_saturate(dst);
         }
         break;
      }
   }

   if (DstReg->RelAddr)
      dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );

   return dst;
}


/**
 * Create a TGSI ureg_src register from a Mesa src register.
 */
static struct ureg_src
translate_src( struct st_translate *t,
               const struct prog_src_register *SrcReg )
{
   struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );

   if (t->procType == TGSI_PROCESSOR_GEOMETRY && SrcReg->HasIndex2) {
      src = src_register( t, SrcReg->File, SrcReg->Index2 );
      if (SrcReg->RelAddr2)
         src = ureg_src_dimension_indirect( src, ureg_src(t->address[0]),
                                            SrcReg->Index);
      else
         src = ureg_src_dimension( src, SrcReg->Index);
   }

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

   if (SrcReg->Negate == NEGATE_XYZW)
      src = ureg_negate(src);

   if (SrcReg->Abs) 
      src = ureg_abs(src);

   if (SrcReg->RelAddr) {
      src = ureg_src_indirect( src, ureg_src(t->address[0]));
      if (SrcReg->File != PROGRAM_INPUT &&
          SrcReg->File != PROGRAM_OUTPUT) {
         /* If SrcReg->Index was negative, it was set to zero in
          * src_register().  Reassign it now.  But don't do this
          * for input/output regs since they get remapped while
          * const buffers don't.
          */
         src.Index = SrcReg->Index;
      }
   }

   return src;
}


static struct ureg_src swizzle_4v( struct ureg_src src,
                                   const unsigned *swz )
{
   return ureg_swizzle( src, swz[0], swz[1], swz[2], swz[3] );
}


/**
 * Translate a SWZ instruction into a MOV, MUL or MAD instruction.  EG:
 *
 *   SWZ dst, src.x-y10 
 * 
 * becomes:
 *
 *   MAD dst {1,-1,0,0}, src.xyxx, {0,0,1,0}
 */
static void emit_swz( struct st_translate *t,
                      struct ureg_dst dst,
                      const struct prog_src_register *SrcReg )
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );

   unsigned negate_mask =  SrcReg->Negate;

   unsigned one_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ONE) << 0 |
                        (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ONE) << 1 |
                        (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ONE) << 2 |
                        (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ONE) << 3);

   unsigned zero_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ZERO) << 0 |
                         (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ZERO) << 1 |
                         (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ZERO) << 2 |
                         (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ZERO) << 3);

   unsigned negative_one_mask = one_mask & negate_mask;
   unsigned positive_one_mask = one_mask & ~negate_mask;
   
   struct ureg_src imm;
   unsigned i;
   unsigned mul_swizzle[4] = {0,0,0,0};
   unsigned add_swizzle[4] = {0,0,0,0};
   unsigned src_swizzle[4] = {0,0,0,0};
   boolean need_add = FALSE;
   boolean need_mul = FALSE;

   if (dst.WriteMask == 0)
      return;

   /* Is this just a MOV?
    */
   if (zero_mask == 0 &&
       one_mask == 0 &&
       (negate_mask == 0 || negate_mask == TGSI_WRITEMASK_XYZW)) 
   {
      ureg_MOV( ureg, dst, translate_src( t, SrcReg ));
      return;
   }

#define IMM_ZERO    0
#define IMM_ONE     1
#define IMM_NEG_ONE 2

   imm = ureg_imm3f( ureg, 0, 1, -1 );

   for (i = 0; i < 4; i++) {
      unsigned bit = 1 << i;

      if (dst.WriteMask & bit) {
         if (positive_one_mask & bit) {
            mul_swizzle[i] = IMM_ZERO;
            add_swizzle[i] = IMM_ONE;
            need_add = TRUE;
         }
         else if (negative_one_mask & bit) {
            mul_swizzle[i] = IMM_ZERO;
            add_swizzle[i] = IMM_NEG_ONE;
            need_add = TRUE;
         }
         else if (zero_mask & bit) {
            mul_swizzle[i] = IMM_ZERO;
            add_swizzle[i] = IMM_ZERO;
            need_add = TRUE;
         }
         else {
            add_swizzle[i] = IMM_ZERO;
            src_swizzle[i] = GET_SWZ(SrcReg->Swizzle, i);
            need_mul = TRUE;
            if (negate_mask & bit) {
               mul_swizzle[i] = IMM_NEG_ONE;
            }
            else {
               mul_swizzle[i] = IMM_ONE;
            }
         }
      }
   }

   if (need_mul && need_add) {
      ureg_MAD( ureg, 
                dst,
                swizzle_4v( src, src_swizzle ),
                swizzle_4v( imm, mul_swizzle ),
                swizzle_4v( imm, add_swizzle ) );
   }
   else if (need_mul) {
      ureg_MUL( ureg, 
                dst,
                swizzle_4v( src, src_swizzle ),
                swizzle_4v( imm, mul_swizzle ) );
   }
   else if (need_add) {
      ureg_MOV( ureg, 
                dst,
                swizzle_4v( imm, add_swizzle ) );
   }
   else {
      debug_assert(0);
   }

#undef IMM_ZERO
#undef IMM_ONE
#undef IMM_NEG_ONE
}


/**
 * Negate the value of DDY to match GL semantics where (0,0) is the
 * lower-left corner of the window.
 * Note that the GL_ARB_fragment_coord_conventions extension will
 * effect this someday.
 */
static void emit_ddy( struct st_translate *t,
                      struct ureg_dst dst,
                      const struct prog_src_register *SrcReg )
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_src src = translate_src( t, SrcReg );
   src = ureg_negate( src );
   ureg_DDY( ureg, dst, src );
}



static unsigned
translate_opcode( unsigned op )
{
   switch( op ) {
   case OPCODE_ARL:
      return TGSI_OPCODE_ARL;
   case OPCODE_ABS:
      return TGSI_OPCODE_ABS;
   case OPCODE_ADD:
      return TGSI_OPCODE_ADD;
   case OPCODE_BGNLOOP:
      return TGSI_OPCODE_BGNLOOP;
   case OPCODE_BGNSUB:
      return TGSI_OPCODE_BGNSUB;
   case OPCODE_BRA:
      return TGSI_OPCODE_BRA;
   case OPCODE_BRK:
      return TGSI_OPCODE_BRK;
   case OPCODE_CAL:
      return TGSI_OPCODE_CAL;
   case OPCODE_CMP:
      return TGSI_OPCODE_CMP;
   case OPCODE_CONT:
      return TGSI_OPCODE_CONT;
   case OPCODE_COS:
      return TGSI_OPCODE_COS;
   case OPCODE_DDX:
      return TGSI_OPCODE_DDX;
   case OPCODE_DDY:
      return TGSI_OPCODE_DDY;
   case OPCODE_DP2:
      return TGSI_OPCODE_DP2;
   case OPCODE_DP2A:
      return TGSI_OPCODE_DP2A;
   case OPCODE_DP3:
      return TGSI_OPCODE_DP3;
   case OPCODE_DP4:
      return TGSI_OPCODE_DP4;
   case OPCODE_DPH:
      return TGSI_OPCODE_DPH;
   case OPCODE_DST:
      return TGSI_OPCODE_DST;
   case OPCODE_ELSE:
      return TGSI_OPCODE_ELSE;
   case OPCODE_EMIT_VERTEX:
      return TGSI_OPCODE_EMIT;
   case OPCODE_END_PRIMITIVE:
      return TGSI_OPCODE_ENDPRIM;
   case OPCODE_ENDIF:
      return TGSI_OPCODE_ENDIF;
   case OPCODE_ENDLOOP:
      return TGSI_OPCODE_ENDLOOP;
   case OPCODE_ENDSUB:
      return TGSI_OPCODE_ENDSUB;
   case OPCODE_EX2:
      return TGSI_OPCODE_EX2;
   case OPCODE_EXP:
      return TGSI_OPCODE_EXP;
   case OPCODE_FLR:
      return TGSI_OPCODE_FLR;
   case OPCODE_FRC:
      return TGSI_OPCODE_FRC;
   case OPCODE_IF:
      return TGSI_OPCODE_IF;
   case OPCODE_TRUNC:
      return TGSI_OPCODE_TRUNC;
   case OPCODE_KIL:
      return TGSI_OPCODE_KIL;
   case OPCODE_KIL_NV:
      return TGSI_OPCODE_KILP;
   case OPCODE_LG2:
      return TGSI_OPCODE_LG2;
   case OPCODE_LOG:
      return TGSI_OPCODE_LOG;
   case OPCODE_LIT:
      return TGSI_OPCODE_LIT;
   case OPCODE_LRP:
      return TGSI_OPCODE_LRP;
   case OPCODE_MAD:
      return TGSI_OPCODE_MAD;
   case OPCODE_MAX:
      return TGSI_OPCODE_MAX;
   case OPCODE_MIN:
      return TGSI_OPCODE_MIN;
   case OPCODE_MOV:
      return TGSI_OPCODE_MOV;
   case OPCODE_MUL:
      return TGSI_OPCODE_MUL;
   case OPCODE_NOP:
      return TGSI_OPCODE_NOP;
   case OPCODE_NRM3:
      return TGSI_OPCODE_NRM;
   case OPCODE_NRM4:
      return TGSI_OPCODE_NRM4;
   case OPCODE_POW:
      return TGSI_OPCODE_POW;
   case OPCODE_RCP:
      return TGSI_OPCODE_RCP;
   case OPCODE_RET:
      return TGSI_OPCODE_RET;
   case OPCODE_RSQ:
      return TGSI_OPCODE_RSQ;
   case OPCODE_SCS:
      return TGSI_OPCODE_SCS;
   case OPCODE_SEQ:
      return TGSI_OPCODE_SEQ;
   case OPCODE_SGE:
      return TGSI_OPCODE_SGE;
   case OPCODE_SGT:
      return TGSI_OPCODE_SGT;
   case OPCODE_SIN:
      return TGSI_OPCODE_SIN;
   case OPCODE_SLE:
      return TGSI_OPCODE_SLE;
   case OPCODE_SLT:
      return TGSI_OPCODE_SLT;
   case OPCODE_SNE:
      return TGSI_OPCODE_SNE;
   case OPCODE_SSG:
      return TGSI_OPCODE_SSG;
   case OPCODE_SUB:
      return TGSI_OPCODE_SUB;
   case OPCODE_TEX:
      return TGSI_OPCODE_TEX;
   case OPCODE_TXB:
      return TGSI_OPCODE_TXB;
   case OPCODE_TXD:
      return TGSI_OPCODE_TXD;
   case OPCODE_TXL:
      return TGSI_OPCODE_TXL;
   case OPCODE_TXP:
      return TGSI_OPCODE_TXP;
   case OPCODE_XPD:
      return TGSI_OPCODE_XPD;
   case OPCODE_END:
      return TGSI_OPCODE_END;
   default:
      debug_assert( 0 );
      return TGSI_OPCODE_NOP;
   }
}


static void
compile_instruction(
   struct st_translate *t,
   const struct prog_instruction *inst,
   boolean clamp_dst_color_output)
{
   struct ureg_program *ureg = t->ureg;
   GLuint i;
   struct ureg_dst dst[1] = { { 0 } };
   struct ureg_src src[4];
   unsigned num_dst;
   unsigned num_src;

   num_dst = _mesa_num_inst_dst_regs( inst->Opcode );
   num_src = _mesa_num_inst_src_regs( inst->Opcode );

   if (num_dst) 
      dst[0] = translate_dst( t, 
                              &inst->DstReg,
                              inst->SaturateMode,
                              clamp_dst_color_output);

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

   switch( inst->Opcode ) {
   case OPCODE_SWZ:
      emit_swz( t, dst[0], &inst->SrcReg[0] );
      return;

   case OPCODE_BGNLOOP:
   case OPCODE_CAL:
   case OPCODE_ELSE:
   case OPCODE_ENDLOOP:
   case OPCODE_IF:
      debug_assert(num_dst == 0);
      ureg_label_insn( ureg,
                       translate_opcode( inst->Opcode ),
                       src, num_src,
                       get_label( t, inst->BranchTarget ));
      return;

   case OPCODE_TEX:
   case OPCODE_TXB:
   case OPCODE_TXD:
   case OPCODE_TXL:
   case OPCODE_TXP:
      src[num_src++] = t->samplers[inst->TexSrcUnit];
      ureg_tex_insn( ureg,
                     translate_opcode( inst->Opcode ),
                     dst, num_dst, 
                     st_translate_texture_target( inst->TexSrcTarget,
                                               inst->TexShadow ),
                     NULL, 0,
                     src, num_src );
      return;

   case OPCODE_SCS:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_XPD:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_NOISE1:
   case OPCODE_NOISE2:
   case OPCODE_NOISE3:
   case OPCODE_NOISE4:
      /* 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.
       */
      ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) );
      break;
		 
   case OPCODE_DDY:
      emit_ddy( t, dst[0], &inst->SrcReg[0] );
      break;

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


/**
 * 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 st_translate *t,
                      const struct gl_program *program,
                      boolean invert,
                      GLfloat adjX, GLfloat adjY[2])
{
   struct ureg_program *ureg = t->ureg;

   /* Fragment program uses fragment position input.
    * Need to replace instances of INPUT[WPOS] with temp T
    * where T = INPUT[WPOS] by y is inverted.
    */
   static const gl_state_index wposTransformState[STATE_LENGTH]
      = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 };
   
   /* XXX: note we are modifying the incoming shader here!  Need to
    * do this before emitting the constant decls below, or this
    * will be missed:
    */
   unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
                                                       wposTransformState);

   struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
   struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
   struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_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_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:
    */
   t->inputs[t->inputMapping[FRAG_ATTRIB_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)
{
   const struct gl_fragment_program *fp =
      (const struct gl_fragment_program *) program;
   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 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 (fp->OriginUpperLeft) {
      /* 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_fs_coord_origin(ureg, 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_fs_coord_origin(ureg, 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 (fp->PixelCenterInteger) {
      /* 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_fs_coord_pixel_center(ureg, 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_fs_coord_pixel_center(ureg, 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(t, program, 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 st_translate *t,
               const struct gl_program *program )
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_dst face_temp = ureg_DECL_temporary( ureg );
   struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]];

   /* MOV_SAT face_temp, input[face]
    */
   face_temp = ureg_saturate( face_temp );
   ureg_MOV( ureg, face_temp, face_input );

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


static void
emit_edgeflags( struct st_translate *t,
                 const struct gl_program *program )
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]];
   struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]];

   ureg_MOV( ureg, edge_dst, edge_src );
}


/**
 * Translate Mesa program 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
 */
enum pipe_error
st_translate_mesa_program(
   struct gl_context *ctx,
   uint procType,
   struct ureg_program *ureg,
   const struct gl_program *program,
   GLuint numInputs,
   const GLuint inputMapping[],
   const ubyte inputSemanticName[],
   const ubyte inputSemanticIndex[],
   const GLuint interpMode[],
   GLuint numOutputs,
   const GLuint outputMapping[],
   const ubyte outputSemanticName[],
   const ubyte outputSemanticIndex[],
   boolean passthrough_edgeflags,
   boolean clamp_color)
{
   struct st_translate translate, *t;
   unsigned i;
   enum pipe_error ret = PIPE_OK;

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

   t = &translate;
   memset(t, 0, sizeof *t);

   t->procType = procType;
   t->inputMapping = inputMapping;
   t->outputMapping = outputMapping;
   t->ureg = ureg;

   /*_mesa_print_program(program);*/

   /*
    * Declare input attributes.
    */
   if (procType == TGSI_PROCESSOR_FRAGMENT) {
      for (i = 0; i < numInputs; i++) {
         if (program->InputFlags[0] & PROG_PARAM_BIT_CYL_WRAP) {
            t->inputs[i] = ureg_DECL_fs_input_cyl(ureg,
                                                  inputSemanticName[i],
                                                  inputSemanticIndex[i],
                                                  interpMode[i],
                                                  TGSI_CYLINDRICAL_WRAP_X);
         }
         else {
            t->inputs[i] = ureg_DECL_fs_input(ureg,
                                              inputSemanticName[i],
                                              inputSemanticIndex[i],
                                              interpMode[i]);
         }
      }

      if (program->InputsRead & FRAG_BIT_WPOS) {
         /* Must do this after setting up t->inputs, and before
          * emitting constant references, below:
          */
         emit_wpos(st_context(ctx), t, program, ureg);
      }

      if (program->InputsRead & FRAG_BIT_FACE) {
         emit_face_var( t, program );
      }

      /*
       * Declare output attributes.
       */
      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;
         default:
            debug_assert(0);
            return 0;
         }
      }
   }
   else if (procType == TGSI_PROCESSOR_GEOMETRY) {
      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_gs_input(ureg,
                                           i,
                                           inputSemanticName[i],
                                           inputSemanticIndex[i]);
      }

      for (i = 0; i < numOutputs; i++) {
         t->outputs[i] = ureg_DECL_output( ureg,
                                           outputSemanticName[i],
                                           outputSemanticIndex[i] );
      }
   }
   else {
      assert(procType == TGSI_PROCESSOR_VERTEX);

      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
      }

      for (i = 0; i < numOutputs; i++) {
         t->outputs[i] = ureg_DECL_output( ureg,
                                           outputSemanticName[i],
                                           outputSemanticIndex[i] );
      }
      if (passthrough_edgeflags)
         emit_edgeflags( t, program );
   }

   /* Declare address register.
    */
   if (program->NumAddressRegs > 0) {
      debug_assert( program->NumAddressRegs == 1 );
      t->address[0] = ureg_DECL_address( ureg );
   }

   /* Declare misc input registers
    */
   {
      GLbitfield sysInputs = program->SystemValuesRead;
      unsigned numSys = 0;
      for (i = 0; sysInputs; i++) {
         if (sysInputs & (1 << i)) {
            unsigned semName = mesa_sysval_to_semantic[i];
            t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, 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 == TGSI_PROCESSOR_VERTEX);
               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
               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);
               }
            }
            numSys++;
            sysInputs &= ~(1 << i);
         }
      }
   }

   if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) {
      /* If temps are accessed with indirect addressing, declare temporaries
       * in sequential order.  Else, we declare them on demand elsewhere.
       */
      for (i = 0; i < program->NumTemporaries; i++) {
         /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
         t->temps[i] = ureg_DECL_temporary( t->ureg );
      }
   }

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

      for (i = 0; i < program->Parameters->NumParameters; i++) {
         switch (program->Parameters->Parameters[i].Type) {
         case PROGRAM_ENV_PARAM:
         case PROGRAM_LOCAL_PARAM:
         case PROGRAM_STATE_VAR:
         case PROGRAM_NAMED_PARAM:
         case PROGRAM_UNIFORM:
            t->constants[i] = ureg_DECL_constant( ureg, i );
            break;

            /* Emit immediates 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->IndirectRegisterFiles & PROGRAM_ANY_CONST)
               t->constants[i] = ureg_DECL_constant( ureg, i );
            else
               t->constants[i] = 
                  ureg_DECL_immediate( ureg,
                                       (const float*) program->Parameters->ParameterValues[i],
                                       4 );
            break;
         default:
            break;
         }
      }
   }

   /* texture samplers */
   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
      if (program->SamplersUsed & (1 << i)) {
         t->samplers[i] = ureg_DECL_sampler( ureg, i );
      }
   }

   /* Emit each instruction in turn:
    */
   for (i = 0; i < program->NumInstructions; i++) {
      set_insn_start( t, ureg_get_instruction_number( ureg ));
      compile_instruction( t, &program->Instructions[i], clamp_color );
   }

   /* Fix up all emitted labels:
    */
   for (i = 0; i < t->labels_count; i++) {
      ureg_fixup_label( ureg,
                        t->labels[i].token,
                        t->insn[t->labels[i].branch_target] );
   }

out:
   FREE(t->insn);
   FREE(t->labels);
   FREE(t->constants);

   if (t->error) {
      debug_printf("%s: translate error flag set\n", __FUNCTION__);
   }

   return ret;
}


/**
 * Tokens cannot be free with free otherwise the builtin gallium
 * malloc debugging will get confused.
 */
void
st_free_tokens(const struct tgsi_token *tokens)
{
   ureg_free_tokens(tokens);
}
