13af1f3b9220733f5e3a76fe38fbc397974678234Brian/**************************************************************************
23af1f3b9220733f5e3a76fe38fbc397974678234Brian *
33af1f3b9220733f5e3a76fe38fbc397974678234Brian * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
43af1f3b9220733f5e3a76fe38fbc397974678234Brian * All Rights Reserved.
53af1f3b9220733f5e3a76fe38fbc397974678234Brian *
63af1f3b9220733f5e3a76fe38fbc397974678234Brian * Permission is hereby granted, free of charge, to any person obtaining a
73af1f3b9220733f5e3a76fe38fbc397974678234Brian * copy of this software and associated documentation files (the
83af1f3b9220733f5e3a76fe38fbc397974678234Brian * "Software"), to deal in the Software without restriction, including
93af1f3b9220733f5e3a76fe38fbc397974678234Brian * without limitation the rights to use, copy, modify, merge, publish,
103af1f3b9220733f5e3a76fe38fbc397974678234Brian * distribute, sub license, and/or sell copies of the Software, and to
113af1f3b9220733f5e3a76fe38fbc397974678234Brian * permit persons to whom the Software is furnished to do so, subject to
123af1f3b9220733f5e3a76fe38fbc397974678234Brian * the following conditions:
133af1f3b9220733f5e3a76fe38fbc397974678234Brian *
143af1f3b9220733f5e3a76fe38fbc397974678234Brian * The above copyright notice and this permission notice (including the
153af1f3b9220733f5e3a76fe38fbc397974678234Brian * next paragraph) shall be included in all copies or substantial portions
163af1f3b9220733f5e3a76fe38fbc397974678234Brian * of the Software.
173af1f3b9220733f5e3a76fe38fbc397974678234Brian *
183af1f3b9220733f5e3a76fe38fbc397974678234Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193af1f3b9220733f5e3a76fe38fbc397974678234Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203af1f3b9220733f5e3a76fe38fbc397974678234Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
213af1f3b9220733f5e3a76fe38fbc397974678234Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
223af1f3b9220733f5e3a76fe38fbc397974678234Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
233af1f3b9220733f5e3a76fe38fbc397974678234Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
243af1f3b9220733f5e3a76fe38fbc397974678234Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253af1f3b9220733f5e3a76fe38fbc397974678234Brian *
263af1f3b9220733f5e3a76fe38fbc397974678234Brian **************************************************************************/
273af1f3b9220733f5e3a76fe38fbc397974678234Brian
283af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_reg.h"
293af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_context.h"
303af1f3b9220733f5e3a76fe38fbc397974678234Brian#include "i915_fpc.h"
312c4661f8fce8a27f2082c6ac498f9fb188878476Michal Krol#include "util/u_math.h"
323af1f3b9220733f5e3a76fe38fbc397974678234Brian
333af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
343af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_temp(struct i915_fp_compile *p)
353af1f3b9220733f5e3a76fe38fbc397974678234Brian{
363af1f3b9220733f5e3a76fe38fbc397974678234Brian   int bit = ffs(~p->temp_flag);
373af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (!bit) {
385d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "i915_get_temp: out of temporaries");
393af1f3b9220733f5e3a76fe38fbc397974678234Brian      return 0;
403af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
413af1f3b9220733f5e3a76fe38fbc397974678234Brian
423af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->temp_flag |= 1 << (bit - 1);
430235b3252100eda553babea42c014445358a2985Brian   return bit - 1;
443af1f3b9220733f5e3a76fe38fbc397974678234Brian}
453af1f3b9220733f5e3a76fe38fbc397974678234Brian
463af1f3b9220733f5e3a76fe38fbc397974678234Brian
470235b3252100eda553babea42c014445358a2985Brianstatic void
480235b3252100eda553babea42c014445358a2985Briani915_release_temp(struct i915_fp_compile *p, int reg)
490235b3252100eda553babea42c014445358a2985Brian{
500235b3252100eda553babea42c014445358a2985Brian   p->temp_flag &= ~(1 << reg);
510235b3252100eda553babea42c014445358a2985Brian}
520235b3252100eda553babea42c014445358a2985Brian
530235b3252100eda553babea42c014445358a2985Brian
540235b3252100eda553babea42c014445358a2985Brian/**
550235b3252100eda553babea42c014445358a2985Brian * Get unpreserved temporary, a temp whose value is not preserved between
560235b3252100eda553babea42c014445358a2985Brian * PS program phases.
570235b3252100eda553babea42c014445358a2985Brian */
583af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
593af1f3b9220733f5e3a76fe38fbc397974678234Briani915_get_utemp(struct i915_fp_compile * p)
603af1f3b9220733f5e3a76fe38fbc397974678234Brian{
613af1f3b9220733f5e3a76fe38fbc397974678234Brian   int bit = ffs(~p->utemp_flag);
623af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (!bit) {
635d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "i915_get_utemp: out of temporaries");
643af1f3b9220733f5e3a76fe38fbc397974678234Brian      return 0;
653af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
663af1f3b9220733f5e3a76fe38fbc397974678234Brian
673af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->utemp_flag |= 1 << (bit - 1);
683af1f3b9220733f5e3a76fe38fbc397974678234Brian   return UREG(REG_TYPE_U, (bit - 1));
693af1f3b9220733f5e3a76fe38fbc397974678234Brian}
703af1f3b9220733f5e3a76fe38fbc397974678234Brian
713af1f3b9220733f5e3a76fe38fbc397974678234Brianvoid
723af1f3b9220733f5e3a76fe38fbc397974678234Briani915_release_utemps(struct i915_fp_compile *p)
733af1f3b9220733f5e3a76fe38fbc397974678234Brian{
743af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->utemp_flag = ~0x7;
753af1f3b9220733f5e3a76fe38fbc397974678234Brian}
763af1f3b9220733f5e3a76fe38fbc397974678234Brian
773af1f3b9220733f5e3a76fe38fbc397974678234Brian
783af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
793af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_decl(struct i915_fp_compile *p,
803af1f3b9220733f5e3a76fe38fbc397974678234Brian               uint type, uint nr, uint d0_flags)
813af1f3b9220733f5e3a76fe38fbc397974678234Brian{
823af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint reg = UREG(type, nr);
833af1f3b9220733f5e3a76fe38fbc397974678234Brian
843af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (type == REG_TYPE_T) {
853af1f3b9220733f5e3a76fe38fbc397974678234Brian      if (p->decl_t & (1 << nr))
863af1f3b9220733f5e3a76fe38fbc397974678234Brian         return reg;
873af1f3b9220733f5e3a76fe38fbc397974678234Brian
883af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->decl_t |= (1 << nr);
893af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
903af1f3b9220733f5e3a76fe38fbc397974678234Brian   else if (type == REG_TYPE_S) {
913af1f3b9220733f5e3a76fe38fbc397974678234Brian      if (p->decl_s & (1 << nr))
923af1f3b9220733f5e3a76fe38fbc397974678234Brian         return reg;
933af1f3b9220733f5e3a76fe38fbc397974678234Brian
943af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->decl_s |= (1 << nr);
953af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
963af1f3b9220733f5e3a76fe38fbc397974678234Brian   else
973af1f3b9220733f5e3a76fe38fbc397974678234Brian      return reg;
983af1f3b9220733f5e3a76fe38fbc397974678234Brian
99c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   if (p->decl< p->declarations + I915_PROGRAM_SIZE) {
100c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
101c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = D1_MBZ;
102c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->decl++) = D2_MBZ;
103c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   }
104c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   else
1055d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "Out of declarations");
1063af1f3b9220733f5e3a76fe38fbc397974678234Brian
1073af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->nr_decl_insn++;
1083af1f3b9220733f5e3a76fe38fbc397974678234Brian   return reg;
1093af1f3b9220733f5e3a76fe38fbc397974678234Brian}
1103af1f3b9220733f5e3a76fe38fbc397974678234Brian
1113af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
1123af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_arith(struct i915_fp_compile * p,
1133af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint op,
1143af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint dest,
1153af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint mask,
1163af1f3b9220733f5e3a76fe38fbc397974678234Brian                uint saturate, uint src0, uint src1, uint src2)
1173af1f3b9220733f5e3a76fe38fbc397974678234Brian{
1183af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint c[3];
1193af1f3b9220733f5e3a76fe38fbc397974678234Brian   uint nr_const = 0;
1203af1f3b9220733f5e3a76fe38fbc397974678234Brian
1213af1f3b9220733f5e3a76fe38fbc397974678234Brian   assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
1223af1f3b9220733f5e3a76fe38fbc397974678234Brian   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
1233af1f3b9220733f5e3a76fe38fbc397974678234Brian   assert(dest);
1243af1f3b9220733f5e3a76fe38fbc397974678234Brian
1253af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
1263af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 0;
1273af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
1283af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 1;
1293af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
1303af1f3b9220733f5e3a76fe38fbc397974678234Brian      c[nr_const++] = 2;
1313af1f3b9220733f5e3a76fe38fbc397974678234Brian
1323af1f3b9220733f5e3a76fe38fbc397974678234Brian   /* Recursively call this function to MOV additional const values
1333af1f3b9220733f5e3a76fe38fbc397974678234Brian    * into temporary registers.  Use utemp registers for this -
1343af1f3b9220733f5e3a76fe38fbc397974678234Brian    * currently shouldn't be possible to run out, but keep an eye on
1353af1f3b9220733f5e3a76fe38fbc397974678234Brian    * this.
1363af1f3b9220733f5e3a76fe38fbc397974678234Brian    */
1373af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (nr_const > 1) {
1383af1f3b9220733f5e3a76fe38fbc397974678234Brian      uint s[3], first, i, old_utemp_flag;
1393af1f3b9220733f5e3a76fe38fbc397974678234Brian
1403af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[0] = src0;
1413af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[1] = src1;
1423af1f3b9220733f5e3a76fe38fbc397974678234Brian      s[2] = src2;
1433af1f3b9220733f5e3a76fe38fbc397974678234Brian      old_utemp_flag = p->utemp_flag;
1443af1f3b9220733f5e3a76fe38fbc397974678234Brian
1453af1f3b9220733f5e3a76fe38fbc397974678234Brian      first = GET_UREG_NR(s[c[0]]);
1463af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (i = 1; i < nr_const; i++) {
1473af1f3b9220733f5e3a76fe38fbc397974678234Brian         if (GET_UREG_NR(s[c[i]]) != first) {
1483af1f3b9220733f5e3a76fe38fbc397974678234Brian            uint tmp = i915_get_utemp(p);
1493af1f3b9220733f5e3a76fe38fbc397974678234Brian
1503af1f3b9220733f5e3a76fe38fbc397974678234Brian            i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
1513af1f3b9220733f5e3a76fe38fbc397974678234Brian                            s[c[i]], 0, 0);
1523af1f3b9220733f5e3a76fe38fbc397974678234Brian            s[c[i]] = tmp;
1533af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
1543af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
1553af1f3b9220733f5e3a76fe38fbc397974678234Brian
1563af1f3b9220733f5e3a76fe38fbc397974678234Brian      src0 = s[0];
1573af1f3b9220733f5e3a76fe38fbc397974678234Brian      src1 = s[1];
1583af1f3b9220733f5e3a76fe38fbc397974678234Brian      src2 = s[2];
1593af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->utemp_flag = old_utemp_flag;   /* restore */
1603af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
1613af1f3b9220733f5e3a76fe38fbc397974678234Brian
162c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   if (p->csr< p->program + I915_PROGRAM_SIZE) {
163c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
164c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
165c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
166c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   }
167c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   else
1685d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      i915_program_error(p, "Out of instructions");
1695d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
1705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   if (GET_UREG_TYPE(dest) == REG_TYPE_R)
1715d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
1723af1f3b9220733f5e3a76fe38fbc397974678234Brian
1733af1f3b9220733f5e3a76fe38fbc397974678234Brian   p->nr_alu_insn++;
1743af1f3b9220733f5e3a76fe38fbc397974678234Brian   return dest;
1753af1f3b9220733f5e3a76fe38fbc397974678234Brian}
1763af1f3b9220733f5e3a76fe38fbc397974678234Brian
1770235b3252100eda553babea42c014445358a2985Brian
1780235b3252100eda553babea42c014445358a2985Brian/**
1790235b3252100eda553babea42c014445358a2985Brian * Emit a texture load or texkill instruction.
1800235b3252100eda553babea42c014445358a2985Brian * \param dest  the dest i915 register
1810235b3252100eda553babea42c014445358a2985Brian * \param destmask  the dest register writemask
1820235b3252100eda553babea42c014445358a2985Brian * \param sampler  the i915 sampler register
1830235b3252100eda553babea42c014445358a2985Brian * \param coord  the i915 source texcoord operand
1840235b3252100eda553babea42c014445358a2985Brian * \param opcode  the instruction opcode
1850235b3252100eda553babea42c014445358a2985Brian */
1863af1f3b9220733f5e3a76fe38fbc397974678234Brianuint i915_emit_texld( struct i915_fp_compile *p,
187e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint dest,
188e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint destmask,
189e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint sampler,
190e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint coord,
191e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint opcode,
192e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin                      uint num_coord )
1933af1f3b9220733f5e3a76fe38fbc397974678234Brian{
1940235b3252100eda553babea42c014445358a2985Brian   const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
195e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin
1960235b3252100eda553babea42c014445358a2985Brian   int temp = -1;
197e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   uint ignore = 0;
198e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin
199e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   /* Eliminate the useless texture coordinates. Otherwise we end up generating
200e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin    * a swizzle for no reason below. */
201e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   switch(num_coord) {
202e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 0:
203e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore x */
204e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_X_SHIFT);
205e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 1:
206e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore y */
207e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_Y_SHIFT);
208e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 2:
209e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore z */
210e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_Z_SHIFT);
211e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      case 3:
212e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         /* Ignore w */
213e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin         ignore |= (0xf << UREG_CHANNEL_W_SHIFT);
214e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin   }
2150235b3252100eda553babea42c014445358a2985Brian
21663dbd3fefba93ccfb984ed589795f6784bb4d1e3Stéphane Marchesin   if ( (coord & ~ignore ) != (k & ~ignore) ) {
2170235b3252100eda553babea42c014445358a2985Brian      /* texcoord is swizzled or negated.  Need to allocate a new temporary
2180235b3252100eda553babea42c014445358a2985Brian       * register (a utemp / unpreserved temp) won't do.
2193af1f3b9220733f5e3a76fe38fbc397974678234Brian       */
2200235b3252100eda553babea42c014445358a2985Brian      uint tempReg;
2210235b3252100eda553babea42c014445358a2985Brian
2220235b3252100eda553babea42c014445358a2985Brian      temp = i915_get_temp(p);           /* get temp reg index */
2230235b3252100eda553babea42c014445358a2985Brian      tempReg = UREG(REG_TYPE_R, temp);  /* make i915 register */
2240235b3252100eda553babea42c014445358a2985Brian
2250235b3252100eda553babea42c014445358a2985Brian      i915_emit_arith( p, A0_MOV,
2260235b3252100eda553babea42c014445358a2985Brian                       tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
2270235b3252100eda553babea42c014445358a2985Brian                       0,                            /* saturate */
2280235b3252100eda553babea42c014445358a2985Brian                       coord, 0, 0 );                /* src0, src1, src2 */
2290235b3252100eda553babea42c014445358a2985Brian
2300235b3252100eda553babea42c014445358a2985Brian      /* new src texcoord is tempReg */
2310235b3252100eda553babea42c014445358a2985Brian      coord = tempReg;
2323af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2333af1f3b9220733f5e3a76fe38fbc397974678234Brian
2343af1f3b9220733f5e3a76fe38fbc397974678234Brian   /* Don't worry about saturate as we only support
2353af1f3b9220733f5e3a76fe38fbc397974678234Brian    */
2363af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (destmask != A0_DEST_CHANNEL_ALL) {
2370235b3252100eda553babea42c014445358a2985Brian      /* if not writing to XYZW... */
2383af1f3b9220733f5e3a76fe38fbc397974678234Brian      uint tmp = i915_get_utemp(p);
239e3c94fac4eb159f8c35798d1ad7515a40f5a2ecaStéphane Marchesin      i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode, num_coord );
2403af1f3b9220733f5e3a76fe38fbc397974678234Brian      i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
2410235b3252100eda553babea42c014445358a2985Brian      /* XXX release utemp here? */
2423af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2433af1f3b9220733f5e3a76fe38fbc397974678234Brian   else {
2443af1f3b9220733f5e3a76fe38fbc397974678234Brian      assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
2454a796264dfc1bdba37a7204f3439a8da213109edVinson Lee      assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
2463af1f3b9220733f5e3a76fe38fbc397974678234Brian
2475d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Output register being oC or oD defines a phase boundary */
2485d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
2495d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          GET_UREG_TYPE(dest) == REG_TYPE_OD)
2505d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2515d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2525d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      /* Reading from an r# register whose contents depend on output of the
2535d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       * current phase defines a phase boundary.
2545d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin       */
2555d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
2565d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin          p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
2575d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->nr_tex_indirect++;
2583af1f3b9220733f5e3a76fe38fbc397974678234Brian
259c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      if (p->csr< p->program + I915_PROGRAM_SIZE) {
260c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = (opcode |
2615d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_DEST( dest ) |
2625d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin                        T0_SAMPLER( sampler ));
2633af1f3b9220733f5e3a76fe38fbc397974678234Brian
264c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T1_ADDRESS_REG( coord );
265c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin         *(p->csr++) = T2_MBZ;
266c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin      }
2675d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      else
2685d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         i915_program_error(p, "Out of instructions");
2695d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin
2705d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin      if (GET_UREG_TYPE(dest) == REG_TYPE_R)
2715d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin         p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
2723af1f3b9220733f5e3a76fe38fbc397974678234Brian
2733af1f3b9220733f5e3a76fe38fbc397974678234Brian      p->nr_tex_insn++;
2743af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
2750235b3252100eda553babea42c014445358a2985Brian
2760235b3252100eda553babea42c014445358a2985Brian   if (temp >= 0)
2770235b3252100eda553babea42c014445358a2985Brian      i915_release_temp(p, temp);
2780235b3252100eda553babea42c014445358a2985Brian
2790235b3252100eda553babea42c014445358a2985Brian   return dest;
2803af1f3b9220733f5e3a76fe38fbc397974678234Brian}
2813af1f3b9220733f5e3a76fe38fbc397974678234Brian
2823af1f3b9220733f5e3a76fe38fbc397974678234Brian
2833af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
2843af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const1f(struct i915_fp_compile * p, float c0)
2853af1f3b9220733f5e3a76fe38fbc397974678234Brian{
286c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
2875961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
2883af1f3b9220733f5e3a76fe38fbc397974678234Brian
2893af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
2903af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
2913af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
2923af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
2933af1f3b9220733f5e3a76fe38fbc397974678234Brian
2943af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
295c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
2963af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
2973af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 4; idx++) {
298c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (1 << idx)) ||
299c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian             ifs->constants[reg][idx] == c0) {
300c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx] = c0;
301c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 1 << idx;
302c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
303c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
3043af1f3b9220733f5e3a76fe38fbc397974678234Brian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
3053af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3063af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3073af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3083af1f3b9220733f5e3a76fe38fbc397974678234Brian
3095d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const1f: out of constants");
3103af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3113af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3123af1f3b9220733f5e3a76fe38fbc397974678234Brian
3133af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3143af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
3153af1f3b9220733f5e3a76fe38fbc397974678234Brian{
316c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3175961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg, idx;
3183af1f3b9220733f5e3a76fe38fbc397974678234Brian
3193af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 0.0)
3203af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
3213af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c0 == 1.0)
3223af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
3233af1f3b9220733f5e3a76fe38fbc397974678234Brian
3243af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 0.0)
3253af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
3263af1f3b9220733f5e3a76fe38fbc397974678234Brian   if (c1 == 1.0)
3273af1f3b9220733f5e3a76fe38fbc397974678234Brian      return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
3283af1f3b9220733f5e3a76fe38fbc397974678234Brian
329c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
330c66877c29034af411b06f1f1d1e17b6c048ac38dStéphane Marchesin   // we can use swizzle + neg for that
3313af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
332c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf ||
333c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
3343af1f3b9220733f5e3a76fe38fbc397974678234Brian         continue;
3353af1f3b9220733f5e3a76fe38fbc397974678234Brian      for (idx = 0; idx < 3; idx++) {
336c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (!(ifs->constant_flags[reg] & (3 << idx))) {
337c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 0] = c0;
338c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constants[reg][idx + 1] = c1;
339c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->constant_flags[reg] |= 3 << idx;
340c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            if (reg + 1 > ifs->num_constants)
341c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian               ifs->num_constants = reg + 1;
342c0bb4ba9e665e40a325d82aa2ee48d7b8abd603bBrian            return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);
3433af1f3b9220733f5e3a76fe38fbc397974678234Brian         }
3443af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3453af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3463af1f3b9220733f5e3a76fe38fbc397974678234Brian
3475d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const2f: out of constants");
3483af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3493af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3503af1f3b9220733f5e3a76fe38fbc397974678234Brian
3513af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3523af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4f(struct i915_fp_compile * p,
3533af1f3b9220733f5e3a76fe38fbc397974678234Brian                  float c0, float c1, float c2, float c3)
3543af1f3b9220733f5e3a76fe38fbc397974678234Brian{
355c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian   struct i915_fragment_shader *ifs = p->shader;
3565961732c1b59403b4e736fa354a64d4a0e5d8af2Michal   unsigned reg;
3573af1f3b9220733f5e3a76fe38fbc397974678234Brian
3585d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // XXX emit swizzle here for 0, 1, -1 and any combination thereof
3595d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   // we can use swizzle + neg for that
3603af1f3b9220733f5e3a76fe38fbc397974678234Brian   for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
361c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      if (ifs->constant_flags[reg] == 0xf &&
362c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][0] == c0 &&
363c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][1] == c1 &&
364c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][2] == c2 &&
365c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian          ifs->constants[reg][3] == c3) {
3663af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
3673af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
368c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian      else if (ifs->constant_flags[reg] == 0) {
369c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian
370c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][0] = c0;
371c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][1] = c1;
372c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][2] = c2;
373c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constants[reg][3] = c3;
374c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         ifs->constant_flags[reg] = 0xf;
375c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian         if (reg + 1 > ifs->num_constants)
376c74900ee5d80c7c2b7cbe4ed87395526a742a13eBrian            ifs->num_constants = reg + 1;
3773af1f3b9220733f5e3a76fe38fbc397974678234Brian         return UREG(REG_TYPE_CONST, reg);
3783af1f3b9220733f5e3a76fe38fbc397974678234Brian      }
3793af1f3b9220733f5e3a76fe38fbc397974678234Brian   }
3803af1f3b9220733f5e3a76fe38fbc397974678234Brian
3815d7609715a44d08f29d4b605c4bea2742a194493Stéphane Marchesin   i915_program_error(p, "i915_emit_const4f: out of constants");
3823af1f3b9220733f5e3a76fe38fbc397974678234Brian   return 0;
3833af1f3b9220733f5e3a76fe38fbc397974678234Brian}
3843af1f3b9220733f5e3a76fe38fbc397974678234Brian
3853af1f3b9220733f5e3a76fe38fbc397974678234Brian
3863af1f3b9220733f5e3a76fe38fbc397974678234Brianuint
3873af1f3b9220733f5e3a76fe38fbc397974678234Briani915_emit_const4fv(struct i915_fp_compile * p, const float * c)
3883af1f3b9220733f5e3a76fe38fbc397974678234Brian{
3893af1f3b9220733f5e3a76fe38fbc397974678234Brian   return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
3903af1f3b9220733f5e3a76fe38fbc397974678234Brian}
391