Brian | 00cdc0a | 2006-12-14 15:01:06 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
| 3 | * Version: 6.5.3 |
| 4 | * |
| 5 | * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. |
| 6 | * |
| 7 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 8 | * copy of this software and associated documentation files (the "Software"), |
| 9 | * to deal in the Software without restriction, including without limitation |
| 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 11 | * and/or sell copies of the Software, and to permit persons to whom the |
| 12 | * Software is furnished to do so, subject to the following conditions: |
| 13 | * |
| 14 | * The above copyright notice and this permission notice shall be included |
| 15 | * in all copies or substantial portions of the Software. |
| 16 | * |
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 20 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 21 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 23 | */ |
| 24 | |
| 25 | |
| 26 | #include "glheader.h" |
| 27 | #include "imports.h" |
| 28 | #include "mtypes.h" |
| 29 | #include "prog_instruction.h" |
| 30 | |
| 31 | |
| 32 | /** |
| 33 | * Initialize program instruction fields to defaults. |
| 34 | * \param inst first instruction to initialize |
| 35 | * \param count number of instructions to initialize |
| 36 | */ |
| 37 | void |
| 38 | _mesa_init_instructions(struct prog_instruction *inst, GLuint count) |
| 39 | { |
| 40 | GLuint i; |
| 41 | |
| 42 | _mesa_bzero(inst, count * sizeof(struct prog_instruction)); |
| 43 | |
| 44 | for (i = 0; i < count; i++) { |
| 45 | inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; |
| 46 | inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; |
| 47 | inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; |
| 48 | inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; |
| 49 | inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; |
| 50 | inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; |
| 51 | |
| 52 | inst[i].DstReg.File = PROGRAM_UNDEFINED; |
| 53 | inst[i].DstReg.WriteMask = WRITEMASK_XYZW; |
| 54 | inst[i].DstReg.CondMask = COND_TR; |
| 55 | inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; |
| 56 | |
| 57 | inst[i].SaturateMode = SATURATE_OFF; |
| 58 | inst[i].Precision = FLOAT32; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | |
| 63 | /** |
| 64 | * Allocate an array of program instructions. |
| 65 | * \param numInst number of instructions |
| 66 | * \return pointer to instruction memory |
| 67 | */ |
| 68 | struct prog_instruction * |
| 69 | _mesa_alloc_instructions(GLuint numInst) |
| 70 | { |
| 71 | return (struct prog_instruction *) |
| 72 | _mesa_calloc(numInst * sizeof(struct prog_instruction)); |
| 73 | } |
| 74 | |
| 75 | |
| 76 | /** |
| 77 | * Reallocate memory storing an array of program instructions. |
| 78 | * This is used when we need to append additional instructions onto an |
| 79 | * program. |
| 80 | * \param oldInst pointer to first of old/src instructions |
| 81 | * \param numOldInst number of instructions at <oldInst> |
| 82 | * \param numNewInst desired size of new instruction array. |
| 83 | * \return pointer to start of new instruction array. |
| 84 | */ |
| 85 | struct prog_instruction * |
| 86 | _mesa_realloc_instructions(struct prog_instruction *oldInst, |
| 87 | GLuint numOldInst, GLuint numNewInst) |
| 88 | { |
| 89 | struct prog_instruction *newInst; |
| 90 | |
| 91 | newInst = (struct prog_instruction *) |
| 92 | _mesa_realloc(oldInst, |
| 93 | numOldInst * sizeof(struct prog_instruction), |
| 94 | numNewInst * sizeof(struct prog_instruction)); |
| 95 | |
| 96 | return newInst; |
| 97 | } |
| 98 | |
| 99 | |
Brian | 23d31ef | 2007-03-21 11:57:30 -0600 | [diff] [blame^] | 100 | /** |
| 101 | * Copy an array of program instructions. |
| 102 | * \param dest pointer to destination. |
| 103 | * \param src pointer to source. |
| 104 | * \param n number of instructions to copy. |
| 105 | * \return pointer to destination. |
| 106 | */ |
| 107 | struct prog_instruction * |
| 108 | _mesa_copy_instructions(struct prog_instruction *dest, |
| 109 | const struct prog_instruction *src, GLuint n) |
| 110 | { |
| 111 | return _mesa_memcpy(dest, src, n * sizeof(struct prog_instruction)); |
| 112 | } |
| 113 | |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 114 | |
| 115 | /** |
| 116 | * Basic info about each instruction |
| 117 | */ |
| 118 | struct instruction_info |
| 119 | { |
| 120 | gl_inst_opcode Opcode; |
| 121 | const char *Name; |
| 122 | GLuint NumSrcRegs; |
| 123 | }; |
| 124 | |
| 125 | /** |
| 126 | * Instruction info |
| 127 | * \note Opcode should equal array index! |
| 128 | */ |
| 129 | static const struct instruction_info InstInfo[MAX_OPCODE] = { |
| 130 | { OPCODE_NOP, "NOP", 0 }, |
| 131 | { OPCODE_ABS, "ABS", 1 }, |
| 132 | { OPCODE_ADD, "ADD", 2 }, |
| 133 | { OPCODE_ARA, "ARA", 1 }, |
| 134 | { OPCODE_ARL, "ARL", 1 }, |
| 135 | { OPCODE_ARL_NV, "ARL", 1 }, |
| 136 | { OPCODE_ARR, "ARL", 1 }, |
Brian | 01001d8 | 2007-02-05 11:28:15 -0700 | [diff] [blame] | 137 | { OPCODE_BGNLOOP,"BGNLOOP", 0 }, |
| 138 | { OPCODE_BGNSUB, "BGNSUB", 0 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 139 | { OPCODE_BRA, "BRA", 0 }, |
Brian | 01001d8 | 2007-02-05 11:28:15 -0700 | [diff] [blame] | 140 | { OPCODE_BRK, "BRK", 0 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 141 | { OPCODE_CAL, "CAL", 0 }, |
| 142 | { OPCODE_CMP, "CMP", 3 }, |
Brian | 01001d8 | 2007-02-05 11:28:15 -0700 | [diff] [blame] | 143 | { OPCODE_CONT, "CONT", 1 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 144 | { OPCODE_COS, "COS", 1 }, |
| 145 | { OPCODE_DDX, "DDX", 1 }, |
| 146 | { OPCODE_DDY, "DDY", 1 }, |
| 147 | { OPCODE_DP3, "DP3", 2 }, |
| 148 | { OPCODE_DP4, "DP4", 2 }, |
| 149 | { OPCODE_DPH, "DPH", 2 }, |
| 150 | { OPCODE_DST, "DST", 2 }, |
Brian | 5ae49cf | 2007-01-20 09:27:40 -0700 | [diff] [blame] | 151 | { OPCODE_ELSE, "ELSE", 0 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 152 | { OPCODE_END, "END", 0 }, |
Brian | 5ae49cf | 2007-01-20 09:27:40 -0700 | [diff] [blame] | 153 | { OPCODE_ENDIF, "ENDIF", 0 }, |
Brian | 01001d8 | 2007-02-05 11:28:15 -0700 | [diff] [blame] | 154 | { OPCODE_ENDLOOP,"ENDLOOP", 0 }, |
| 155 | { OPCODE_ENDSUB, "ENDSUB", 0 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 156 | { OPCODE_EX2, "EX2", 1 }, |
| 157 | { OPCODE_EXP, "EXP", 1 }, |
| 158 | { OPCODE_FLR, "FLR", 1 }, |
| 159 | { OPCODE_FRC, "FRC", 1 }, |
Brian | 5ae49cf | 2007-01-20 09:27:40 -0700 | [diff] [blame] | 160 | { OPCODE_IF, "IF", 0 }, |
Brian | 0bad236 | 2007-01-17 15:54:14 -0700 | [diff] [blame] | 161 | { OPCODE_INT, "INT", 1 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 162 | { OPCODE_KIL, "KIL", 1 }, |
| 163 | { OPCODE_KIL_NV, "KIL", 0 }, |
| 164 | { OPCODE_LG2, "LG2", 1 }, |
| 165 | { OPCODE_LIT, "LIT", 1 }, |
| 166 | { OPCODE_LOG, "LOG", 1 }, |
| 167 | { OPCODE_LRP, "LRP", 3 }, |
| 168 | { OPCODE_MAD, "MAD", 3 }, |
| 169 | { OPCODE_MAX, "MAX", 2 }, |
| 170 | { OPCODE_MIN, "MIN", 2 }, |
| 171 | { OPCODE_MOV, "MOV", 1 }, |
| 172 | { OPCODE_MUL, "MUL", 2 }, |
Brian | 7aece10 | 2007-01-28 19:01:35 -0700 | [diff] [blame] | 173 | { OPCODE_NOISE1, "NOISE1", 1 }, |
| 174 | { OPCODE_NOISE2, "NOISE2", 1 }, |
| 175 | { OPCODE_NOISE3, "NOISE3", 1 }, |
| 176 | { OPCODE_NOISE4, "NOISE4", 1 }, |
Brian | 464b82b | 2006-12-14 15:47:08 -0700 | [diff] [blame] | 177 | { OPCODE_PK2H, "PK2H", 1 }, |
| 178 | { OPCODE_PK2US, "PK2US", 1 }, |
| 179 | { OPCODE_PK4B, "PK4B", 1 }, |
| 180 | { OPCODE_PK4UB, "PK4UB", 1 }, |
| 181 | { OPCODE_POW, "POW", 2 }, |
| 182 | { OPCODE_POPA, "POPA", 0 }, |
| 183 | { OPCODE_PRINT, "PRINT", 1 }, |
| 184 | { OPCODE_PUSHA, "PUSHA", 0 }, |
| 185 | { OPCODE_RCC, "RCC", 1 }, |
| 186 | { OPCODE_RCP, "RCP", 1 }, |
| 187 | { OPCODE_RET, "RET", 0 }, |
| 188 | { OPCODE_RFL, "RFL", 1 }, |
| 189 | { OPCODE_RSQ, "RSQ", 1 }, |
| 190 | { OPCODE_SCS, "SCS", 1 }, |
| 191 | { OPCODE_SEQ, "SEQ", 2 }, |
| 192 | { OPCODE_SFL, "SFL", 0 }, |
| 193 | { OPCODE_SGE, "SGE", 2 }, |
| 194 | { OPCODE_SGT, "SGT", 2 }, |
| 195 | { OPCODE_SIN, "SIN", 1 }, |
| 196 | { OPCODE_SLE, "SLE", 2 }, |
| 197 | { OPCODE_SLT, "SLT", 2 }, |
| 198 | { OPCODE_SNE, "SNE", 2 }, |
| 199 | { OPCODE_SSG, "SSG", 1 }, |
| 200 | { OPCODE_STR, "STR", 0 }, |
| 201 | { OPCODE_SUB, "SUB", 2 }, |
| 202 | { OPCODE_SWZ, "SWZ", 1 }, |
| 203 | { OPCODE_TEX, "TEX", 1 }, |
| 204 | { OPCODE_TXB, "TXB", 1 }, |
| 205 | { OPCODE_TXD, "TXD", 3 }, |
| 206 | { OPCODE_TXL, "TXL", 1 }, |
| 207 | { OPCODE_TXP, "TXP", 1 }, |
| 208 | { OPCODE_TXP_NV, "TXP", 1 }, |
| 209 | { OPCODE_UP2H, "UP2H", 1 }, |
| 210 | { OPCODE_UP2US, "UP2US", 1 }, |
| 211 | { OPCODE_UP4B, "UP4B", 1 }, |
| 212 | { OPCODE_UP4UB, "UP4UB", 1 }, |
| 213 | { OPCODE_X2D, "X2D", 3 }, |
| 214 | { OPCODE_XPD, "XPD", 2 } |
| 215 | }; |
| 216 | |
| 217 | |
| 218 | /** |
| 219 | * Return the number of src registers for the given instruction/opcode. |
| 220 | */ |
| 221 | GLuint |
| 222 | _mesa_num_inst_src_regs(gl_inst_opcode opcode) |
| 223 | { |
| 224 | ASSERT(opcode == InstInfo[opcode].Opcode); |
| 225 | ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); |
| 226 | return InstInfo[opcode].NumSrcRegs; |
| 227 | } |
| 228 | |
| 229 | |
| 230 | /** |
| 231 | * Return string name for given program opcode. |
| 232 | */ |
| 233 | const char * |
| 234 | _mesa_opcode_string(gl_inst_opcode opcode) |
| 235 | { |
| 236 | ASSERT(opcode < MAX_OPCODE); |
| 237 | return InstInfo[opcode].Name; |
| 238 | } |
| 239 | |