1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * obtaining a copy of this software and associated documentation
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * files (the "Software"), to deal in the Software without
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * restriction, including without limitation the rights to use, copy,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * modify, merge, publish, distribute, sublicense, and/or sell copies
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software, and to permit persons to whom the Software is
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * furnished to do so, subject to the following conditions:
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * included in all copies or substantial portions of the Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************/
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_tgsi_emit.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_context.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_vs_postamble( struct svga_shader_emitter *emit );
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ps_postamble( struct svga_shader_emitter *emit );
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_opcode(
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint opcode )
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (opcode) {
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS;
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DP2A:       return SVGA3DOP_DP2ADD;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_FRC:        return SVGA3DOP_FRC;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_MAD:        return SVGA3DOP_MAD;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_MAX:        return SVGA3DOP_MAX;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_MIN:        return SVGA3DOP_MIN;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_MOV:        return SVGA3DOP_MOV;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_MUL:        return SVGA3DOP_MUL;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_NOP:        return SVGA3DOP_NOP;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_NRM4:       return SVGA3DOP_NRM;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_printf("Unkown opcode %u\n", opcode);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert( 0 );
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return SVGA3DOP_LAST_INST;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned translate_file( unsigned file )
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (file) {
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_TEMPORARY: return SVGA3DREG_TEMP;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_INPUT:     return SVGA3DREG_INPUT;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_OUTPUT:    return SVGA3DREG_OUTPUT; /* VS3.0+ only */
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_IMMEDIATE: return SVGA3DREG_CONST;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_CONSTANT:  return SVGA3DREG_CONST;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_SAMPLER:   return SVGA3DREG_SAMPLER;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_ADDRESS:   return SVGA3DREG_ADDR;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert( 0 );
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return SVGA3DREG_TEMP;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic SVGA3dShaderDestToken
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_dst_register( struct svga_shader_emitter *emit,
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn,
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        unsigned idx )
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dest;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg->Register.File) {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_OUTPUT:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Output registers encode semantic information in their name.
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Need to lookup a table built at decl time:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dest = emit->output_map[reg->Register.Index];
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned index = reg->Register.Index;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(index < SVGA3D_TEMPREG_MAX);
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         index = MIN2(index, SVGA3D_TEMPREG_MAX - 1);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dest = dst_register(translate_file(reg->Register.File), index);
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dest.mask = reg->Register.WriteMask;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dest.mask);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->Instruction.Saturate)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dest.dstMod = SVGA3DDSTMOD_SATURATE;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return dest;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct src_register
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswizzle( struct src_register src,
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int x,
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int y,
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int z,
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int w )
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   x = (src.base.swizzle >> (x * 2)) & 0x3;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   y = (src.base.swizzle >> (y * 2)) & 0x3;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   z = (src.base.swizzle >> (z * 2)) & 0x3;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   w = (src.base.swizzle >> (w * 2)) & 0x3;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.base.swizzle = TRANSLATE_SWIZZLE(x,y,z,w);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct src_register
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgscalar( struct src_register src,
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        int comp )
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swizzle( src, comp, comp, comp, comp );
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_arl_needs_adjustment( const struct svga_shader_emitter *emit )
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->num_arl_consts; ++i) {
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->arl_consts[i].arl_num == emit->current_arl)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return FALSE;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_arl_adjustment( const struct svga_shader_emitter *emit )
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->num_arl_consts; ++i) {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->arl_consts[i].arl_num == emit->current_arl)
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return emit->arl_consts[i].number;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct src_register
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_src_register( const struct svga_shader_emitter *emit,
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_src_register *reg )
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (reg->Register.File) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_INPUT:
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Input registers are referred to by their semantic name rather
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * than by index.  Use the mapping build up from the decls:
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = emit->input_map[reg->Register.Index];
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_FILE_IMMEDIATE:
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Immediates are appended after TGSI constants in the D3D
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * constant buffer.
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = src_register( translate_file( reg->Register.File ),
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          reg->Register.Index + emit->imm_start );
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = src_register( translate_file( reg->Register.File ),
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          reg->Register.Index );
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Indirect addressing.
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (reg->Register.Indirect) {
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->unit == PIPE_SHADER_FRAGMENT) {
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Pixel shaders have only loop registers for relative
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * addressing into inputs. Ignore the redundant address
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * register, the contents of aL should be in sync with it.
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (reg->Register.File == TGSI_FILE_INPUT) {
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.base.relAddr = 1;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.indirect = src_token(SVGA3DREG_LOOP, 0);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Constant buffers only.
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (reg->Register.File == TGSI_FILE_CONSTANT) {
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* we shift the offset towards the minimum */
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (svga_arl_needs_adjustment( emit )) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               src.base.num -= svga_arl_adjustment( emit );
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.base.relAddr = 1;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Not really sure what should go in the second token:
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.indirect = src_token( SVGA3DREG_ADDR,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      reg->Indirect.Index );
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.indirect.swizzle = SWIZZLE_XXXX;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = swizzle( src,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  reg->Register.SwizzleX,
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  reg->Register.SwizzleY,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  reg->Register.SwizzleZ,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  reg->Register.SwizzleW );
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* src.mod isn't a bitfield, unfortunately:
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * See tgsi_util_get_full_src_register_sign_mode for implementation details.
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (reg->Register.Absolute) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Negate)
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.base.srcMod = SVGA3DSRCMOD_ABS;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Negate)
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.base.srcMod = SVGA3DSRCMOD_NEG;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.base.srcMod = SVGA3DSRCMOD_NONE;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get a temporary register.
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: if we exceed the temporary register limit we just use
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register SVGA3D_TEMPREG_MAX - 1.
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE SVGA3dShaderDestToken
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_temp( struct svga_shader_emitter *emit )
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i = emit->nr_hw_temp + emit->internal_temp_count++;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(i < SVGA3D_TEMPREG_MAX);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = MIN2(i, SVGA3D_TEMPREG_MAX - 1);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return dst_register( SVGA3DREG_TEMP, i );
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Release a single temp.  Currently only effective if it was the last
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allocated temp, otherwise release will be delayed until the next
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * call to reset_temp_regs().
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrelease_temp( struct svga_shader_emitter *emit,
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              SVGA3dShaderDestToken temp )
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (temp.num == emit->internal_temp_count - 1)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit->internal_temp_count--;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void reset_temp_regs( struct svga_shader_emitter *emit )
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->internal_temp_count = 0;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Replace the src with the temporary specified in the dst, but copying
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * only the necessary channels, and preserving the original swizzle (which is
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * important given that several opcodes have constraints in the allowed
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swizzles).
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_repl( struct svga_shader_emitter *emit,
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          SVGA3dShaderDestToken dst,
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct src_register *src0)
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned src0_swizzle;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(SVGA3dShaderGetRegType(dst.value) == SVGA3DREG_TEMP);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0_swizzle = src0->base.swizzle;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst.mask = 0;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (chan = 0; chan < 4; ++chan) {
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned swizzle = (src0_swizzle >> (chan *2)) & 0x3;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst.mask |= 1 << swizzle;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dst.mask);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0->base.swizzle = SVGA3DSWIZZLE_NONE;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, *src0 ))
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *src0 = src( dst );
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0->base.swizzle = src0_swizzle;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_op0( struct svga_shader_emitter *emit,
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderInstToken inst,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderDestToken dest )
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit_instruction( emit, inst ) &&
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_dst( emit, dest ));
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_op1( struct svga_shader_emitter *emit,
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderInstToken inst,
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderDestToken dest,
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src0 )
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_op1( emit, inst, dest, src0 );
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* SVGA shaders may not refer to >1 constant register in a single
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction.  This function checks for that usage and inserts a
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * move to temporary if detected.
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The same applies to input registers -- at most a single input
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register may be read by any instruction.
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_op2( struct svga_shader_emitter *emit,
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderInstToken inst,
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderDestToken dest,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src0,
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src1 )
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderRegType type0, type1;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_temp = FALSE;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp.value = 0;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type0 = SVGA3dShaderGetRegType( src0.base.value );
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type1 = SVGA3dShaderGetRegType( src1.base.value );
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type0 == SVGA3DREG_CONST &&
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       type1 == SVGA3DREG_CONST &&
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       src0.base.num != src1.base.num)
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp = TRUE;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type0 == SVGA3DREG_INPUT &&
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       type1 == SVGA3DREG_INPUT &&
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       src0.base.num != src1.base.num)
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp = TRUE;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp = get_temp( emit );
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_repl( emit, temp, &src0 ))
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_op2( emit, inst, dest, src0, src1 ))
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp)
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, temp );
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* SVGA shaders may not refer to >1 constant register in a single
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction.  This function checks for that usage and inserts a
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * move to temporary if detected.
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_op3( struct svga_shader_emitter *emit,
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderInstToken inst,
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderDestToken dest,
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src0,
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src1,
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src2 )
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp0;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp1;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_temp0 = FALSE;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_temp1 = FALSE;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderRegType type0, type1, type2;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp0.value = 0;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp1.value = 0;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type0 = SVGA3dShaderGetRegType( src0.base.value );
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type1 = SVGA3dShaderGetRegType( src1.base.value );
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type2 = SVGA3dShaderGetRegType( src2.base.value );
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (inst.op != SVGA3DOP_SINCOS) {
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type0 == SVGA3DREG_CONST &&
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ((type1 == SVGA3DREG_CONST && src0.base.num != src1.base.num) ||
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_temp0 = TRUE;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type1 == SVGA3DREG_CONST &&
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          (type2 == SVGA3DREG_CONST && src1.base.num != src2.base.num))
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_temp1 = TRUE;
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type0 == SVGA3DREG_INPUT &&
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ((type1 == SVGA3DREG_INPUT && src0.base.num != src1.base.num) ||
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp0 = TRUE;
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type1 == SVGA3DREG_INPUT &&
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (type2 == SVGA3DREG_INPUT && src1.base.num != src2.base.num))
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp1 = TRUE;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp0) {
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp0 = get_temp( emit );
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_repl( emit, temp0, &src0 ))
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp1) {
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp1 = get_temp( emit );
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_repl( emit, temp1, &src1 ))
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_op3( emit, inst, dest, src0, src1, src2 ))
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp1)
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, temp1 );
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp0)
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, temp0 );
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* SVGA shaders may not refer to >1 constant register in a single
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction.  This function checks for that usage and inserts a
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * move to temporary if detected.
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_op4( struct svga_shader_emitter *emit,
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderInstToken inst,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           SVGA3dShaderDestToken dest,
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src0,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src1,
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src2,
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct src_register src3)
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp0;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp3;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_temp0 = FALSE;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_temp3 = FALSE;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderRegType type0, type1, type2, type3;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp0.value = 0;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp3.value = 0;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type0 = SVGA3dShaderGetRegType( src0.base.value );
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type1 = SVGA3dShaderGetRegType( src1.base.value );
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type2 = SVGA3dShaderGetRegType( src2.base.value );
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   type3 = SVGA3dShaderGetRegType( src2.base.value );
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make life a little easier - this is only used by the TXD
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * instruction which is guaranteed not to have a constant/input reg
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in one slot at least:
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type1 == SVGA3DREG_SAMPLER);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type0 == SVGA3DREG_CONST &&
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp0 = TRUE;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type3 == SVGA3DREG_CONST &&
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp3 = TRUE;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type0 == SVGA3DREG_INPUT &&
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp0 = TRUE;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type3 == SVGA3DREG_INPUT &&
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_temp3 = TRUE;
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp0) {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp0 = get_temp( emit );
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_repl( emit, temp0, &src0 ))
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp3) {
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp3 = get_temp( emit );
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_repl( emit, temp3, &src3 ))
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp3)
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, temp3 );
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_temp0)
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, temp0 );
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean alias_src_dst( struct src_register src,
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              SVGA3dShaderDestToken dst )
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (src.base.num != dst.num)
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(dst.value) !=
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       SVGA3dShaderGetRegType(src.base.value))
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean submit_lrp(struct svga_shader_emitter *emit,
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          SVGA3dShaderDestToken dst,
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct src_register src0,
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct src_register src1,
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct src_register src2)
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken tmp;
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_dst_tmp = FALSE;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The dst reg must be a temporary, and not be the same as src0 or src2 */
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       alias_src_dst(src0, dst) ||
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       alias_src_dst(src2, dst))
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_dst_tmp = TRUE;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_dst_tmp) {
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp = get_temp( emit );
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp.mask = dst.mask;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp = dst;
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op3(emit, inst_token( SVGA3DOP_LRP ), tmp, src0, src1, src2))
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_dst_tmp) {
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_def_const( struct svga_shader_emitter *emit,
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               SVGA3dShaderConstType type,
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               unsigned idx,
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float a,
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float b,
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float c,
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float d )
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3DOpDefArgs def;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken opcode;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type) {
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case SVGA3D_CONST_TYPE_FLOAT:
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = inst_token( SVGA3DOP_DEF );
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.dst = dst_register( SVGA3DREG_CONST, idx );
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constValues[0] = a;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constValues[1] = b;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constValues[2] = c;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constValues[3] = d;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case SVGA3D_CONST_TYPE_INT:
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = inst_token( SVGA3DOP_DEFI );
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.dst = dst_register( SVGA3DREG_CONSTINT, idx );
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constIValues[0] = (int)a;
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constIValues[1] = (int)b;
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constIValues[2] = (int)c;
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      def.constIValues[3] = (int)d;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = inst_token( SVGA3DOP_NOP );
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_instruction(emit, opcode) ||
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       !svga_shader_emit_dwords( emit, def.values, Elements(def.values)))
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_zero_immediate( struct svga_shader_emitter *emit )
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned idx = emit->nr_hw_float_const++;
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit the constant (0, 0.5, -1, 1) and use swizzling to generate
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * other useful vectors.
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        idx, 0, 0.5, -1, 1 ))
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->zero_immediate_idx = idx;
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->created_zero_immediate = TRUE;
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_loop_const( struct svga_shader_emitter *emit )
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned idx = emit->nr_hw_int_const++;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_INT, idx,
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        255, /* iteration count */
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        0, /* initial value */
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        1, /* step size */
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        0 /* not used, must be 0 */))
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->loop_const_idx = idx;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->created_loop_const = TRUE;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_arl_consts( struct svga_shader_emitter *emit )
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->num_arl_consts; i += 4) {
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int j;
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned idx = emit->nr_hw_float_const++;
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      float vals[4];
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < 4 && (j + i) < emit->num_arl_consts; ++j) {
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         vals[j] = emit->arl_consts[i + j].number;
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit->arl_consts[i + j].idx = idx;
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (j) {
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 0:
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_X;
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 1:
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Y;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 2:
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Z;
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 3:
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_W;
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while (j < 4)
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         vals[j++] = 0;
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           vals[0], vals[1],
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           vals[2], vals[3]))
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_vface( struct svga_shader_emitter *emit )
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->emitted_vface);
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src_register(SVGA3DREG_MISCTYPE, SVGA3DMISCREG_FACE);
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* returns {0, 0, 0, 1} immediate */
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_zero_immediate( struct svga_shader_emitter *emit )
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->created_zero_immediate);
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->zero_immediate_idx >= 0);
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swizzle(src_register( SVGA3DREG_CONST,
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                emit->zero_immediate_idx),
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  0, 0, 0, 3);
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* returns {1, 1, 1, -1} immediate */
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_pos_neg_one_immediate( struct svga_shader_emitter *emit )
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->created_zero_immediate);
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->zero_immediate_idx >= 0);
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swizzle(src_register( SVGA3DREG_CONST,
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                emit->zero_immediate_idx),
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  3, 3, 3, 2);
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* returns {0.5, 0.5, 0.5, 0.5} immediate */
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_half_immediate( struct svga_shader_emitter *emit )
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->created_zero_immediate);
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->zero_immediate_idx >= 0);
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swizzle(src_register(SVGA3DREG_CONST, emit->zero_immediate_idx),
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  1, 1, 1, 1);
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* returns the loop const */
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_loop_const( struct svga_shader_emitter *emit )
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->created_loop_const);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->loop_const_idx >= 0);
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src_register( SVGA3DREG_CONSTINT,
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        emit->loop_const_idx );
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_fake_arl_const( struct svga_shader_emitter *emit )
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register reg;
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int idx = 0, swizzle = 0, i;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->num_arl_consts; ++ i) {
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->arl_consts[i].arl_num == emit->current_arl) {
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         idx = emit->arl_consts[i].idx;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swizzle = emit->arl_consts[i].swizzle;
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg = src_register( SVGA3DREG_CONST, idx );
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return scalar(reg, swizzle);
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct src_register
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_tex_dimensions( struct svga_shader_emitter *emit, int sampler_num )
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int idx;
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register reg;
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* the width/height indexes start right after constants */
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   idx = emit->key.fkey.tex[sampler_num].width_height_idx +
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reg = src_register( SVGA3DREG_CONST, idx );
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return reg;
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_fake_arl(struct svga_shader_emitter *emit,
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const struct tgsi_full_instruction *insn)
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 = get_fake_arl_const( emit );
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken tmp = get_temp( emit );
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), tmp, src( tmp ),
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src1))
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* replicate the original swizzle */
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src1 = src(tmp);
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src1.base.swizzle = src0.base.swizzle;
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op1( emit, inst_token( SVGA3DOP_MOVA ),
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dst, src1 );
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_if(struct svga_shader_emitter *emit,
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct tgsi_full_instruction *insn)
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register zero = get_zero_immediate( emit );
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if_token.control = SVGA3DOPCOMPC_NE;
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = scalar(zero, TGSI_SWIZZLE_X);
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(src0.base.value) == SVGA3DREG_CONST) {
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Max different constant registers readable per IFC instruction is 1.
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp = get_temp( emit );
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0 = scalar(src( tmp ), TGSI_SWIZZLE_X);
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->dynamic_branching_level++;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit_instruction( emit, if_token ) &&
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_src( emit, src0 ) &&
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_src( emit, zero ) );
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_endif(struct svga_shader_emitter *emit,
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct tgsi_full_instruction *insn)
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->dynamic_branching_level--;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_instruction(emit, inst_token(SVGA3DOP_ENDIF));
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_else(struct svga_shader_emitter *emit,
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn)
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_instruction(emit, inst_token(SVGA3DOP_ELSE));
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI FLR instruction.
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    FLR  DST, SRC
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    FRC  TMP, SRC
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    SUB  DST, SRC, TMP
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_floor(struct svga_shader_emitter *emit,
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const struct tgsi_full_instruction *insn )
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FRC  TMP, SRC */
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ), temp, src0 ))
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* SUB  DST, SRC, TMP */
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src0,
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    negate( src( temp ) ) ))
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI CEIL instruction.
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    CEIL  DST, SRC
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    FRC  TMP, -SRC
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    ADD  DST, SRC, TMP
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ceil(struct svga_shader_emitter *emit,
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn)
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(emit, &insn->Src[0]);
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp(emit);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FRC  TMP, -SRC */
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), temp, negate(src0)))
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* ADD DST, SRC, TMP */
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), dst, src0, src(temp)))
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI DIV instruction.
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    DIV  DST.xy, SRC0, SRC1
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    RCP  TMP.x, SRC1.xxxx
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    RCP  TMP.y, SRC1.yyyy
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    MUL  DST.xy, SRC0, TMP
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_div(struct svga_shader_emitter *emit,
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src1 = translate_src_register(
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* For each enabled element, perform a RCP instruction.  Note that
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * RCP is scalar in SVGA3D:
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned channel = 1 << i;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & channel) {
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* RCP  TMP.?, SRC1.???? */
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask(temp, channel),
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          scalar(src1, i) ))
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Vector mul:
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * MUL  DST, SRC0, TMP
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst, src0,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src( temp ) ))
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI DP2 instruction.
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    DP2  DST, SRC1, SRC2
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    MUL  TMP, SRC1, SRC2
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    ADD  DST, TMP.xxxx, TMP.yyyy
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_dp2(struct svga_shader_emitter *emit,
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src1 = translate_src_register(
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register temp_src0, temp_src1;
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MUL  TMP, SRC1, SRC2 */
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), temp, src0, src1 ))
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp_src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp_src1 = scalar(src( temp ), TGSI_SWIZZLE_Y);
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* ADD  DST, TMP.xxxx, TMP.yyyy */
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    temp_src0, temp_src1 ))
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI DPH instruction.
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    DPH  DST, SRC1, SRC2
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    DP3  TMP, SRC1, SRC2
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    ADD  DST, TMP, SRC2.wwww
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_dph(struct svga_shader_emitter *emit,
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 = translate_src_register(
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* DP3  TMP, SRC1, SRC2 */
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src1 ))
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src1 = scalar(src1, TGSI_SWIZZLE_W);
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* ADD  DST, TMP, SRC2.wwww */
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src( temp ), src1 ))
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate the following TGSI DST instruction.
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    NRM  DST, SRC
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * To the following SVGA3D instruction sequence.
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    DP3  TMP, SRC, SRC
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    RSQ  TMP, TMP
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    MUL  DST, SRC, TMP
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_nrm(struct svga_shader_emitter *emit,
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* DP3  TMP, SRC, SRC */
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src0 ))
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* RSQ  TMP, TMP */
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_RSQ ), temp, src( temp )))
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MUL  DST, SRC, TMP */
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst,
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src0, src( temp )))
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean do_emit_sincos(struct svga_shader_emitter *emit,
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              SVGA3dShaderDestToken dst,
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              struct src_register src0)
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = scalar(src0, TGSI_SWIZZLE_X);
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op1(emit, inst_token(SVGA3DOP_SINCOS), dst, src0);
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_sincos(struct svga_shader_emitter *emit,
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const struct tgsi_full_instruction *insn)
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* SCS TMP SRC */
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_XY), src0 ))
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV DST TMP */
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src( temp ) ))
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SCS TMP SRC
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV DST TMP.yyyy
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_sin(struct svga_shader_emitter *emit,
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* SCS TMP SRC */
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_Y), src0))
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = scalar(src( temp ), TGSI_SWIZZLE_Y);
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV DST TMP.yyyy */
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SCS TMP SRC
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV DST TMP.xxxx
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_cos(struct svga_shader_emitter *emit,
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp = get_temp( emit );
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* SCS TMP SRC */
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!do_emit_sincos( emit, writemask(temp, TGSI_WRITEMASK_X), src0 ))
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV DST TMP.xxxx */
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ssg(struct svga_shader_emitter *emit,
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp0 = get_temp( emit );
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp1 = get_temp( emit );
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register zero, one;
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* SGN  DST, SRC0, TMP0, TMP1 */
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op3( emit, inst_token( SVGA3DOP_SGN ), dst, src0,
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         src( temp0 ), src( temp1 ) );
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = get_zero_immediate( emit );
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   one = scalar( zero, TGSI_SWIZZLE_W );
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = scalar( zero, TGSI_SWIZZLE_X );
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* CMP  TMP0, SRC0, one, zero */
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    writemask( temp0, dst.mask ), src0, one, zero ))
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* CMP  TMP1, negate(SRC0), negate(one), zero */
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    writemask( temp1, dst.mask ), negate( src0 ), negate( one ),
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    zero ))
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* ADD  DST, TMP0, TMP1 */
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src( temp0 ),
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      src( temp1 ) );
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ADD DST SRC0, negate(SRC0)
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_sub(struct svga_shader_emitter *emit,
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 = translate_src_register(
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src1 = negate(src1);
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src0, src1 ))
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_kil(struct svga_shader_emitter *emit,
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct tgsi_full_src_register *reg = &insn->Src[0];
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0, srcIn;
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* is the W component tested in another position? */
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const boolean w_tested = (reg->Register.SwizzleW == reg->Register.SwizzleX ||
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             reg->Register.SwizzleW == reg->Register.SwizzleY ||
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             reg->Register.SwizzleW == reg->Register.SwizzleZ);
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const boolean special = (reg->Register.Absolute ||
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.Negate ||
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.Indirect ||
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.SwizzleX != 0 ||
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.SwizzleY != 1 ||
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.SwizzleZ != 2 ||
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            reg->Register.File != TGSI_FILE_TEMPORARY);
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp;
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = srcIn = translate_src_register( emit, reg );
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (special || !w_tested) {
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* need a temp reg */
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp = get_temp( emit );
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (special) {
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* move the source into a temp register */
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      submit_op1( emit, inst_token( SVGA3DOP_MOV ),
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  writemask( temp, TGSI_WRITEMASK_XYZ ),
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  src0 );
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0 = src( temp );
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do the texkill (on the xyz components) */
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), dst(src0) ))
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!w_tested) {
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* need to emit a second texkill to test the W component */
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* put src.wwww into temp register */
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token( SVGA3DOP_MOV ),
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      writemask( temp, TGSI_WRITEMASK_XYZ ),
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      scalar(srcIn, TGSI_SWIZZLE_W)))
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* second texkill */
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), temp ))
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* mesa state tracker always emits kilp as an unconditional
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * kil */
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_kilp(struct svga_shader_emitter *emit,
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp;
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register one = scalar( get_zero_immediate( emit ),
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     TGSI_SWIZZLE_W );
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = inst_token( SVGA3DOP_TEXKILL );
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* texkill doesn't allow negation on the operand so lets move
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * negation of {1} to a temp register */
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp = get_temp( emit );
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp,
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    negate( one ) ))
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op0( emit, inst, temp );
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Test if r1 and r2 are the same register.
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsame_register(struct src_register r1, struct src_register r2)
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (r1.base.num == r2.base.num &&
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           r1.base.type_upper == r2.base.type_upper &&
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           r1.base.type_lower == r2.base.type_lower);
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Implement conditionals by initializing destination reg to 'fail',
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * then set predicate reg with UFOP_SETP, then move 'pass' to dest
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * based on predicate reg.
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SETP src0, cmp, src1  -- do this first to avoid aliasing problems.
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV dst, fail
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV dst, pass, p0
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_conditional(struct svga_shader_emitter *emit,
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 unsigned compare_func,
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 SVGA3dShaderDestToken dst,
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct src_register src0,
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct src_register src1,
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct src_register pass,
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct src_register fail)
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken setp_token, mov_token;
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   setp_token = inst_token( SVGA3DOP_SETP );
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (compare_func) {
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_NEVER:
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         dst, fail );
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_LESS:
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMP_LT;
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_EQUAL:
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMP_EQ;
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_LEQUAL:
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMP_LE;
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_GREATER:
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMP_GT;
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_NOTEQUAL:
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMPC_NE;
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_GEQUAL:
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setp_token.control = SVGA3DOPCOMP_GE;
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FUNC_ALWAYS:
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         dst, pass );
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (same_register(src(dst), pass)) {
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* We'll get bad results if the dst and pass registers are the same
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * so use a temp register containing pass.
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken temp = get_temp(emit);
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass))
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pass = src(temp);
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* SETP src0, COMPOP, src1 */
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, setp_token, pred_reg,
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src0, src1 ))
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mov_token = inst_token( SVGA3DOP_MOV );
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV dst, fail */
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op1( emit, mov_token, dst,
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    fail ))
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV dst, pass (predicated)
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note that the predicate reg (and possible modifiers) is passed
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * as the first source argument.
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mov_token.predicated = 1;
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!submit_op2( emit, mov_token, dst,
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src( pred_reg ), pass ))
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_select(struct svga_shader_emitter *emit,
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned compare_func,
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            SVGA3dShaderDestToken dst,
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct src_register src0,
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct src_register src1 )
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* There are some SVGA instructions which implement some selects
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * directly, but they are only available in the vertex shader.
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (compare_func) {
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_FUNC_GEQUAL:
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src0, src1 );
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_FUNC_LEQUAL:
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src1, src0 );
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_FUNC_GREATER:
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src1, src0 );
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_FUNC_LESS:
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src0, src1 );
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Otherwise, need to use the setp approach:
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register one, zero;
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* zero immediate is 0,0,0,1 */
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      zero = get_zero_immediate( emit );
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      one  = scalar( zero, TGSI_SWIZZLE_W );
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      zero = scalar( zero, TGSI_SWIZZLE_X );
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_conditional(
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit,
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         compare_func,
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst,
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src0,
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src1,
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         one, zero);
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_select_op(struct svga_shader_emitter *emit,
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              unsigned compare,
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const struct tgsi_full_instruction *insn)
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 = translate_src_register(
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_select( emit, compare, dst, src0, src1 );
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate TGSI CMP instruction.
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_cmp(struct svga_shader_emitter *emit,
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const struct tgsi_full_instruction *insn)
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 =
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register(emit, &insn->Src[0] );
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src1 =
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register(emit, &insn->Src[1] );
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src2 =
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register(emit, &insn->Src[2] );
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero =
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X);
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* We used to simulate CMP with SLT+LRP.  But that didn't work when
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * src1 or src2 was Inf/NaN.  In particular, GLSL sqrt(0) failed
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * because it involves a CMP to handle the 0 case.
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Use a conditional expression instead.
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_conditional(emit, PIPE_FUNC_LESS, dst,
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              src0, zero, src1, src2);
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(emit->unit == PIPE_SHADER_FRAGMENT);
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* CMP  DST, SRC0, SRC2, SRC1 */
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst,
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         src0, src2, src1);
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate texture instructions to SVGA3D representation.
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_tex2(struct svga_shader_emitter *emit,
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn,
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         SVGA3dShaderDestToken dst )
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register texcoord;
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register sampler;
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken tmp;
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst.value = 0;
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (insn->Instruction.Opcode) {
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TEX:
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEX;
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXP:
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEX;
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.control = SVGA3DOPCONT_PROJECT;
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXB:
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEX;
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.control = SVGA3DOPCONT_BIAS;
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXL:
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEXLDL;
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   texcoord = translate_src_register( emit, &insn->Src[0] );
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler = translate_src_register( emit, &insn->Src[1] );
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->dynamic_branching_level > 0)
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp = get_temp( emit );
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Can't do mipmapping inside dynamic branch constructs.  Force LOD
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * zero in that case.
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->dynamic_branching_level > 0 &&
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst.op == SVGA3DOP_TEX &&
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero = get_zero_immediate( emit );
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOV  tmp, texcoord */
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token( SVGA3DOP_MOV ),
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       tmp,
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       texcoord ))
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOV  tmp.w, zero */
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token( SVGA3DOP_MOV ),
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( tmp, TGSI_WRITEMASK_W ),
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( zero, TGSI_SWIZZLE_X )))
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texcoord = src( tmp );
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEXLDL;
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Explicit normalization of texcoords:
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MUL  tmp, SRC0, WH */
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       tmp, texcoord, wh ))
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texcoord = src( tmp );
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op2( emit, inst, dst, texcoord, sampler );
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate texture instructions to SVGA3D representation.
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_tex4(struct svga_shader_emitter *emit,
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn,
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         SVGA3dShaderDestToken dst )
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register texcoord;
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register ddx;
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register ddy;
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register sampler;
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   texcoord = translate_src_register( emit, &insn->Src[0] );
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ddx      = translate_src_register( emit, &insn->Src[1] );
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ddy      = translate_src_register( emit, &insn->Src[2] );
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler  = translate_src_register( emit, &insn->Src[3] );
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst.value = 0;
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (insn->Instruction.Opcode) {
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXD:
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit texture swizzle code.
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_tex_swizzle( struct svga_shader_emitter *emit,
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 SVGA3dShaderDestToken dst,
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 struct src_register src,
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned swizzle_x,
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned swizzle_y,
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned swizzle_z,
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned swizzle_w)
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned swizzleIn[4] = {swizzle_x, swizzle_y, swizzle_z, swizzle_w};
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned srcSwizzle[4];
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned srcWritemask = 0x0, zeroWritemask = 0x0, oneWritemask = 0x0;
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* build writemasks and srcSwizzle terms */
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (swizzleIn[i] == PIPE_SWIZZLE_ZERO) {
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         zeroWritemask |= (1 << i);
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (swizzleIn[i] == PIPE_SWIZZLE_ONE) {
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         oneWritemask |= (1 << i);
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcSwizzle[i] = swizzleIn[i];
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         srcWritemask |= (1 << i);
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* write x/y/z/w comps */
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & srcWritemask) {
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token(SVGA3DOP_MOV),
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      writemask(dst, srcWritemask),
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      swizzle(src,
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              srcSwizzle[0],
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              srcSwizzle[1],
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              srcSwizzle[2],
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              srcSwizzle[3])))
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* write 0 comps */
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & zeroWritemask) {
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token(SVGA3DOP_MOV),
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      writemask(dst, zeroWritemask),
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X)))
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* write 1 comps */
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & oneWritemask) {
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token(SVGA3DOP_MOV),
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      writemask(dst, oneWritemask),
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_W)))
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_tex(struct svga_shader_emitter *emit,
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn )
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst =
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_dst_register( emit, insn, 0 );
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 =
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register( emit, &insn->Src[0] );
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 =
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register( emit, &insn->Src[1] );
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken tex_result;
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned unit = src1.base.num;
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* check for shadow samplers */
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean compare = (emit->key.fkey.tex[unit].compare_mode ==
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      PIPE_TEX_COMPARE_R_TO_TEXTURE);
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* texture swizzle */
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean swizzle = (emit->key.fkey.tex[unit].swizzle_r != PIPE_SWIZZLE_RED ||
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      emit->key.fkey.tex[unit].swizzle_g != PIPE_SWIZZLE_GREEN ||
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      emit->key.fkey.tex[unit].swizzle_b != PIPE_SWIZZLE_BLUE ||
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      emit->key.fkey.tex[unit].swizzle_a != PIPE_SWIZZLE_ALPHA);
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean saturate = insn->Instruction.Saturate != TGSI_SAT_NONE;
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If doing compare processing or tex swizzle or saturation, we need to put
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the fetched color into a temporary so it can be used as a source later on.
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (compare || swizzle || saturate) {
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tex_result = get_temp( emit );
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tex_result = dst;
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(insn->Instruction.Opcode) {
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TEX:
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXB:
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXP:
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXL:
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_tex2( emit, insn, tex_result ))
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXD:
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_tex4( emit, insn, tex_result ))
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (compare) {
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken dst2;
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (swizzle || saturate)
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst2 = tex_result;
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst2 = dst;
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_XYZ) {
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* When sampling a depth texture, the result of the comparison is in
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the Y component.
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct src_register r_coord;
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (insn->Instruction.Opcode == TGSI_OPCODE_TXP) {
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Divide texcoord R by Q */
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             scalar(src0, TGSI_SWIZZLE_W) ))
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return FALSE;
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             scalar(src0, TGSI_SWIZZLE_Z),
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return FALSE;
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            r_coord = scalar(src(src0_zdivw), TGSI_SWIZZLE_X);
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            r_coord = scalar(src0, TGSI_SWIZZLE_Z);
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Compare texture sample value against R component of texcoord */
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!emit_select(emit,
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          emit->key.fkey.tex[unit].compare_func,
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask( dst2, TGSI_WRITEMASK_XYZ ),
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          r_coord,
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          tex_src_x))
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_W) {
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct src_register one =
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         writemask( dst2, TGSI_WRITEMASK_W ),
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         one ))
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           return FALSE;
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (saturate && !swizzle) {
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOV_SAT real_dst, dst */
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src(tex_result) ))
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (swizzle) {
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* swizzle from tex_result to dst (handles saturation too, if any) */
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_tex_swizzle(emit,
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       dst, src(tex_result),
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->key.fkey.tex[unit].swizzle_r,
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->key.fkey.tex[unit].swizzle_g,
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->key.fkey.tex[unit].swizzle_b,
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->key.fkey.tex[unit].swizzle_a);
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_bgnloop2( struct svga_shader_emitter *emit,
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const struct tgsi_full_instruction *insn )
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_LOOP );
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register const_int = get_loop_const( emit );
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->dynamic_branching_level++;
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit_instruction( emit, inst ) &&
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_src( emit, loop_reg ) &&
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_src( emit, const_int ) );
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_endloop2( struct svga_shader_emitter *emit,
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const struct tgsi_full_instruction *insn )
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->dynamic_branching_level--;
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_instruction( emit, inst );
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_brk( struct svga_shader_emitter *emit,
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn )
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_BREAK );
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_instruction( emit, inst );
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_scalar_op1( struct svga_shader_emitter *emit,
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                unsigned opcode,
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct tgsi_full_instruction *insn )
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst;
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src;
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = inst_token( opcode );
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst = translate_dst_register( emit, insn, 0 );
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = translate_src_register( emit, &insn->Src[0] );
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = scalar( src, TGSI_SWIZZLE_X );
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op1( emit, inst, dst, src );
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_simple_instruction(struct svga_shader_emitter *emit,
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       unsigned opcode,
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct tgsi_full_instruction *insn )
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct tgsi_full_src_register *src = insn->Src;
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst;
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = inst_token( opcode );
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst = translate_dst_register( emit, insn, 0 );
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (insn->Instruction.NumSrcRegs) {
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 0:
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op0( emit, inst, dst );
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 1:
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1( emit, inst, dst,
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[0] ));
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 2:
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op2( emit, inst, dst,
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[0] ),
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[1] ) );
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case 3:
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op3( emit, inst, dst,
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[0] ),
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[1] ),
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         translate_src_register( emit, &src[2] ) );
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_deriv(struct svga_shader_emitter *emit,
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const struct tgsi_full_instruction *insn )
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->dynamic_branching_level > 0 &&
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       insn->Src[0].Register.File == TGSI_FILE_TEMPORARY)
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero = get_zero_immediate( emit );
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken dst =
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         translate_dst_register( emit, insn, 0 );
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Deriv opcodes not valid inside dynamic branching, workaround
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * by zeroing out the destination.
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token( SVGA3DOP_MOV ),
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dst,
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      scalar(zero, TGSI_SWIZZLE_X)))
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned opcode;
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct tgsi_full_src_register *reg = &insn->Src[0];
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderInstToken inst;
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken dst;
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register src0;
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (insn->Instruction.Opcode) {
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_DDX:
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         opcode = SVGA3DOP_DSX;
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_DDY:
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         opcode = SVGA3DOP_DSY;
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = inst_token( opcode );
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst = translate_dst_register( emit, insn, 0 );
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0 = translate_src_register( emit, reg );
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* We cannot use negate or abs on source to dsx/dsy instruction.
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Absolute ||
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          reg->Register.Negate) {
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         SVGA3dShaderDestToken temp = get_temp( emit );
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!emit_repl( emit, temp, &src0 ))
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1( emit, inst, dst, src0 );
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_arl(struct svga_shader_emitter *emit,
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ++emit->current_arl;
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_FRAGMENT) {
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOVA not present in pixel shader instruction set.
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Ignore this instruction altogether since it is
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * only used for loop counters -- and for that
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * we reference aL directly.
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (svga_arl_needs_adjustment( emit )) {
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_fake_arl( emit, insn );
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* no need to adjust, just emit straight arl */
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_simple_instruction(emit, SVGA3DOP_MOVA, insn);
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_pow(struct svga_shader_emitter *emit,
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 = translate_src_register(
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src1 = translate_src_register(
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_tmp = FALSE;
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* POW can only output to a temporary */
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_tmp = TRUE;
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* POW src1 must not be the same register as dst */
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (alias_src_dst( src1, dst ))
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_tmp = TRUE;
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* it's a scalar op */
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = scalar( src0, TGSI_SWIZZLE_X );
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src1 = scalar( src1, TGSI_SWIZZLE_X );
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_tmp) {
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp = writemask(get_temp( emit ), TGSI_WRITEMASK_X );
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token( SVGA3DOP_POW ), tmp, src0, src1))
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, scalar(src(tmp), 0) );
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op2(emit, inst_token( SVGA3DOP_POW ), dst, src0, src1);
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_xpd(struct svga_shader_emitter *emit,
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src1 = translate_src_register(
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean need_dst_tmp = FALSE;
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XPD can only output to a temporary */
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP)
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_dst_tmp = TRUE;
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The dst reg must not be the same as src0 or src1*/
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (alias_src_dst(src0, dst) ||
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       alias_src_dst(src1, dst))
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      need_dst_tmp = TRUE;
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (need_dst_tmp) {
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp = get_temp( emit );
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Obey DX9 restrictions on mask:
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp.mask = dst.mask & TGSI_WRITEMASK_XYZ;
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), tmp, src0, src1))
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), dst, src0, src1))
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Need to emit 1.0 to dst.w?
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_W) {
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero = get_zero_immediate( emit );
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit,
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token( SVGA3DOP_MOV ),
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      writemask(dst, TGSI_WRITEMASK_W),
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      zero))
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_lrp(struct svga_shader_emitter *emit,
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 = translate_src_register(
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[0] );
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src1 = translate_src_register(
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[1] );
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src2 = translate_src_register(
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit, &insn->Src[2] );
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_lrp(emit, dst, src0, src1, src2);
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_dst_insn(struct svga_shader_emitter *emit,
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const struct tgsi_full_instruction *insn )
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* SVGA/DX9 has a DST instruction, but only for vertex shaders:
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_simple_instruction(emit, SVGA3DOP_DST, insn);
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* result[0] = 1    * 1;
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * result[1] = a[1] * b[1];
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * result[2] = a[2] * 1;
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * result[3] = 1    * b[3];
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp;
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct src_register src0 = translate_src_register(
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit, &insn->Src[0] );
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct src_register src1 = translate_src_register(
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit, &insn->Src[1] );
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero = get_zero_immediate( emit );
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      boolean need_tmp = FALSE;
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          alias_src_dst(src0, dst) ||
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          alias_src_dst(src1, dst))
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_tmp = TRUE;
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (need_tmp) {
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tmp = get_temp( emit );
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tmp = dst;
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* tmp.xw = 1.0
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tmp.mask & TGSI_WRITEMASK_XW) {
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask(tmp, TGSI_WRITEMASK_XW ),
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          scalar( zero, 3 )))
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* tmp.yz = src0
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tmp.mask & TGSI_WRITEMASK_YZ) {
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask(tmp, TGSI_WRITEMASK_YZ ),
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src0))
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* tmp.yw = tmp * src1
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tmp.mask & TGSI_WRITEMASK_YW) {
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask(tmp, TGSI_WRITEMASK_YW ),
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src(tmp),
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src1))
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* dst = tmp
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (need_tmp) {
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          dst,
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src(tmp)))
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_exp(struct svga_shader_emitter *emit,
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 =
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register( emit, &insn->Src[0] );
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register zero = get_zero_immediate( emit );
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken fraction;
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_Y)
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fraction = dst;
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (dst.mask & TGSI_WRITEMASK_X)
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fraction = get_temp( emit );
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fraction.value = 0;
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If y is being written, fill it with src0 - floor(src0).
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_XY) {
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( fraction, TGSI_WRITEMASK_Y ),
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src0 ))
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If x is being written, fill it with 2 ^ floor(src0).
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_X) {
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( dst, TGSI_WRITEMASK_X ),
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src0,
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( dst, TGSI_WRITEMASK_X ),
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(dst.mask & TGSI_WRITEMASK_Y))
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         release_temp( emit, fraction );
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If z is being written, fill it with 2 ^ src0 (partial precision).
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_Z) {
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( dst, TGSI_WRITEMASK_Z ),
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src0 ) )
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If w is being written, fill it with one.
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_W) {
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(dst, TGSI_WRITEMASK_W),
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( zero, TGSI_SWIZZLE_W ) ))
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_lit(struct svga_shader_emitter *emit,
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const struct tgsi_full_instruction *insn )
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* SVGA/DX9 has a LIT instruction, but only for vertex shaders:
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_simple_instruction(emit, SVGA3DOP_LIT, insn);
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* D3D vs. GL semantics can be fairly easily accomodated by
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * variations on this sequence.
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * GL:
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   tmp.y = src.x
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   tmp.z = pow(src.y,src.w)
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   p0 = src0.xxxx > 0
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   result = zero.wxxw
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   (p0) result.yz = tmp
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * D3D:
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   tmp.y = src.x
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   tmp.z = pow(src.y,src.w)
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   p0 = src0.xxyy > 0
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   result = zero.wxxw
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   (p0) result.yz = tmp
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Will implement the GL version for now.
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp = get_temp( emit );
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct src_register src0 = translate_src_register(
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit, &insn->Src[0] );
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register zero = get_zero_immediate( emit );
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* tmp = pow(src.y, src.w)
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_Z) {
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op2(emit, inst_token( SVGA3DOP_POW ),
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         tmp,
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         scalar(src0, 1),
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         scalar(src0, 3)))
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* tmp.y = src.x
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_Y) {
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask(tmp, TGSI_WRITEMASK_Y ),
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          scalar(src0, 0)))
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Can't quite do this with emit conditional due to the extra
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * writemask on the predicated mov:
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         SVGA3dShaderInstToken setp_token, mov_token;
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct src_register predsrc;
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         setp_token = inst_token( SVGA3DOP_SETP );
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mov_token = inst_token( SVGA3DOP_MOV );
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         setp_token.control = SVGA3DOPCOMP_GT;
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* D3D vs GL semantics:
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (0)
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            predsrc = swizzle(src0, 0, 0, 1, 1); /* D3D */
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            predsrc = swizzle(src0, 0, 0, 0, 0); /* GL */
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* SETP src0.xxyy, GT, {0}.x */
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op2( emit, setp_token, pred_reg,
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          predsrc,
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          swizzle(zero, 0, 0, 0, 0) ))
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* MOV dst, fail */
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst,
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          swizzle(zero, 3, 0, 0, 3 )))
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             return FALSE;
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* MOV dst.yz, tmp (predicated)
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          *
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Note that the predicate reg (and possible modifiers) is passed
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * as the first source argument.
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dst.mask & TGSI_WRITEMASK_YZ) {
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mov_token.predicated = 1;
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!submit_op2( emit, mov_token,
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             writemask(dst, TGSI_WRITEMASK_YZ),
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             src( pred_reg ), src( tmp ) ))
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return FALSE;
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ex2( struct svga_shader_emitter *emit,
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct tgsi_full_instruction *insn )
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken inst;
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst;
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0;
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = inst_token( SVGA3DOP_EXP );
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst = translate_dst_register( emit, insn, 0 );
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = translate_src_register( emit, &insn->Src[0] );
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = scalar( src0, TGSI_SWIZZLE_X );
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask != TGSI_WRITEMASK_XYZW) {
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken tmp = get_temp( emit );
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst, tmp, src0 ))
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         dst,
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         scalar( src( tmp ), TGSI_SWIZZLE_X ) );
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return submit_op1( emit, inst, dst, src0 );
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_log(struct svga_shader_emitter *emit,
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct tgsi_full_instruction *insn)
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register src0 =
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register( emit, &insn->Src[0] );
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register zero = get_zero_immediate( emit );
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken abs_tmp;
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register abs_src0;
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken log2_abs;
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   abs_tmp.value = 0;
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_Z)
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      log2_abs = dst;
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (dst.mask & TGSI_WRITEMASK_XY)
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      log2_abs = get_temp( emit );
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      log2_abs.value = 0;
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If z is being written, fill it with log2( abs( src0 ) ).
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_XYZ) {
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!src0.base.srcMod || src0.base.srcMod == SVGA3DSRCMOD_ABS)
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         abs_src0 = src0;
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         abs_tmp = get_temp( emit );
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          abs_tmp,
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src0 ) )
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         abs_src0 = src( abs_tmp );
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abs_src0 = absolute( scalar( abs_src0, TGSI_SWIZZLE_X ) );
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_LOG ),
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( log2_abs, TGSI_WRITEMASK_Z ),
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       abs_src0 ) )
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_XY) {
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken floor_log2;
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_X)
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         floor_log2 = dst;
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         floor_log2 = get_temp( emit );
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If x is being written, fill it with floor( log2( abs( src0 ) ) ).
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( floor_log2, TGSI_WRITEMASK_X ),
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ) ) )
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( floor_log2, TGSI_WRITEMASK_X ),
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ),
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       negate( src( floor_log2 ) ) ) )
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If y is being written, fill it with
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * abs ( src0 ) / ( 2 ^ floor( log2( abs( src0 ) ) ) ).
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.mask & TGSI_WRITEMASK_Y) {
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask( dst, TGSI_WRITEMASK_Y ),
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          negate( scalar( src( floor_log2 ),
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          TGSI_SWIZZLE_X ) ) ) )
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          writemask( dst, TGSI_WRITEMASK_Y ),
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          src( dst ),
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          abs_src0 ) )
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(dst.mask & TGSI_WRITEMASK_X))
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         release_temp( emit, floor_log2 );
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(dst.mask & TGSI_WRITEMASK_Z))
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         release_temp( emit, log2_abs );
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_XYZ && src0.base.srcMod &&
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       src0.base.srcMod != SVGA3DSRCMOD_ABS)
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      release_temp( emit, abs_tmp );
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If w is being written, fill it with one.
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.mask & TGSI_WRITEMASK_W) {
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(dst, TGSI_WRITEMASK_W),
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( zero, TGSI_SWIZZLE_W ) ))
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate TGSI TRUNC or ROUND instruction.
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We need to truncate toward zero. Ex: trunc(-1.9) = -1
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Different approaches are needed for VS versus PS.
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_trunc_round(struct svga_shader_emitter *emit,
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct tgsi_full_instruction *insn,
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 boolean round)
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct src_register src0 =
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      translate_src_register(emit, &insn->Src[0] );
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken t1 = get_temp(emit);
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (round) {
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken t0 = get_temp(emit);
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register half = get_half_immediate(emit);
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t0 = abs(src0) + 0.5 */
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t0,
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      absolute(src0), half))
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t1 = fract(t0) */
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, src(t0)))
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t1 = t0 - t1 */
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, src(t0),
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      negate(src(t1))))
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* trunc */
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t1 = fract(abs(src0)) */
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, absolute(src0)))
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t1 = abs(src0) - t1 */
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, absolute(src0),
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      negate(src(t1))))
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Now we need to multiply t1 by the sign of the original value.
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* For VS: use SGN instruction */
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need two extra/dummy registers: */
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken t2 = get_temp(emit), t3 = get_temp(emit),
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t4 = get_temp(emit);
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* t2 = sign(src0) */
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op3(emit, inst_token(SVGA3DOP_SGN), t2, src0,
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      src(t3), src(t4)))
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* dst = t1 * t2 */
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2(emit, inst_token(SVGA3DOP_MUL), dst, src(t1), src(t2)))
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* For FS: Use CMP instruction */
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return submit_op3(emit, inst_token( SVGA3DOP_CMP ), dst,
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        src0, src(t1), negate(src(t1)));
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_bgnsub( struct svga_shader_emitter *emit,
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           unsigned position,
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const struct tgsi_full_instruction *insn )
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note that we've finished the main function and are now emitting
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * subroutines.  This affects how we terminate the generated
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * shader.
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->in_main_func = FALSE;
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->nr_labels; i++) {
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->label[i] == position) {
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return (emit_instruction( emit, inst_token( SVGA3DOP_RET ) ) &&
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 emit_instruction( emit, inst_token( SVGA3DOP_LABEL ) ) &&
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(0);
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_call( struct svga_shader_emitter *emit,
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const struct tgsi_full_instruction *insn )
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned position = insn->Label.Label;
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->nr_labels; i++) {
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->label[i] == position)
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->nr_labels == Elements(emit->label))
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i == emit->nr_labels) {
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit->label[i] = position;
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit->nr_labels++;
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit_instruction( emit, inst_token( SVGA3DOP_CALL ) ) &&
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_end( struct svga_shader_emitter *emit )
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_vs_postamble( emit );
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_ps_postamble( emit );
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean svga_emit_instruction( struct svga_shader_emitter *emit,
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      unsigned position,
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct tgsi_full_instruction *insn )
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (insn->Instruction.Opcode) {
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ARL:
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_arl( emit, insn );
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TEX:
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXB:
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXP:
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXL:
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXD:
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_tex( emit, insn );
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DDX:
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DDY:
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_deriv( emit, insn );
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_BGNSUB:
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_bgnsub( emit, position, insn );
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ENDSUB:
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CAL:
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_call( emit, insn );
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_FLR:
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_floor( emit, insn );
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TRUNC:
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_trunc_round( emit, insn, FALSE );
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ROUND:
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_trunc_round( emit, insn, TRUE );
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CEIL:
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_ceil( emit, insn );
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CMP:
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_cmp( emit, insn );
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DIV:
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_div( emit, insn );
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DP2:
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_dp2( emit, insn );
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DPH:
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_dph( emit, insn );
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_NRM:
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_nrm( emit, insn );
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_COS:
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_cos( emit, insn );
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SIN:
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_sin( emit, insn );
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SCS:
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_sincos( emit, insn );
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_END:
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TGSI always finishes the main func with an END */
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_end( emit );
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_KIL:
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_kil( emit, insn );
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Selection opcodes.  The underlying language is fairly
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * non-orthogonal about these.
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SEQ:
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_EQUAL, insn );
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SNE:
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_NOTEQUAL, insn );
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SGT:
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_GREATER, insn );
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SGE:
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_GEQUAL, insn );
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SLT:
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_LESS, insn );
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SLE:
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_select_op( emit, PIPE_FUNC_LEQUAL, insn );
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SUB:
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_sub( emit, insn );
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_POW:
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_pow( emit, insn );
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_EX2:
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_ex2( emit, insn );
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_EXP:
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_exp( emit, insn );
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_LOG:
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_log( emit, insn );
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_LG2:
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_scalar_op1( emit, SVGA3DOP_LOG, insn );
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_RSQ:
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_scalar_op1( emit, SVGA3DOP_RSQ, insn );
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_RCP:
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_scalar_op1( emit, SVGA3DOP_RCP, insn );
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CONT:
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_RET:
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This is a noop -- we tell mesa that we can't support RET
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * within a function (early return), so this will always be
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * followed by an ENDSUB.
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* These aren't actually used by any of the frontends we care
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * about:
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CLAMP:
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_AND:
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_OR:
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_I2F:
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_NOT:
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SHL:
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ISHR:
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_XOR:
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_IF:
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_if( emit, insn );
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ELSE:
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_else( emit, insn );
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ENDIF:
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_endif( emit, insn );
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_BGNLOOP:
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_bgnloop2( emit, insn );
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ENDLOOP:
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_endloop2( emit, insn );
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_BRK:
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_brk( emit, insn );
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_XPD:
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_xpd( emit, insn );
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_KILP:
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_kilp( emit, insn );
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_DST:
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_dst_insn( emit, insn );
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_LIT:
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_lit( emit, insn );
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_LRP:
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_lrp( emit, insn );
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SSG:
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return emit_ssg( emit, insn );
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default: {
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned opcode = translate_opcode(insn->Instruction.Opcode);
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (opcode == SVGA3DOP_LAST_INST)
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_simple_instruction( emit, opcode, insn ))
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean svga_emit_immediate( struct svga_shader_emitter *emit,
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    struct tgsi_full_immediate *imm)
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const float id[4] = {0,0,0,1};
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float value[4];
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(1 <= imm->Immediate.NrTokens && imm->Immediate.NrTokens <= 5);
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < imm->Immediate.NrTokens - 1; i++)
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      value[i] = imm->u[i].Float;
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for ( ; i < 4; i++ )
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      value[i] = id[i];
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          emit->imm_start + emit->internal_imm_count++,
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          value[0], value[1], value[2], value[3]);
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean make_immediate( struct svga_shader_emitter *emit,
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float a,
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float b,
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float c,
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               float d,
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               struct src_register *out )
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned idx = emit->nr_hw_float_const++;
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        idx, a, b, c, d ))
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *out = src_register( SVGA3DREG_CONST, idx );
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_vs_preamble( struct svga_shader_emitter *emit )
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit->key.vkey.need_prescale) {
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!make_immediate( emit, 0, 0, .5, .5,
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           &emit->imm_0055))
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ps_preamble( struct svga_shader_emitter *emit )
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->ps_reads_pos && emit->info.reads_z) {
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Assemble the position from various bits of inputs. Depth and W are
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * passed in a texcoord this is due to D3D's vPos not hold Z or W.
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Also fixup the perspective interpolation.
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temp_pos.xy = vPos.xy
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temp_pos.w = rcp(texcoord1.w);
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temp_pos.z = texcoord1.z * temp_pos.w;
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_XY ),
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->ps_true_pos ))
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_RCP),
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_W ),
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_W ) ))
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit,
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MUL),
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_Z ),
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_Z ),
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar( src(emit->ps_temp_pos), TGSI_SWIZZLE_W ) ))
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_ps_postamble( struct svga_shader_emitter *emit )
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* PS oDepth is incredibly fragile and it's very hard to catch the
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * types of usage that break it during shader emit.  Easier just to
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * redirect the main program to a temporary and then only touch
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * oDepth with a hand-crafted MOV below.
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(emit->true_pos.value) != 0) {
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->true_pos,
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar(src(emit->temp_pos), TGSI_SWIZZLE_Z) ))
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Potentially override output colors with white for XOR
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * logicop workaround.
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (emit->unit == PIPE_SHADER_FRAGMENT &&
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             emit->key.fkey.white_fragments) {
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct src_register one = scalar( get_zero_immediate( emit ),
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              TGSI_SWIZZLE_W );
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!submit_op1( emit,
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             inst_token(SVGA3DOP_MOV),
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             emit->true_col[i],
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             one ))
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return FALSE;
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!submit_op1( emit,
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             inst_token(SVGA3DOP_MOV),
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             emit->true_col[i],
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             src(emit->temp_col[i]) ))
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return FALSE;
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_vs_postamble( struct svga_shader_emitter *emit )
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* PSIZ output is incredibly fragile and it's very hard to catch
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the types of usage that break it during shader emit.  Easier
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * just to redirect the main program to a temporary and then only
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * touch PSIZ with a hand-crafted MOV below.
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (SVGA3dShaderGetRegType(emit->true_psiz.value) != 0) {
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       emit->true_psiz,
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar(src(emit->temp_psiz), TGSI_SWIZZLE_X) ))
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Need to perform various manipulations on vertex position to cope
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * with the different GL and D3D clip spaces.
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->key.vkey.need_prescale) {
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken depth = emit->depth_pos;
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken pos = emit->true_pos;
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned offset = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register prescale_scale = src_register( SVGA3DREG_CONST,
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         offset + 0 );
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register prescale_trans = src_register( SVGA3DREG_CONST,
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         offset + 1 );
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(depth, TGSI_WRITEMASK_W),
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scalar(src(temp_pos), TGSI_SWIZZLE_W) ))
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MUL temp_pos.xyz,    temp_pos,      prescale.scale
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * MAD result.position, temp_pos.wwww, prescale.trans, temp_pos
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   --> Note that prescale.trans.w == 0
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit,
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MUL),
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(temp_pos, TGSI_WRITEMASK_XYZ),
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos),
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       prescale_scale ))
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op3( emit,
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MAD),
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       pos,
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       swizzle(src(temp_pos), 3, 3, 3, 3),
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       prescale_trans,
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos)))
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Also write to depth value */
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op3( emit,
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MAD),
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(depth, TGSI_WRITEMASK_Z),
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       swizzle(src(temp_pos), 3, 3, 3, 3),
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       prescale_trans,
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos) ))
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken depth = emit->depth_pos;
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SVGA3dShaderDestToken pos = emit->true_pos;
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct src_register imm_0055 = emit->imm_0055;
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Adjust GL clipping coordinate space to hardware (D3D-style):
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * DP4 temp_pos.z, {0,0,.5,.5}, temp_pos
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * MOV result.position, temp_pos
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op2( emit,
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_DP4),
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(temp_pos, TGSI_WRITEMASK_Z),
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       imm_0055,
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos) ))
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       pos,
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos) ))
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Move the manipulated depth into the extra texcoord reg */
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit,
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst_token(SVGA3DOP_MOV),
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       writemask(depth, TGSI_WRITEMASK_ZW),
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       src(temp_pos) ))
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  0: IF VFACE :4
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  1:   COLOR = FrontColor;
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  2: ELSE
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  3:   COLOR = BackColor;
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  4: ENDIF
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_light_twoside( struct svga_shader_emitter *emit )
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register vface, zero;
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register front[2];
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register back[2];
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken color[2];
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int count =  emit->internal_color_count;
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderInstToken if_token;
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (count == 0)
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vface = get_vface( emit );
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = get_zero_immediate( emit );
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Can't use get_temp() to allocate the color reg as such
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * temporaries will be reclaimed after each instruction by the call
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * to reset_temp_regs().
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      color[i] = dst_register( SVGA3DREG_TEMP, emit->nr_hw_temp++ );
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      front[i] = emit->input_map[emit->internal_color_idx[i]];
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Back is always the next input:
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      back[i] = front[i];
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      back[i].base.num = front[i].base.num + 1;
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Reassign the input_map to the actual front-face color:
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit->input_map[emit->internal_color_idx[i]] = src(color[i]);
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if_token = inst_token( SVGA3DOP_IFC );
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->key.fkey.front_ccw)
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_token.control = SVGA3DOPCOMP_LT;
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_token.control = SVGA3DOPCOMP_GT;
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = scalar(zero, TGSI_SWIZZLE_X);
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(emit_instruction( emit, if_token ) &&
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit_src( emit, vface ) &&
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit_src( emit, zero ) ))
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], front[i] ))
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(emit_instruction( emit, inst_token( SVGA3DOP_ELSE))))
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], back[i] ))
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_instruction( emit, inst_token( SVGA3DOP_ENDIF ) ))
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  0: SETP_GT TEMP, VFACE, 0
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  where TEMP is a fake frontface register
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_frontface( struct svga_shader_emitter *emit )
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register vface, zero;
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SVGA3dShaderDestToken temp;
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register pass, fail;
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vface = get_vface( emit );
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zero = get_zero_immediate( emit );
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Can't use get_temp() to allocate the fake frontface reg as such
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * temporaries will be reclaimed after each instruction by the call
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * to reset_temp_regs().
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   temp = dst_register( SVGA3DREG_TEMP,
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        emit->nr_hw_temp++ );
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->key.fkey.front_ccw) {
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pass = scalar( zero, TGSI_SWIZZLE_X );
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fail = scalar( zero, TGSI_SWIZZLE_W );
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pass = scalar( zero, TGSI_SWIZZLE_W );
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fail = scalar( zero, TGSI_SWIZZLE_X );
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit_conditional(emit, PIPE_FUNC_GREATER,
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         temp, vface, scalar( zero, TGSI_SWIZZLE_X ),
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         pass, fail))
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return FALSE;
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Reassign the input_map to the actual front-face color:
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->input_map[emit->internal_frontface_idx] = src(temp);
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit code to invert the T component of the incoming texture coordinate.
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is used for drawing point sprites when
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pipe_rasterizer_state::sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT.
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean emit_inverted_texcoords( struct svga_shader_emitter *emit )
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register zero = get_zero_immediate(emit);
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct src_register pos_neg_one = get_pos_neg_one_immediate( emit );
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned inverted_texcoords = emit->inverted_texcoords;
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (inverted_texcoords) {
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned unit = ffs(inverted_texcoords) - 1;
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(emit->inverted_texcoords & (1 << unit));
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(unit < Elements(emit->ps_true_texcoord));
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(unit < Elements(emit->ps_inverted_texcoord_input));
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(emit->ps_inverted_texcoord_input[unit]
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             < Elements(emit->input_map));
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* inverted = coord * (1, -1, 1, 1) + (0, 1, 0, 0) */
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!submit_op3(emit,
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst_token(SVGA3DOP_MAD),
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dst(emit->ps_inverted_texcoord[unit]),
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      emit->ps_true_texcoord[unit],
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      swizzle(pos_neg_one, 0, 3, 0, 0),  /* (1, -1, 1, 1) */
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      swizzle(zero, 0, 3, 0, 0)))  /* (0, 1, 0, 0) */
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Reassign the input_map entry to the new texcoord register */
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit->input_map[emit->ps_inverted_texcoord_input[unit]] =
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit->ps_inverted_texcoord[unit];
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inverted_texcoords &= ~(1 << unit);
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgneeds_to_create_zero( struct svga_shader_emitter *emit )
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_FRAGMENT) {
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->key.fkey.light_twoside)
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->key.fkey.white_fragments)
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->emit_frontface)
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->info.opcode_count[TGSI_OPCODE_DST] >= 1 ||
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          emit->info.opcode_count[TGSI_OPCODE_SSG] >= 1 ||
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          emit->info.opcode_count[TGSI_OPCODE_LIT] >= 1)
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->inverted_texcoords)
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* look for any PIPE_SWIZZLE_ZERO/ONE terms */
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < emit->key.fkey.num_textures; i++) {
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (emit->key.fkey.tex[i].swizzle_r > PIPE_SWIZZLE_ALPHA ||
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             emit->key.fkey.tex[i].swizzle_g > PIPE_SWIZZLE_ALPHA ||
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             emit->key.fkey.tex[i].swizzle_b > PIPE_SWIZZLE_ALPHA ||
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             emit->key.fkey.tex[i].swizzle_a > PIPE_SWIZZLE_ALPHA)
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return TRUE;
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < emit->key.fkey.num_textures; i++) {
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (emit->key.fkey.tex[i].compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return TRUE;
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->info.opcode_count[TGSI_OPCODE_CMP] >= 1)
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return TRUE;
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_ROUND] >= 1 ||
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SLT] >= 1 ||
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SNE] >= 1 ||
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_SEQ] >= 1 ||
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_EXP] >= 1 ||
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_LOG] >= 1 ||
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_XPD] >= 1 ||
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       emit->info.opcode_count[TGSI_OPCODE_KILP] >= 1)
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return TRUE;
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return FALSE;
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgneeds_to_create_loop_const( struct svga_shader_emitter *emit )
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1);
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgneeds_to_create_arl_consts( struct svga_shader_emitter *emit )
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (emit->num_arl_consts > 0);
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpre_parse_add_indirect( struct svga_shader_emitter *emit,
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        int num, int current_arl)
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(num < 0);
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < emit->num_arl_consts; ++i) {
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->arl_consts[i].arl_num == current_arl)
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* new entry */
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->num_arl_consts == i) {
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++emit->num_arl_consts;
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->arl_consts[i].number = (emit->arl_consts[i].number > num) ?
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                num :
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                emit->arl_consts[i].number;
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->arl_consts[i].arl_num = current_arl;
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpre_parse_instruction( struct svga_shader_emitter *emit,
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct tgsi_full_instruction *insn,
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       int current_arl)
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->Src[0].Register.Indirect &&
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       insn->Src[0].Indirect.File == TGSI_FILE_ADDRESS) {
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct tgsi_full_src_register *reg = &insn->Src[0];
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Index < 0) {
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->Src[1].Register.Indirect &&
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       insn->Src[1].Indirect.File == TGSI_FILE_ADDRESS) {
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct tgsi_full_src_register *reg = &insn->Src[1];
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Index < 0) {
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (insn->Src[2].Register.Indirect &&
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       insn->Src[2].Indirect.File == TGSI_FILE_ADDRESS) {
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct tgsi_full_src_register *reg = &insn->Src[2];
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg->Register.Index < 0) {
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpre_parse_tokens( struct svga_shader_emitter *emit,
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct tgsi_token *tokens )
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_parse_context parse;
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int current_arl = 0;
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_parse_init( &parse, tokens );
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (!tgsi_parse_end_of_tokens( &parse )) {
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tgsi_parse_token( &parse );
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (parse.FullToken.Token.Type) {
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_IMMEDIATE:
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_DECLARATION:
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_INSTRUCTION:
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (parse.FullToken.FullInstruction.Instruction.Opcode ==
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             TGSI_OPCODE_ARL) {
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ++current_arl;
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!pre_parse_instruction( emit, &parse.FullToken.FullInstruction,
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     current_arl ))
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean svga_shader_emit_helpers( struct svga_shader_emitter *emit )
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (needs_to_create_zero( emit )) {
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      create_zero_immediate( emit );
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (needs_to_create_loop_const( emit )) {
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      create_loop_const( emit );
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (needs_to_create_arl_consts( emit )) {
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      create_arl_consts( emit );
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_FRAGMENT) {
3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!emit_ps_preamble( emit ))
3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return FALSE;
3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->key.fkey.light_twoside) {
3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!emit_light_twoside( emit ))
3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->emit_frontface) {
3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!emit_frontface( emit ))
3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (emit->inverted_texcoords) {
3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!emit_inverted_texcoords( emit ))
3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return TRUE;
3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct tgsi_token *tokens )
3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_parse_context parse;
3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean ret = TRUE;
3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean helpers_emitted = FALSE;
3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned line_nr = 0;
3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_parse_init( &parse, tokens );
3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit->internal_imm_count = 0;
3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (emit->unit == PIPE_SHADER_VERTEX) {
3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = emit_vs_preamble( emit );
3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!ret)
3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto done;
3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pre_parse_tokens(emit, tokens);
3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (!tgsi_parse_end_of_tokens( &parse )) {
3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tgsi_parse_token( &parse );
3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (parse.FullToken.Token.Type) {
3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_IMMEDIATE:
3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ret = svga_emit_immediate( emit, &parse.FullToken.FullImmediate );
3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!ret)
3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto done;
3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_DECLARATION:
3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ret = svga_translate_decl_sm30( emit, &parse.FullToken.FullDeclaration );
3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!ret)
3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto done;
3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_TOKEN_TYPE_INSTRUCTION:
3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!helpers_emitted) {
3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!svga_shader_emit_helpers( emit ))
3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               goto done;
3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            helpers_emitted = TRUE;
3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ret = svga_emit_instruction( emit,
3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      line_nr++,
3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &parse.FullToken.FullInstruction );
3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!ret)
3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto done;
3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reset_temp_regs( emit );
3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Need to terminate the current subroutine.  Note that the
3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * hardware doesn't tolerate shaders without sub-routines
3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * terminating with RET+END.
3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!emit->in_main_func) {
3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = emit_instruction( emit, inst_token( SVGA3DOP_RET ) );
3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!ret)
3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto done;
3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(emit->dynamic_branching_level == 0);
3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Need to terminate the whole shader:
3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ret)
3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto done;
3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdone:
3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tgsi_parse_free( &parse );
3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3369