13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/*
23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Mesa 3-D graphics library
33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Version:  7.3
43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright (C) 1999-2009  VMware, Inc.  All Rights Reserved.
73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * copy of this software and associated documentation files (the "Software"),
103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * to deal in the Software without restriction, including without limitation
113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Software is furnished to do so, subject to the following conditions:
143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The above copyright notice and this permission notice shall be included
163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * in all copies or substantial portions of the Software.
173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "main/glheader.h"
283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "main/imports.h"
293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "main/mtypes.h"
303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "prog_instruction.h"
313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Initialize program instruction fields to defaults.
353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param inst  first instruction to initialize
363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param count  number of instructions to initialize
373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid
393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint i;
423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
43760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   memset(inst, 0, count * sizeof(struct prog_instruction));
443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < count; i++) {
463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].DstReg.File = PROGRAM_UNDEFINED;
543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].DstReg.CondMask = COND_TR;
563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].SaturateMode = SATURATE_OFF;
593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      inst[i].Precision = FLOAT32;
603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Allocate an array of program instructions.
663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param numInst  number of instructions
673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \return pointer to instruction memory
683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct prog_instruction *
703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_alloc_instructions(GLuint numInst)
713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return (struct prog_instruction *)
73760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      calloc(1, numInst * sizeof(struct prog_instruction));
743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Reallocate memory storing an array of program instructions.
793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * This is used when we need to append additional instructions onto an
803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * program.
813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param oldInst  pointer to first of old/src instructions
823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param numOldInst  number of instructions at <oldInst>
833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param numNewInst  desired size of new instruction array.
843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \return  pointer to start of new instruction array.
853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct prog_instruction *
873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_realloc_instructions(struct prog_instruction *oldInst,
883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                           GLuint numOldInst, GLuint numNewInst)
893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct prog_instruction *newInst;
913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   newInst = (struct prog_instruction *)
933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      _mesa_realloc(oldInst,
943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                    numOldInst * sizeof(struct prog_instruction),
953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                    numNewInst * sizeof(struct prog_instruction));
963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return newInst;
983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copy an array of program instructions.
1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param dest  pointer to destination.
1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param src  pointer to source.
1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \param n  number of instructions to copy.
1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \return pointer to destination.
1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct prog_instruction *
1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_copy_instructions(struct prog_instruction *dest,
1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                        const struct prog_instruction *src, GLuint n)
1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint i;
113760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   memcpy(dest, src, n * sizeof(struct prog_instruction));
1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < n; i++) {
1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (src[i].Comment)
1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         dest[i].Comment = _mesa_strdup(src[i].Comment);
1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return dest;
1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Free an array of instructions
1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid
1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint i;
1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < count; i++) {
1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (inst[i].Data)
131760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         free(inst[i].Data);
1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (inst[i].Comment)
133760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org         free((char *) inst[i].Comment);
1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
135760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   free(inst);
1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Basic info about each instruction
1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct instruction_info
1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   gl_inst_opcode Opcode;
1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   const char *Name;
1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint NumSrcRegs;
1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint NumDstRegs;
1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org};
1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Instruction info
1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * \note Opcode should equal array index!
1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic const struct instruction_info InstInfo[MAX_OPCODE] = {
1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOP,    "NOP",     0, 0 },
1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ABS,    "ABS",     1, 1 },
1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ADD,    "ADD",     2, 1 },
1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_AND,    "AND",     2, 1 },
1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ARA,    "ARA",     1, 1 },
1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ARL,    "ARL",     1, 1 },
1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ARL_NV, "ARL_NV",  1, 1 },
1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ARR,    "ARL",     1, 1 },
1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_BGNSUB, "BGNSUB",  0, 0 },
1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_BRA,    "BRA",     0, 0 },
1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_BRK,    "BRK",     0, 0 },
1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_CAL,    "CAL",     0, 0 },
1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_CMP,    "CMP",     3, 1 },
1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_CONT,   "CONT",    0, 0 },
1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_COS,    "COS",     1, 1 },
1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DDX,    "DDX",     1, 1 },
1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DDY,    "DDY",     1, 1 },
1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DP2,    "DP2",     2, 1 },
1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DP2A,   "DP2A",    3, 1 },
1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DP3,    "DP3",     2, 1 },
1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DP4,    "DP4",     2, 1 },
1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DPH,    "DPH",     2, 1 },
1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_DST,    "DST",     2, 1 },
1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ELSE,   "ELSE",    0, 0 },
180760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   { OPCODE_EMIT_VERTEX,   "EMIT_VERTEX",    0, 0 },
1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_END,    "END",     0, 0 },
182760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   { OPCODE_END_PRIMITIVE,    "END_PRIMITIVE",     0, 0 },
1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ENDIF,  "ENDIF",   0, 0 },
1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_ENDSUB, "ENDSUB",  0, 0 },
1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_EX2,    "EX2",     1, 1 },
1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_EXP,    "EXP",     1, 1 },
1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_FLR,    "FLR",     1, 1 },
1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_FRC,    "FRC",     1, 1 },
1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_IF,     "IF",      1, 0 },
1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_KIL,    "KIL",     1, 0 },
1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_KIL_NV, "KIL_NV",  0, 0 },
1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_LG2,    "LG2",     1, 1 },
1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_LIT,    "LIT",     1, 1 },
1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_LOG,    "LOG",     1, 1 },
1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_LRP,    "LRP",     3, 1 },
1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_MAD,    "MAD",     3, 1 },
1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_MAX,    "MAX",     2, 1 },
1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_MIN,    "MIN",     2, 1 },
2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_MOV,    "MOV",     1, 1 },
2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_MUL,    "MUL",     2, 1 },
2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOISE1, "NOISE1",  1, 1 },
2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOISE2, "NOISE2",  1, 1 },
2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOISE3, "NOISE3",  1, 1 },
2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOISE4, "NOISE4",  1, 1 },
2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NOT,    "NOT",     1, 1 },
2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NRM3,   "NRM3",    1, 1 },
2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_NRM4,   "NRM4",    1, 1 },
2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_OR,     "OR",      2, 1 },
2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PK2H,   "PK2H",    1, 1 },
2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PK2US,  "PK2US",   1, 1 },
2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PK4B,   "PK4B",    1, 1 },
2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PK4UB,  "PK4UB",   1, 1 },
2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_POW,    "POW",     2, 1 },
2153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_POPA,   "POPA",    0, 0 },
2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PRINT,  "PRINT",   1, 0 },
2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_PUSHA,  "PUSHA",   0, 0 },
2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_RCC,    "RCC",     1, 1 },
2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_RCP,    "RCP",     1, 1 },
2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_RET,    "RET",     0, 0 },
2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_RFL,    "RFL",     1, 1 },
2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_RSQ,    "RSQ",     1, 1 },
2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SCS,    "SCS",     1, 1 },
2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SEQ,    "SEQ",     2, 1 },
2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SFL,    "SFL",     0, 1 },
2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SGE,    "SGE",     2, 1 },
2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SGT,    "SGT",     2, 1 },
2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SIN,    "SIN",     1, 1 },
2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SLE,    "SLE",     2, 1 },
2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SLT,    "SLT",     2, 1 },
2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SNE,    "SNE",     2, 1 },
2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SSG,    "SSG",     1, 1 },
2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_STR,    "STR",     0, 1 },
2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SUB,    "SUB",     2, 1 },
2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_SWZ,    "SWZ",     1, 1 },
2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TEX,    "TEX",     1, 1 },
2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TXB,    "TXB",     1, 1 },
2383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TXD,    "TXD",     3, 1 },
2393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TXL,    "TXL",     1, 1 },
2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TXP,    "TXP",     1, 1 },
2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TXP_NV, "TXP_NV",  1, 1 },
2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_TRUNC,  "TRUNC",   1, 1 },
2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_UP2H,   "UP2H",    1, 1 },
2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_UP2US,  "UP2US",   1, 1 },
2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_UP4B,   "UP4B",    1, 1 },
2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_UP4UB,  "UP4UB",   1, 1 },
2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_X2D,    "X2D",     3, 1 },
2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_XOR,    "XOR",     2, 1 },
2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   { OPCODE_XPD,    "XPD",     2, 1 }
2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org};
2513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Return the number of src registers for the given instruction/opcode.
2553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
2563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgGLuint
2573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_num_inst_src_regs(gl_inst_opcode opcode)
2583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(opcode < MAX_OPCODE);
2603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(opcode == InstInfo[opcode].Opcode);
2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
2623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return InstInfo[opcode].NumSrcRegs;
2633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
2673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Return the number of dst registers for the given instruction/opcode.
2683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
2693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgGLuint
2703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
2713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(opcode < MAX_OPCODE);
2733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(opcode == InstInfo[opcode].Opcode);
2743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
2753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return InstInfo[opcode].NumDstRegs;
2763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgGLboolean
2803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_is_tex_instruction(gl_inst_opcode opcode)
2813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return (opcode == OPCODE_TEX ||
2833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org           opcode == OPCODE_TXB ||
2843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org           opcode == OPCODE_TXD ||
2853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org           opcode == OPCODE_TXL ||
2863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org           opcode == OPCODE_TXP);
2873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
2913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Check if there's a potential src/dst register data dependency when
2923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * using SOA execution.
2933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Example:
2943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *   MOV T, T.yxwz;
2953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * This would expand into:
2963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *   MOV t0, t1;
2973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *   MOV t1, t0;
2983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *   MOV t2, t3;
2993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *   MOV t3, t2;
3003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The second instruction will have the wrong value for t0 if executed as-is.
3013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
3023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgGLboolean
3033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_check_soa_dependencies(const struct prog_instruction *inst)
3043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
3053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   GLuint i, chan;
3063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (inst->DstReg.WriteMask == WRITEMASK_X ||
3083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org       inst->DstReg.WriteMask == WRITEMASK_Y ||
3093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org       inst->DstReg.WriteMask == WRITEMASK_Z ||
3103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org       inst->DstReg.WriteMask == WRITEMASK_W ||
3113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org       inst->DstReg.WriteMask == 0x0) {
3123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      /* no chance of data dependency */
3133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return GL_FALSE;
3143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
3153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* loop over src regs */
3173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < 3; i++) {
3183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (inst->SrcReg[i].File == inst->DstReg.File &&
3193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org          inst->SrcReg[i].Index == inst->DstReg.Index) {
3203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         /* loop over dest channels */
3213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         GLuint channelsWritten = 0x0;
3223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         for (chan = 0; chan < 4; chan++) {
3233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            if (inst->DstReg.WriteMask & (1 << chan)) {
3243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               /* check if we're reading a channel that's been written */
3253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
3263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               if (swizzle <= SWIZZLE_W &&
3273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                   (channelsWritten & (1 << swizzle))) {
3283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                  return GL_TRUE;
3293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               }
3303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               channelsWritten |= (1 << chan);
3323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            }
3333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         }
3343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
3353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
3363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return GL_FALSE;
3373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
3383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
3403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
3413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Return string name for given program opcode.
3423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
3433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgconst char *
3443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org_mesa_opcode_string(gl_inst_opcode opcode)
3453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
3463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (opcode < MAX_OPCODE)
3473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return InstInfo[opcode].Name;
3483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   else {
3493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      static char s[20];
3503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
3513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return s;
3523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
3533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
3543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
355