1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.3
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file prog_execute.c
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software interpreter for vertex/fragment programs.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Brian Paul
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: we do everything in single-precision floating point; we don't
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * currently observe the single/half/fixed-precision qualifiers.
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_execute.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_instruction.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_parameter.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_print.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "prog_noise.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* debug predicate */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_PROG 0
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set x to positive or negative infinity.
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_IEEE) || defined(_WIN32)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x)                  \
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do {                                      \
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fi_type fi;                         \
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fi.i = 0x7F800000;                  \
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         x = fi.f;                           \
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } while (0)
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x)                  \
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do {                                      \
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fi_type fi;                         \
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fi.i = 0xFF800000;                  \
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         x = fi.f;                           \
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } while (0)
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(VMS)
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x)  x = __MAXFLOAT
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x)  x = -__MAXFLOAT
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_POS_INFINITY(x)  x = (GLfloat) HUGE_VAL
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_NEG_INFINITY(x)  x = (GLfloat) -HUGE_VAL
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return TRUE for +0 and other positive values, FALSE otherwise.
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used for RCC opcode.
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpositive(float x)
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi_type fi;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi.f = x;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fi.i & 0x80000000)
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return a pointer to the 4-element float vector specified by the given
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * source register.
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline const GLfloat *
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_src_register_pointer(const struct prog_src_register *source,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct gl_program_machine *machine)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_program *prog = machine->CurProgram;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint reg = source->Index;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->RelAddr) {
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* add address register value to src index/offset */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg += machine->AddressReg[0][0];
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg < 0) {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (source->File) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_TEMPORARY:
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_TEMPS)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->Temporaries[reg];
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_INPUT:
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (reg >= VERT_ATTRIB_MAX)
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return ZeroVec;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return machine->VertAttribs[reg];
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (reg >= FRAG_ATTRIB_MAX)
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return ZeroVec;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return machine->Attribs[reg][machine->CurElement];
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_OUTPUT:
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_OUTPUTS)
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->Outputs[reg];
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_LOCAL_PARAM:
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_LOCAL_PARAMS)
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->CurProgram->LocalParams[reg];
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_ENV_PARAM:
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_ENV_PARAMS)
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->EnvParams[reg];
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_STATE_VAR:
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fallthrough */
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_CONSTANT:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fallthrough */
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_UNIFORM:
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fallthrough */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_NAMED_PARAM:
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= (GLint) prog->Parameters->NumParameters)
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ZeroVec;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (GLfloat *) prog->Parameters->ParameterValues[reg];
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_SYSTEM_VALUE:
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(reg < Elements(machine->SystemValues));
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->SystemValues[reg];
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL,
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "Invalid src register file %d in get_src_register_pointer()",
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         source->File);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return a pointer to the 4-element float vector specified by the given
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * destination register.
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat *
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_dst_register_pointer(const struct prog_dst_register *dest,
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct gl_program_machine *machine)
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static GLfloat dummyReg[4];
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint reg = dest->Index;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dest->RelAddr) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* add address register value to src index/offset */
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reg += machine->AddressReg[0][0];
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg < 0) {
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return dummyReg;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (dest->File) {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_TEMPORARY:
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_TEMPS)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return dummyReg;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->Temporaries[reg];
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_OUTPUT:
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (reg >= MAX_PROGRAM_OUTPUTS)
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return dummyReg;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return machine->Outputs[reg];
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_WRITE_ONLY:
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return dummyReg;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL,
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "Invalid dest register file %d in get_dst_register_pointer()",
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dest->File);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch a 4-element float vector from the given source register.
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply swizzling and negating as needed.
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4(const struct prog_src_register *source,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const struct gl_program_machine *machine, GLfloat result[4])
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat *src = get_src_register_pointer(source, machine);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(src);
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Swizzle == SWIZZLE_NOOP) {
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* no swizzling */
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      COPY_4V(result, src);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = src[GET_SWZ(source->Swizzle, 0)];
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[1] = src[GET_SWZ(source->Swizzle, 1)];
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[2] = src[GET_SWZ(source->Swizzle, 2)];
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[3] = src[GET_SWZ(source->Swizzle, 3)];
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Abs) {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = FABSF(result[0]);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[1] = FABSF(result[1]);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[2] = FABSF(result[2]);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[3] = FABSF(result[3]);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Negate) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(source->Negate == NEGATE_XYZW);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = -result[0];
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[1] = -result[1];
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[2] = -result[2];
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[3] = -result[3];
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NAN_CHECK
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(result[0]));
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(result[0]));
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(result[0]));
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(result[0]));
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch a 4-element uint vector from the given source register.
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Apply swizzling but not negation/abs.
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4ui(const struct prog_src_register *source,
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                const struct gl_program_machine *machine, GLuint result[4])
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(src);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Swizzle == SWIZZLE_NOOP) {
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* no swizzling */
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      COPY_4V(result, src);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = src[GET_SWZ(source->Swizzle, 0)];
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[1] = src[GET_SWZ(source->Swizzle, 1)];
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[2] = src[GET_SWZ(source->Swizzle, 2)];
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[3] = src[GET_SWZ(source->Swizzle, 3)];
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note: no Negate or Abs here */
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch the derivative with respect to X or Y for the given register.
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX this currently only works for fragment program input attribs.
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector4_deriv(struct gl_context * ctx,
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const struct prog_src_register *source,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const struct gl_program_machine *machine,
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    char xOrY, GLfloat result[4])
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->File == PROGRAM_INPUT &&
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       source->Index < (GLint) machine->NumDeriv) {
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLint col = machine->CurElement;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3];
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLfloat invQ = 1.0f / w;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat deriv[4];
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (xOrY == 'X') {
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[0] = machine->DerivX[source->Index][0] * invQ;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[1] = machine->DerivX[source->Index][1] * invQ;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[2] = machine->DerivX[source->Index][2] * invQ;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[3] = machine->DerivX[source->Index][3] * invQ;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[0] = machine->DerivY[source->Index][0] * invQ;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[1] = machine->DerivY[source->Index][1] * invQ;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[2] = machine->DerivY[source->Index][2] * invQ;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         deriv[3] = machine->DerivY[source->Index][3] * invQ;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = deriv[GET_SWZ(source->Swizzle, 0)];
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[1] = deriv[GET_SWZ(source->Swizzle, 1)];
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[2] = deriv[GET_SWZ(source->Swizzle, 2)];
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[3] = deriv[GET_SWZ(source->Swizzle, 3)];
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source->Abs) {
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[0] = FABSF(result[0]);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[1] = FABSF(result[1]);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[2] = FABSF(result[2]);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[3] = FABSF(result[3]);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (source->Negate) {
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(source->Negate == NEGATE_XYZW);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[0] = -result[0];
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[1] = -result[1];
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[2] = -result[2];
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result[3] = -result[3];
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but only return result[0] element.
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector1(const struct prog_src_register *source,
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const struct gl_program_machine *machine, GLfloat result[4])
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat *src = get_src_register_pointer(source, machine);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(src);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[0] = src[GET_SWZ(source->Swizzle, 0)];
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Abs) {
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = FABSF(result[0]);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (source->Negate) {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[0] = -result[0];
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_vector1ui(const struct prog_src_register *source,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                const struct gl_program_machine *machine)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src[GET_SWZ(source->Swizzle, 0)];
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch texel from texture.  Use partial derivatives when possible.
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfetch_texel(struct gl_context *ctx,
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct gl_program_machine *machine,
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct prog_instruction *inst,
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLfloat texcoord[4], GLfloat lodBias,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat color[4])
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint unit = machine->Samplers[inst->TexSrcUnit];
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note: we only have the right derivatives for fragment input attribs.
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (machine->NumDeriv > 0 &&
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->SrcReg[0].File == PROGRAM_INPUT &&
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) {
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* simple texture fetch for which we should have derivatives */
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint attr = inst->SrcReg[0].Index;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      machine->FetchTexelDeriv(ctx, texcoord,
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               machine->DerivX[attr],
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               machine->DerivY[attr],
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               lodBias, unit, color);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color);
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Test value against zero and return GT, LT, EQ or UN if NaN.
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLuint
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggenerate_cc(float value)
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value != value)
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return COND_UN;           /* NaN */
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value > 0.0F)
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return COND_GT;
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value < 0.0F)
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return COND_LT;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return COND_EQ;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Test if the ccMaskRule is satisfied by the given condition code.
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to mask destination writes according to the current condition code.
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtest_cc(GLuint condCode, GLuint ccMaskRule)
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ccMaskRule) {
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_EQ: return (condCode == COND_EQ);
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_NE: return (condCode != COND_EQ);
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_LT: return (condCode == COND_LT);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_GT: return (condCode == COND_GT);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_TR: return GL_TRUE;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case COND_FL: return GL_FALSE;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:      return GL_TRUE;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Evaluate the 4 condition codes against a predicate and return GL_TRUE
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or GL_FALSE to indicate result.
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLboolean
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgeval_condition(const struct gl_program_machine *machine,
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const struct prog_instruction *inst)
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint swizzle = inst->DstReg.CondSwizzle;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint condMask = inst->DstReg.CondMask;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Store 4 floats into a register.  Observe the instructions saturate and
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * set-condition-code flags.
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstore_vector4(const struct prog_instruction *inst,
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              struct gl_program_machine *machine, const GLfloat value[4])
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct prog_dst_register *dstReg = &(inst->DstReg);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint writeMask = dstReg->WriteMask;
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat clampedValue[4];
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat *dst = get_dst_register_pointer(dstReg, machine);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value[0] > 1.0e10 ||
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       IS_INF_OR_NAN(value[0]) ||
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       IS_INF_OR_NAN(value[1]) ||
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (clamp) {
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      value = clampedValue;
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dstReg->CondMask != COND_TR) {
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* condition codes may turn off some writes */
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_X) {
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_X;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Y) {
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_Y;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Z) {
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_Z;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_W) {
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_W;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NAN_CHECK
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(value[0]));
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(value[0]));
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(value[0]));
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!IS_INF_OR_NAN(value[0]));
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_X)
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[0] = value[0];
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_Y)
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[1] = value[1];
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_Z)
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[2] = value[2];
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_W)
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[3] = value[3];
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (inst->CondUpdate) {
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_X)
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[0] = generate_cc(value[0]);
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Y)
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[1] = generate_cc(value[1]);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Z)
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[2] = generate_cc(value[2]);
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_W)
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[3] = generate_cc(value[3]);
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_PROG
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("CondCodes=(%s,%s,%s,%s) for:\n",
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[0]),
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[1]),
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[2]),
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[3]));
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Store 4 uints into a register.  Observe the set-condition-code flags.
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstore_vector4ui(const struct prog_instruction *inst,
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                struct gl_program_machine *machine, const GLuint value[4])
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct prog_dst_register *dstReg = &(inst->DstReg);
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint writeMask = dstReg->WriteMask;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine);
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dstReg->CondMask != COND_TR) {
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* condition codes may turn off some writes */
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_X) {
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_X;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Y) {
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_Y;
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Z) {
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_Z;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_W) {
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      dstReg->CondMask))
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            writeMask &= ~WRITEMASK_W;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_X)
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[0] = value[0];
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_Y)
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[1] = value[1];
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_Z)
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[2] = value[2];
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (writeMask & WRITEMASK_W)
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[3] = value[3];
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (inst->CondUpdate) {
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_X)
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[0] = generate_cc((float)value[0]);
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Y)
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[1] = generate_cc((float)value[1]);
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_Z)
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[2] = generate_cc((float)value[2]);
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (writeMask & WRITEMASK_W)
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         machine->CondCodes[3] = generate_cc((float)value[3]);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_PROG
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("CondCodes=(%s,%s,%s,%s) for:\n",
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[0]),
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[1]),
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[2]),
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             _mesa_condcode_string(machine->CondCodes[3]));
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Execute the given vertex/fragment program.
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ctx  rendering context
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param program  the program to execute
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param machine  machine state (must be initialized)
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_execute_program(struct gl_context * ctx,
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct gl_program *program,
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct gl_program_machine *machine)
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint numInst = program->NumInstructions;
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint maxExec = 65536;
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint pc, numExec = 0;
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   machine->CurProgram = program;
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (DEBUG_PROG) {
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("execute program %u --------------------\n", program->Id);
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (program->Target == GL_VERTEX_PROGRAM_ARB) {
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      machine->EnvParams = ctx->VertexProgram.Parameters;
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      machine->EnvParams = ctx->FragmentProgram.Parameters;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (pc = 0; pc < numInst; pc++) {
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct prog_instruction *inst = program->Instructions + pc;
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUG_PROG) {
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_print_instruction(inst);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (inst->Opcode) {
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ABS:
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = FABSF(a[0]);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = FABSF(a[1]);
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = FABSF(a[2]);
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = FABSF(a[3]);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ADD:
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] + b[0];
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] + b[1];
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] + b[2];
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] + b[3];
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_AND:     /* bitwise AND */
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint a[4], b[4], result[4];
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[0], machine, a);
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[1], machine, b);
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] & b[0];
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] & b[1];
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] & b[2];
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] & b[3];
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ARL:
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat t[4];
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, t);
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            machine->AddressReg[0][0] = IFLOOR(t[0]);
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("ARL %d\n", machine->AddressReg[0][0]);
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_BGNLOOP:
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* no-op */
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(program->Instructions[inst->BranchTarget].Opcode
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                == OPCODE_ENDLOOP);
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ENDLOOP:
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* subtract 1 here since pc is incremented by for(pc) loop */
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(program->Instructions[inst->BranchTarget].Opcode
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                == OPCODE_BGNLOOP);
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pc = inst->BranchTarget - 1;   /* go to matching BNGLOOP */
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_BGNSUB:      /* begin subroutine */
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ENDSUB:      /* end subroutine */
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_BRA:         /* branch (conditional) */
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* take branch */
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Subtract 1 here since we'll do pc++ below */
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pc = inst->BranchTarget - 1;
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_BRK:         /* break out of loop (conditional) */
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(program->Instructions[inst->BranchTarget].Opcode
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                == OPCODE_ENDLOOP);
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* break out of loop */
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* pc++ at end of for-loop will put us after the ENDLOOP inst */
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pc = inst->BranchTarget;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_CONT:        /* continue loop (conditional) */
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(program->Instructions[inst->BranchTarget].Opcode
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                == OPCODE_ENDLOOP);
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* continue at ENDLOOP */
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Subtract 1 here since we'll do pc++ at end of for-loop */
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pc = inst->BranchTarget - 1;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_CAL:         /* Call subroutine (conditional) */
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* call the subroutine */
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Subtract 1 here since we'll do pc++ at end of for-loop */
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pc = inst->BranchTarget - 1;
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_CMP:
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], c[4], result[4];
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[2], machine, c);
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] < 0.0F ? b[0] : c[0];
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] < 0.0F ? b[1] : c[1];
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] < 0.0F ? b[2] : c[2];
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] < 0.0F ? b[3] : c[3];
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%g %g %g %g) : (%g %g %g %g)\n",
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3],
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      c[0], c[1], c[2], c[3]);
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_COS:
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3]
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               = (GLfloat) cos(a[0]);
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DDX:         /* Partial derivative with respect to X */
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                'X', result);
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DDY:         /* Partial derivative with respect to Y */
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                'Y', result);
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP2:
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = DOT2(a, b);
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("DP2 %g = (%g %g) . (%g %g)\n",
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], a[0], a[1], b[0], b[1]);
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP2A:
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], c, result[4];
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[1], machine, &c);
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c;
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("DP2A %g = (%g %g) . (%g %g) + %g\n",
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], a[0], a[1], b[0], b[1], c);
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP3:
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DP4:
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], a[0], a[1], a[2], a[3],
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DPH:
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3];
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_DST:         /* Distance vector */
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = 1.0F;
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] * b[1];
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2];
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = b[3];
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_EXP:
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat t[4], q[4], floor_t0;
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, t);
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            floor_t0 = FLOORF(t[0]);
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (floor_t0 > FLT_MAX_EXP) {
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               SET_POS_INFINITY(q[0]);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               SET_POS_INFINITY(q[2]);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else if (floor_t0 < FLT_MIN_EXP) {
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               q[0] = 0.0F;
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               q[2] = 0.0F;
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               q[0] = LDEXPF(1.0, (int) floor_t0);
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Note: GL_NV_vertex_program expects
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * result.z = result.x * APPX(result.y)
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * We do what the ARB extension says.
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               q[2] = (GLfloat) pow(2.0, t[0]);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            q[1] = t[0] - floor_t0;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            q[3] = 1.0F;
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4( inst, machine, q );
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_EX2:         /* Exponential base 2 */
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4], val;
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            val = (GLfloat) pow(2.0, a[0]);
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /*
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (IS_INF_OR_NAN(val))
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               val = 1.0e10;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            */
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = val;
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_FLR:
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = FLOORF(a[0]);
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = FLOORF(a[1]);
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = FLOORF(a[2]);
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = FLOORF(a[3]);
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_FRC:
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] - FLOORF(a[0]);
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] - FLOORF(a[1]);
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] - FLOORF(a[2]);
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] - FLOORF(a[3]);
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_IF:
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLboolean cond;
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(program->Instructions[inst->BranchTarget].Opcode
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   == OPCODE_ELSE ||
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   program->Instructions[inst->BranchTarget].Opcode
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   == OPCODE_ENDIF);
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* eval condition */
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               GLfloat a[4];
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               fetch_vector1(&inst->SrcReg[0], machine, a);
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               cond = (a[0] != 0.0);
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               cond = eval_condition(machine, inst);
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("IF: %d\n", cond);
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* do if/else */
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (cond) {
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* do if-clause (just continue execution) */
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* go to the instruction after ELSE or ENDIF */
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(inst->BranchTarget >= 0);
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               pc = inst->BranchTarget;
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ELSE:
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* goto ENDIF */
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ASSERT(program->Instructions[inst->BranchTarget].Opcode
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                == OPCODE_ENDIF);
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(inst->BranchTarget >= 0);
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pc = inst->BranchTarget;
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_ENDIF:
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* nothing */
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_KIL_NV:      /* NV_f_p only (conditional) */
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return GL_FALSE;
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_KIL:         /* ARB_f_p only */
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4];
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("KIL if (%g %g %g %g) <= 0.0\n",
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3]);
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return GL_FALSE;
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LG2:         /* log base 2 */
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4], val;
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* The fast LOG2 macro doesn't meet the precision requirements.
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (a[0] == 0.0F) {
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               val = -FLT_MAX;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               val = (float)(log(a[0]) * 1.442695F);
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = val;
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LIT:
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLfloat epsilon = 1.0F / 256.0F;      /* from NV VP spec */
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[0] = MAX2(a[0], 0.0F);
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[1] = MAX2(a[1], 0.0F);
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* XXX ARB version clamps a[3], NV version doesn't */
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = 1.0F;
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[0];
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* XXX we could probably just use pow() here */
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (a[0] > 0.0F) {
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (a[1] == 0.0 && a[3] == 0.0)
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[2] = 1.0F;
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[2] = (GLfloat) pow(a[1], a[3]);
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[2] = 0.0F;
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = 1.0F;
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3]);
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LOG:
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat t[4], q[4], abs_t0;
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, t);
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            abs_t0 = FABSF(t[0]);
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (abs_t0 != 0.0F) {
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Since we really can't handle infinite values on VMS
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * like other OSes we'll use __MAXFLOAT to represent
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * infinity.  This may need some tweaking.
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef VMS
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (abs_t0 == __MAXFLOAT)
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (IS_INF_OR_NAN(abs_t0))
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               {
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  SET_POS_INFINITY(q[0]);
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  q[1] = 1.0F;
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  SET_POS_INFINITY(q[2]);
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else {
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  int exponent;
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLfloat mantissa = FREXPF(t[0], &exponent);
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  q[0] = (GLfloat) (exponent - 1);
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  /* The fast LOG2 macro doesn't meet the precision
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   * requirements.
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   */
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  q[2] = (float)(log(t[0]) * 1.442695F);
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               SET_NEG_INFINITY(q[0]);
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               q[1] = 1.0F;
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               SET_NEG_INFINITY(q[2]);
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            q[3] = 1.0;
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, q);
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_LRP:
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], c[4], result[4];
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[2], machine, c);
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("LRP (%g %g %g %g) = (%g %g %g %g), "
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      "(%g %g %g %g), (%g %g %g %g)\n",
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MAD:
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], c[4], result[4];
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[2], machine, c);
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] * b[0] + c[0];
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] * b[1] + c[1];
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] * b[2] + c[2];
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] * b[3] + c[3];
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      "(%g %g %g %g) + (%g %g %g %g)\n",
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MAX:
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = MAX2(a[0], b[0]);
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = MAX2(a[1], b[1]);
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = MAX2(a[2], b[2]);
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = MAX2(a[3], b[3]);
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MIN:
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = MIN2(a[0], b[0]);
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = MIN2(a[1], b[1]);
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = MIN2(a[2], b[2]);
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = MIN2(a[3], b[3]);
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MOV:
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, result);
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("MOV (%g %g %g %g)\n",
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3]);
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_MUL:
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] * b[0];
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] * b[1];
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] * b[2];
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] * b[3];
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOISE1:
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[1] =
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[2] =
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[3] = _mesa_noise1(a[0]);
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOISE2:
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[1] =
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[2] = result[3] = _mesa_noise2(a[0], a[1]);
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOISE3:
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[1] =
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[2] =
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[3] = _mesa_noise3(a[0], a[1], a[2]);
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOISE4:
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[1] =
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[2] =
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]);
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOP:
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NOT:         /* bitwise NOT */
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint a[4], result[4];
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[0], machine, a);
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = ~a[0];
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = ~a[1];
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = ~a[2];
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = ~a[3];
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NRM3:        /* 3-component normalization */
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat tmp;
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (tmp != 0.0F)
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               tmp = INV_SQRTF(tmp);
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = tmp * a[0];
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = tmp * a[1];
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = tmp * a[2];
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = 0.0;  /* undefined, but prevent valgrind warnings */
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_NRM4:        /* 4-component normalization */
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat tmp;
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (tmp != 0.0F)
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               tmp = INV_SQRTF(tmp);
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = tmp * a[0];
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = tmp * a[1];
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = tmp * a[2];
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = tmp * a[3];
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_OR:          /* bitwise OR */
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint a[4], b[4], result[4];
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[0], machine, a);
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[1], machine, b);
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] | b[0];
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] | b[1];
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] | b[2];
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] | b[3];
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_PK2H:        /* pack two 16-bit floats in one 32-bit float */
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4];
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint result[4];
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLhalfNV hx, hy;
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            hx = _mesa_float_to_half(a[0]);
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            hy = _mesa_float_to_half(a[1]);
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] =
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] =
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = hx | (hy << 16);
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_PK2US:       /* pack two GLushorts into one 32-bit float */
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4];
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint result[4], usx, usy;
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[0] = CLAMP(a[0], 0.0F, 1.0F);
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[1] = CLAMP(a[1], 0.0F, 1.0F);
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            usx = F_TO_I(a[0] * 65535.0F);
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            usy = F_TO_I(a[1] * 65535.0F);
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] =
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] =
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = usx | (usy << 16);
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_PK4B:        /* pack four GLbytes into one 32-bit float */
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4];
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint result[4], ubx, uby, ubz, ubw;
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubx = F_TO_I(127.0F * a[0] + 128.0F);
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            uby = F_TO_I(127.0F * a[1] + 128.0F);
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubz = F_TO_I(127.0F * a[2] + 128.0F);
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubw = F_TO_I(127.0F * a[3] + 128.0F);
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] =
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] =
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_PK4UB:       /* pack four GLubytes into one 32-bit float */
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4];
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint result[4], ubx, uby, ubz, ubw;
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[0] = CLAMP(a[0], 0.0F, 1.0F);
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[1] = CLAMP(a[1], 0.0F, 1.0F);
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[2] = CLAMP(a[2], 0.0F, 1.0F);
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[3] = CLAMP(a[3], 0.0F, 1.0F);
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubx = F_TO_I(255.0F * a[0]);
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            uby = F_TO_I(255.0F * a[1]);
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubz = F_TO_I(255.0F * a[2]);
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ubw = F_TO_I(255.0F * a[3]);
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] =
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] =
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] =
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_POW:
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[1], machine, b);
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3]
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               = (GLfloat) pow(a[0], b[0]);
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RCC:  /* clamped riciprocal */
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const float largest = 1.884467e+19, smallest = 5.42101e-20;
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], r, result[4];
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (a[0] == 0)
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  printf("RCC(0)\n");
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (IS_INF_OR_NAN(a[0]))
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  printf("RCC(inf)\n");
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (a[0] == 1.0F) {
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               r = 1.0F;
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               r = 1.0F / a[0];
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (positive(r)) {
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (r > largest) {
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  r = largest;
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (r < smallest) {
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  r = smallest;
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (r < -largest) {
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  r = -largest;
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (r > -smallest) {
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  r = -smallest;
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = r;
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RCP:
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (a[0] == 0)
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  printf("RCP(0)\n");
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (IS_INF_OR_NAN(a[0]))
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  printf("RCP(inf)\n");
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RET:         /* return from subroutine (conditional) */
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (eval_condition(machine, inst)) {
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (machine->StackDepth == 0) {
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* subtract one because of pc++ in the for loop */
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pc = machine->CallStack[--machine->StackDepth] - 1;
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RFL:         /* reflection vector */
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, axis);
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, dir);
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmpW = DOT3(axis, axis);
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = tmpX * axis[0] - dir[0];
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = tmpX * axis[1] - dir[1];
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = tmpX * axis[2] - dir[2];
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* result[3] is never written! XXX enforce in parser! */
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_RSQ:         /* 1 / sqrt() */
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a[0] = FABSF(a[0]);
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SCS:         /* sine and cos */
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (GLfloat) cos(a[0]);
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (GLfloat) sin(a[0]);
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = 0.0;    /* undefined! */
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = 0.0;    /* undefined! */
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SEQ:         /* set on equal */
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SFL:         /* set false, operands ignored */
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SGE:         /* set on greater or equal */
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SGT:         /* set on greater */
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SIN:
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector1(&inst->SrcReg[0], machine, a);
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[1] = result[2] = result[3]
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               = (GLfloat) sin(a[0]);
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SLE:         /* set on less or equal */
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SLT:         /* set on less */
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SNE:         /* set on not equal */
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3],
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      b[0], b[1], b[2], b[3]);
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SSG:         /* set sign (-1, 0 or +1) */
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F));
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F));
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F));
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F));
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_STR:         /* set true, operands ignored */
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SUB:
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] - b[0];
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] - b[1];
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] - b[2];
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] - b[3];
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_SWZ:         /* extended swizzle */
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct prog_src_register *source = &inst->SrcReg[0];
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLfloat *src = get_src_register_pointer(source, machine);
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint i;
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (i = 0; i < 4; i++) {
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const GLuint swz = GET_SWZ(source->Swizzle, i);
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (swz == SWIZZLE_ZERO)
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[i] = 0.0;
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (swz == SWIZZLE_ONE)
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[i] = 1.0;
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else {
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ASSERT(swz >= 0);
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ASSERT(swz <= 3);
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[i] = src[swz];
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (source->Negate & (1 << i))
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  result[i] = -result[i];
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TEX:         /* Both ARB and NV frag prog */
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Simple texel lookup */
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], color[4];
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* For TEX, texcoord.Q should not be used and its value should not
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * matter (at most, we pass coord.xyz to texture3D() in GLSL).
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * Set Q=1 so that FetchTexelDeriv() doesn't get a garbage value
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * which is effectively what happens when the texcoord swizzle
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * is .xyzz
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            texcoord[3] = 1.0f;
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n",
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      color[0], color[1], color[2], color[3],
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst->TexSrcUnit,
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      texcoord[0], texcoord[1], texcoord[2], texcoord[3]);
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXB:         /* GL_ARB_fragment_program only */
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Texel lookup with LOD bias */
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], color[4], lodBias;
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* texcoord[3] is the bias to add to lambda */
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lodBias = texcoord[3];
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("TXB (%g, %g, %g, %g) = texture[%d][%g %g %g %g]"
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      "  bias %g\n",
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      color[0], color[1], color[2], color[3],
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst->TexSrcUnit,
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      texcoord[0],
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      texcoord[1],
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      texcoord[2],
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      texcoord[3],
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      lodBias);
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXD:         /* GL_NV_fragment_program only */
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Texture lookup w/ partial derivatives for LOD */
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, dtdx);
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[2], machine, dtdy);
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     0.0, /* lodBias */
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     inst->TexSrcUnit, color);
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXL:
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Texel lookup with explicit LOD */
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], color[4], lod;
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* texcoord[3] is the LOD */
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lod = texcoord[3];
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    machine->FetchTexelLod(ctx, texcoord, lod,
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   machine->Samplers[inst->TexSrcUnit], color);
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXP:         /* GL_ARB_fragment_program only */
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Texture lookup w/ projective divide */
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], color[4];
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Not so sure about this test - if texcoord[3] is
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * zero, we'd probably be fine except for an ASSERT in
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * IROUND_POS() which gets triggered by the inf values created.
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (texcoord[3] != 0.0) {
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[0] /= texcoord[3];
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[1] /= texcoord[3];
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[2] /= texcoord[3];
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TXP_NV:      /* GL_NV_fragment_program only */
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Texture lookup w/ projective divide, as above, but do not
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * do the divide by w if sampling from a cube map.
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat texcoord[4], color[4];
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                texcoord[3] != 0.0) {
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[0] /= texcoord[3];
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[1] /= texcoord[3];
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               texcoord[2] /= texcoord[3];
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, color);
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_TRUNC:       /* truncate toward zero */
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], result[4];
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (GLfloat) (GLint) a[0];
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (GLfloat) (GLint) a[1];
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (GLfloat) (GLint) a[2];
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (GLfloat) (GLint) a[3];
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_UP2H:        /* unpack two 16-bit floats */
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLushort hx, hy;
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            hx = raw & 0xffff;
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            hy = raw >> 16;
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[2] = _mesa_half_to_float(hx);
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = result[3] = _mesa_half_to_float(hy);
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_UP2US:       /* unpack two GLushorts */
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLushort usx, usy;
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            usx = raw & 0xffff;
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            usy = raw >> 16;
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = result[2] = usx * (1.0f / 65535.0f);
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = result[3] = usy * (1.0f / 65535.0f);
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_UP4B:        /* unpack four GLbytes */
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F;
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F;
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F;
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F;
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_UP4UB:       /* unpack four GLubytes */
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat result[4];
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = ((raw >> 0) & 0xff) / 255.0F;
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = ((raw >> 8) & 0xff) / 255.0F;
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = ((raw >> 16) & 0xff) / 255.0F;
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = ((raw >> 24) & 0xff) / 255.0F;
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_XOR:         /* bitwise XOR */
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLuint a[4], b[4], result[4];
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[0], machine, a);
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4ui(&inst->SrcReg[1], machine, b);
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] ^ b[0];
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] ^ b[1];
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] ^ b[2];
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] ^ b[3];
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4ui(inst, machine, result);
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_XPD:         /* cross product */
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], result[4];
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[1] * b[2] - a[2] * b[1];
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[2] * b[0] - a[0] * b[2];
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[0] * b[1] - a[1] * b[0];
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = 1.0;
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (DEBUG_PROG) {
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      result[0], result[1], result[2], result[3],
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      a[0], a[1], a[2], b[0], b[1], b[2]);
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_X2D:         /* 2-D matrix transform */
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat a[4], b[4], c[4], result[4];
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[0], machine, a);
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[1], machine, b);
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fetch_vector4(&inst->SrcReg[2], machine, c);
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            store_vector4(inst, machine, result);
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_PRINT:
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               GLfloat a[4];
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               fetch_vector4(&inst->SrcReg[0], machine, a);
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            a[0], a[1], a[2], a[3]);
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               printf("%s\n", (const char *) inst->Data);
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_END:
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_TRUE;
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program",
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       inst->Opcode);
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_TRUE;        /* return value doesn't matter */
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numExec++;
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (numExec > maxExec) {
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 static GLboolean reported = GL_FALSE;
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!reported) {
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_problem(ctx, "Infinite loop detected in fragment program");
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    reported = GL_TRUE;
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return GL_TRUE;
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } /* for pc */
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1904