100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian/*
200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Mesa 3-D graphics library
38f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul * Version:  7.3
400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian *
58f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
68f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul * Copyright (C) 1999-2009  VMware, Inc.  All Rights Reserved.
700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian *
800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Permission is hereby granted, free of charge, to any person obtaining a
900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * copy of this software and associated documentation files (the "Software"),
1000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * to deal in the Software without restriction, including without limitation
1100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * and/or sell copies of the Software, and to permit persons to whom the
1300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Software is furnished to do so, subject to the following conditions:
1400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian *
1500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * The above copyright notice and this permission notice shall be included
1600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * in all copies or substantial portions of the Software.
1700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian *
1800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian */
2500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
2600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/mtypes.h"
3000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian#include "prog_instruction.h"
3100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
3200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
3300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian/**
3400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Initialize program instruction fields to defaults.
3500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param inst  first instruction to initialize
3600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param count  number of instructions to initialize
3700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian */
3800cdc0a472c55330cbc58317f01b07f8f90be5a5Brianvoid
3900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
4000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian{
4100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   GLuint i;
4200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
436bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(inst, 0, count * sizeof(struct prog_instruction));
4400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
4500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   for (i = 0; i < count; i++) {
4600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
4700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
4800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
4900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
5000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
5100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
5200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
5300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].DstReg.File = PROGRAM_UNDEFINED;
5400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
5500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].DstReg.CondMask = COND_TR;
5600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
5700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
5800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].SaturateMode = SATURATE_OFF;
5900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      inst[i].Precision = FLOAT32;
6000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   }
6100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian}
6200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
6300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
6400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian/**
6500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Allocate an array of program instructions.
6600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param numInst  number of instructions
6700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \return pointer to instruction memory
6800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian */
6900cdc0a472c55330cbc58317f01b07f8f90be5a5Brianstruct prog_instruction *
7000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian_mesa_alloc_instructions(GLuint numInst)
7100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian{
7200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   return (struct prog_instruction *)
7332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      calloc(1, numInst * sizeof(struct prog_instruction));
7400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian}
7500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
7600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
7700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian/**
7800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * Reallocate memory storing an array of program instructions.
7900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * This is used when we need to append additional instructions onto an
8000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * program.
8100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param oldInst  pointer to first of old/src instructions
8200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param numOldInst  number of instructions at <oldInst>
8300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \param numNewInst  desired size of new instruction array.
8400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian * \return  pointer to start of new instruction array.
8500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian */
8600cdc0a472c55330cbc58317f01b07f8f90be5a5Brianstruct prog_instruction *
8700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian_mesa_realloc_instructions(struct prog_instruction *oldInst,
8800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian                           GLuint numOldInst, GLuint numNewInst)
8900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian{
9000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   struct prog_instruction *newInst;
9100cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
9200cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   newInst = (struct prog_instruction *)
9300cdc0a472c55330cbc58317f01b07f8f90be5a5Brian      _mesa_realloc(oldInst,
9400cdc0a472c55330cbc58317f01b07f8f90be5a5Brian                    numOldInst * sizeof(struct prog_instruction),
9500cdc0a472c55330cbc58317f01b07f8f90be5a5Brian                    numNewInst * sizeof(struct prog_instruction));
9600cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
9700cdc0a472c55330cbc58317f01b07f8f90be5a5Brian   return newInst;
9800cdc0a472c55330cbc58317f01b07f8f90be5a5Brian}
9900cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
10000cdc0a472c55330cbc58317f01b07f8f90be5a5Brian
10123d31efc167f09d47635352f697ffcb087d3ebbdBrian/**
10223d31efc167f09d47635352f697ffcb087d3ebbdBrian * Copy an array of program instructions.
10323d31efc167f09d47635352f697ffcb087d3ebbdBrian * \param dest  pointer to destination.
10423d31efc167f09d47635352f697ffcb087d3ebbdBrian * \param src  pointer to source.
10523d31efc167f09d47635352f697ffcb087d3ebbdBrian * \param n  number of instructions to copy.
10623d31efc167f09d47635352f697ffcb087d3ebbdBrian * \return pointer to destination.
10723d31efc167f09d47635352f697ffcb087d3ebbdBrian */
10823d31efc167f09d47635352f697ffcb087d3ebbdBrianstruct prog_instruction *
10923d31efc167f09d47635352f697ffcb087d3ebbdBrian_mesa_copy_instructions(struct prog_instruction *dest,
11023d31efc167f09d47635352f697ffcb087d3ebbdBrian                        const struct prog_instruction *src, GLuint n)
11123d31efc167f09d47635352f697ffcb087d3ebbdBrian{
1124cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian   GLuint i;
113c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(dest, src, n * sizeof(struct prog_instruction));
1144cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian   for (i = 0; i < n; i++) {
1154cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian      if (src[i].Comment)
1164cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian         dest[i].Comment = _mesa_strdup(src[i].Comment);
1174cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian   }
1184cc2674aee98a4c2972f4f097a89b7b4a30df4abBrian   return dest;
11923d31efc167f09d47635352f697ffcb087d3ebbdBrian}
12023d31efc167f09d47635352f697ffcb087d3ebbdBrian
121464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
122464b82b1e690b5ab690bd1673251e5b4edf69a62Brian/**
123450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul * Free an array of instructions
124450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul */
125450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paulvoid
126450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
127450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul{
128450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul   GLuint i;
129450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul   for (i = 0; i < count; i++) {
130450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul      if (inst[i].Data)
13132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg         free(inst[i].Data);
132450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul      if (inst[i].Comment)
13332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg         free((char *) inst[i].Comment);
134450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul   }
13532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(inst);
136450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul}
137450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul
138450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul
139450136d368ce7a08cf25992c79b51f51f8a9bb7cBrian Paul/**
140464b82b1e690b5ab690bd1673251e5b4edf69a62Brian * Basic info about each instruction
141464b82b1e690b5ab690bd1673251e5b4edf69a62Brian */
142464b82b1e690b5ab690bd1673251e5b4edf69a62Brianstruct instruction_info
143464b82b1e690b5ab690bd1673251e5b4edf69a62Brian{
144464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   gl_inst_opcode Opcode;
145464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   const char *Name;
146464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   GLuint NumSrcRegs;
147bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   GLuint NumDstRegs;
148464b82b1e690b5ab690bd1673251e5b4edf69a62Brian};
149464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
150464b82b1e690b5ab690bd1673251e5b4edf69a62Brian/**
151464b82b1e690b5ab690bd1673251e5b4edf69a62Brian * Instruction info
152464b82b1e690b5ab690bd1673251e5b4edf69a62Brian * \note Opcode should equal array index!
153464b82b1e690b5ab690bd1673251e5b4edf69a62Brian */
154464b82b1e690b5ab690bd1673251e5b4edf69a62Brianstatic const struct instruction_info InstInfo[MAX_OPCODE] = {
155bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_NOP,    "NOP",     0, 0 },
156bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ABS,    "ABS",     1, 1 },
157bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ADD,    "ADD",     2, 1 },
15837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul   { OPCODE_AND,    "AND",     2, 1 },
159bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ARA,    "ARA",     1, 1 },
160bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ARL,    "ARL",     1, 1 },
1618f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul   { OPCODE_ARL_NV, "ARL_NV",  1, 1 },
162bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ARR,    "ARL",     1, 1 },
163bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
164bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_BGNSUB, "BGNSUB",  0, 0 },
165bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_BRA,    "BRA",     0, 0 },
166bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_BRK,    "BRK",     0, 0 },
167bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_CAL,    "CAL",     0, 0 },
168bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_CMP,    "CMP",     3, 1 },
169bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_CONT,   "CONT",    0, 0 },
170bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_COS,    "COS",     1, 1 },
171bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DDX,    "DDX",     1, 1 },
172bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DDY,    "DDY",     1, 1 },
17365cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul   { OPCODE_DP2,    "DP2",     2, 1 },
17465cb74ecc0287d766493fd3649295e2e1b20099bBrian Paul   { OPCODE_DP2A,   "DP2A",    3, 1 },
175bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DP3,    "DP3",     2, 1 },
176bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DP4,    "DP4",     2, 1 },
177bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DPH,    "DPH",     2, 1 },
178bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_DST,    "DST",     2, 1 },
179bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ELSE,   "ELSE",    0, 0 },
180da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   { OPCODE_EMIT_VERTEX,   "EMIT_VERTEX",    0, 0 },
181bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_END,    "END",     0, 0 },
182da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   { OPCODE_END_PRIMITIVE,    "END_PRIMITIVE",     0, 0 },
183bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ENDIF,  "ENDIF",   0, 0 },
184bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
185bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_ENDSUB, "ENDSUB",  0, 0 },
186bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_EX2,    "EX2",     1, 1 },
187bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_EXP,    "EXP",     1, 1 },
188bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_FLR,    "FLR",     1, 1 },
189bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_FRC,    "FRC",     1, 1 },
190bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_IF,     "IF",      1, 0 },
191bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_KIL,    "KIL",     1, 0 },
1928f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul   { OPCODE_KIL_NV, "KIL_NV",  0, 0 },
193bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_LG2,    "LG2",     1, 1 },
194bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_LIT,    "LIT",     1, 1 },
195bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_LOG,    "LOG",     1, 1 },
196bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_LRP,    "LRP",     3, 1 },
197bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_MAD,    "MAD",     3, 1 },
198bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_MAX,    "MAX",     2, 1 },
199bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_MIN,    "MIN",     2, 1 },
200bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_MOV,    "MOV",     1, 1 },
201bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_MUL,    "MUL",     2, 1 },
202bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_NOISE1, "NOISE1",  1, 1 },
203bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_NOISE2, "NOISE2",  1, 1 },
204bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_NOISE3, "NOISE3",  1, 1 },
205bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_NOISE4, "NOISE4",  1, 1 },
2066dc91b8371f04f9bab61c1f6504236264feac8b4Brian Paul   { OPCODE_NOT,    "NOT",     1, 1 },
207f6ead50827c03017e6b730313c361b39190da92fBrian Paul   { OPCODE_NRM3,   "NRM3",    1, 1 },
208f6ead50827c03017e6b730313c361b39190da92fBrian Paul   { OPCODE_NRM4,   "NRM4",    1, 1 },
2096dc91b8371f04f9bab61c1f6504236264feac8b4Brian Paul   { OPCODE_OR,     "OR",      2, 1 },
210bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PK2H,   "PK2H",    1, 1 },
211bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PK2US,  "PK2US",   1, 1 },
212bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PK4B,   "PK4B",    1, 1 },
213bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PK4UB,  "PK4UB",   1, 1 },
214bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_POW,    "POW",     2, 1 },
215bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_POPA,   "POPA",    0, 0 },
216bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PRINT,  "PRINT",   1, 0 },
217bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_PUSHA,  "PUSHA",   0, 0 },
218bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_RCC,    "RCC",     1, 1 },
219bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_RCP,    "RCP",     1, 1 },
220bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_RET,    "RET",     0, 0 },
221bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_RFL,    "RFL",     1, 1 },
222bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_RSQ,    "RSQ",     1, 1 },
223bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SCS,    "SCS",     1, 1 },
224bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SEQ,    "SEQ",     2, 1 },
225bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SFL,    "SFL",     0, 1 },
226bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SGE,    "SGE",     2, 1 },
227bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SGT,    "SGT",     2, 1 },
228bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SIN,    "SIN",     1, 1 },
229bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SLE,    "SLE",     2, 1 },
230bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SLT,    "SLT",     2, 1 },
231bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SNE,    "SNE",     2, 1 },
232bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SSG,    "SSG",     1, 1 },
233bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_STR,    "STR",     0, 1 },
234bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SUB,    "SUB",     2, 1 },
235bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_SWZ,    "SWZ",     1, 1 },
236bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_TEX,    "TEX",     1, 1 },
237bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_TXB,    "TXB",     1, 1 },
238bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_TXD,    "TXD",     3, 1 },
239bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_TXL,    "TXL",     1, 1 },
240bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_TXP,    "TXP",     1, 1 },
2418f7349dbb46e1ec6d8194a42753e83c1913944bcBrian Paul   { OPCODE_TXP_NV, "TXP_NV",  1, 1 },
242035c0cf71a5fe3beee55654e1f7148adfe626cc0Brian Paul   { OPCODE_TRUNC,  "TRUNC",   1, 1 },
243bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_UP2H,   "UP2H",    1, 1 },
244bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_UP2US,  "UP2US",   1, 1 },
245bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_UP4B,   "UP4B",    1, 1 },
246bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_UP4UB,  "UP4UB",   1, 1 },
247bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_X2D,    "X2D",     3, 1 },
24837eef7b474c5d9a7c566f9edf35c797c5a98d065Brian Paul   { OPCODE_XOR,    "XOR",     2, 1 },
249bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   { OPCODE_XPD,    "XPD",     2, 1 }
250464b82b1e690b5ab690bd1673251e5b4edf69a62Brian};
251464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
252464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
253464b82b1e690b5ab690bd1673251e5b4edf69a62Brian/**
254464b82b1e690b5ab690bd1673251e5b4edf69a62Brian * Return the number of src registers for the given instruction/opcode.
255464b82b1e690b5ab690bd1673251e5b4edf69a62Brian */
256464b82b1e690b5ab690bd1673251e5b4edf69a62BrianGLuint
257464b82b1e690b5ab690bd1673251e5b4edf69a62Brian_mesa_num_inst_src_regs(gl_inst_opcode opcode)
258464b82b1e690b5ab690bd1673251e5b4edf69a62Brian{
259be8c0b25eaf67b7deefe7844d0b8ed19abad8d86Brian Paul   ASSERT(opcode < MAX_OPCODE);
260464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   ASSERT(opcode == InstInfo[opcode].Opcode);
261464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
262464b82b1e690b5ab690bd1673251e5b4edf69a62Brian   return InstInfo[opcode].NumSrcRegs;
263464b82b1e690b5ab690bd1673251e5b4edf69a62Brian}
264464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
265464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
266464b82b1e690b5ab690bd1673251e5b4edf69a62Brian/**
267bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul * Return the number of dst registers for the given instruction/opcode.
268bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul */
269bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian PaulGLuint
270bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
271bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul{
272be8c0b25eaf67b7deefe7844d0b8ed19abad8d86Brian Paul   ASSERT(opcode < MAX_OPCODE);
273bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   ASSERT(opcode == InstInfo[opcode].Opcode);
274bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
275bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   return InstInfo[opcode].NumDstRegs;
276bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul}
277bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul
278bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul
279bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian PaulGLboolean
280bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul_mesa_is_tex_instruction(gl_inst_opcode opcode)
281bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul{
282bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul   return (opcode == OPCODE_TEX ||
283bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul           opcode == OPCODE_TXB ||
284bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul           opcode == OPCODE_TXD ||
285bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul           opcode == OPCODE_TXL ||
286bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul           opcode == OPCODE_TXP);
287bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul}
288bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul
289bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul
290bff695b926249ead1944eef2aa05b2e0eaf9ba7fBrian Paul/**
2910e85dcb66b990a63d60032816798ff693f9248e7Brian Paul * Check if there's a potential src/dst register data dependency when
2920e85dcb66b990a63d60032816798ff693f9248e7Brian Paul * using SOA execution.
2930e85dcb66b990a63d60032816798ff693f9248e7Brian Paul * Example:
2940e85dcb66b990a63d60032816798ff693f9248e7Brian Paul *   MOV T, T.yxwz;
2950e85dcb66b990a63d60032816798ff693f9248e7Brian Paul * This would expand into:
2960e85dcb66b990a63d60032816798ff693f9248e7Brian Paul *   MOV t0, t1;
2970e85dcb66b990a63d60032816798ff693f9248e7Brian Paul *   MOV t1, t0;
2980e85dcb66b990a63d60032816798ff693f9248e7Brian Paul *   MOV t2, t3;
2990e85dcb66b990a63d60032816798ff693f9248e7Brian Paul *   MOV t3, t2;
3000e85dcb66b990a63d60032816798ff693f9248e7Brian Paul * The second instruction will have the wrong value for t0 if executed as-is.
3010e85dcb66b990a63d60032816798ff693f9248e7Brian Paul */
3020e85dcb66b990a63d60032816798ff693f9248e7Brian PaulGLboolean
3030e85dcb66b990a63d60032816798ff693f9248e7Brian Paul_mesa_check_soa_dependencies(const struct prog_instruction *inst)
3040e85dcb66b990a63d60032816798ff693f9248e7Brian Paul{
3050e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   GLuint i, chan;
3060e85dcb66b990a63d60032816798ff693f9248e7Brian Paul
3070e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   if (inst->DstReg.WriteMask == WRITEMASK_X ||
3080e85dcb66b990a63d60032816798ff693f9248e7Brian Paul       inst->DstReg.WriteMask == WRITEMASK_Y ||
3090e85dcb66b990a63d60032816798ff693f9248e7Brian Paul       inst->DstReg.WriteMask == WRITEMASK_Z ||
3100e85dcb66b990a63d60032816798ff693f9248e7Brian Paul       inst->DstReg.WriteMask == WRITEMASK_W ||
3110e85dcb66b990a63d60032816798ff693f9248e7Brian Paul       inst->DstReg.WriteMask == 0x0) {
3120e85dcb66b990a63d60032816798ff693f9248e7Brian Paul      /* no chance of data dependency */
3130e85dcb66b990a63d60032816798ff693f9248e7Brian Paul      return GL_FALSE;
3140e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   }
3150e85dcb66b990a63d60032816798ff693f9248e7Brian Paul
3160e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   /* loop over src regs */
3170e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   for (i = 0; i < 3; i++) {
3180e85dcb66b990a63d60032816798ff693f9248e7Brian Paul      if (inst->SrcReg[i].File == inst->DstReg.File &&
3190e85dcb66b990a63d60032816798ff693f9248e7Brian Paul          inst->SrcReg[i].Index == inst->DstReg.Index) {
3200e85dcb66b990a63d60032816798ff693f9248e7Brian Paul         /* loop over dest channels */
3210e85dcb66b990a63d60032816798ff693f9248e7Brian Paul         GLuint channelsWritten = 0x0;
3220e85dcb66b990a63d60032816798ff693f9248e7Brian Paul         for (chan = 0; chan < 4; chan++) {
3230e85dcb66b990a63d60032816798ff693f9248e7Brian Paul            if (inst->DstReg.WriteMask & (1 << chan)) {
3240e85dcb66b990a63d60032816798ff693f9248e7Brian Paul               /* check if we're reading a channel that's been written */
3250e85dcb66b990a63d60032816798ff693f9248e7Brian Paul               GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
3260e85dcb66b990a63d60032816798ff693f9248e7Brian Paul               if (swizzle <= SWIZZLE_W &&
3270e85dcb66b990a63d60032816798ff693f9248e7Brian Paul                   (channelsWritten & (1 << swizzle))) {
3280e85dcb66b990a63d60032816798ff693f9248e7Brian Paul                  return GL_TRUE;
3290e85dcb66b990a63d60032816798ff693f9248e7Brian Paul               }
3300e85dcb66b990a63d60032816798ff693f9248e7Brian Paul
3310e85dcb66b990a63d60032816798ff693f9248e7Brian Paul               channelsWritten |= (1 << chan);
3320e85dcb66b990a63d60032816798ff693f9248e7Brian Paul            }
3330e85dcb66b990a63d60032816798ff693f9248e7Brian Paul         }
3340e85dcb66b990a63d60032816798ff693f9248e7Brian Paul      }
3350e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   }
3360e85dcb66b990a63d60032816798ff693f9248e7Brian Paul   return GL_FALSE;
3370e85dcb66b990a63d60032816798ff693f9248e7Brian Paul}
3380e85dcb66b990a63d60032816798ff693f9248e7Brian Paul
3390e85dcb66b990a63d60032816798ff693f9248e7Brian Paul
3400e85dcb66b990a63d60032816798ff693f9248e7Brian Paul/**
341464b82b1e690b5ab690bd1673251e5b4edf69a62Brian * Return string name for given program opcode.
342464b82b1e690b5ab690bd1673251e5b4edf69a62Brian */
343464b82b1e690b5ab690bd1673251e5b4edf69a62Brianconst char *
344464b82b1e690b5ab690bd1673251e5b4edf69a62Brian_mesa_opcode_string(gl_inst_opcode opcode)
345464b82b1e690b5ab690bd1673251e5b4edf69a62Brian{
3465c5d78e1918fedb6fd43f5fafdba2a142a09d56fBrian Paul   if (opcode < MAX_OPCODE)
3475c5d78e1918fedb6fd43f5fafdba2a142a09d56fBrian Paul      return InstInfo[opcode].Name;
3487c2fe42dedcd9f437f2b3fae92963d4c4c56fe03Brian Paul   else {
3497c2fe42dedcd9f437f2b3fae92963d4c4c56fe03Brian Paul      static char s[20];
35078a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul      _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
3517c2fe42dedcd9f437f2b3fae92963d4c4c56fe03Brian Paul      return s;
3527c2fe42dedcd9f437f2b3fae92963d4c4c56fe03Brian Paul   }
353464b82b1e690b5ab690bd1673251e5b4edf69a62Brian}
354464b82b1e690b5ab690bd1673251e5b4edf69a62Brian
355