diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt | 79 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 61 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info.c | 238 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_text.c | 79 |
6 files changed, 326 insertions, 137 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt index 5b21a2be0b..a3f4947c73 100644 --- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt +++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt @@ -262,7 +262,7 @@ TGSI Instruction Specification dst.w = round(src.w) -1.3.10 EXPBASE2 - Exponent Base 2 +1.3.10 EXPBASE2 - Exponential Base 2 dst.x = pow(2.0, src.x) dst.y = pow(2.0, src.x) @@ -382,9 +382,7 @@ TGSI Instruction Specification 1.5.7 KILP - Predicated Discard - if (cc.x || cc.y || cc.z || cc.w) - discard - endif + discard 1.5.8 LG2 - Logarithm Base 2 @@ -548,7 +546,7 @@ TGSI Instruction Specification 1.6.3 BRA - Branch - TBD + pc = target 1.6.4 CAL - Subroutine Call @@ -1038,3 +1036,74 @@ TGSI Instruction Specification Alias for ARR. + +2 Explanation of symbols used +============================== + + +2.1 Functions +-------------- + + + abs(x) Absolute value of x. + |x| + (x < 0.0) ? -x : x + + ceil(x) Ceiling of x. + + clamp(x,y,z) Clamp x between y and z. + (x < y) ? y : (x > z) ? z : x + + cos(x) Cosine of x. + + floor(x) Floor of x. + + lg2(x) Logarithm base 2 of x. + + max(x,y) Maximum of x and y. + (x > y) ? x : y + + min(x,y) Minimum of x and y. + (x < y) ? x : y + + partialx(x) Derivative of x relative to fragment's X. + + partialy(x) Derivative of x relative to fragment's Y. + + pop() Pop from stack. + + pow(x,y) Raise x to power of y. + + push(x) Push x on stack. + + round(x) Round x. + + sin(x) Sine of x. + + sqrt(x) Square root of x. + + trunc(x) Truncate x. + + +2.2 Keywords +------------- + + + discard Discard fragment. + + dst First destination register. + + dst0 First destination register. + + pc Program counter. + + src First source register. + + src0 First source register. + + src1 Second source register. + + src2 Third source register. + + target Label of target instruction. + diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index ba807e498f..e8bd7cda3b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -123,6 +123,53 @@ #define UPDATE_EXEC_MASK(MACH) \ MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + +static const union tgsi_exec_channel ZeroVec = + { { 0.0, 0.0, 0.0, 0.0 } }; + + +#ifdef DEBUG +static void +check_inf_or_nan(const union tgsi_exec_channel *chan) +{ + assert(!util_is_inf_or_nan(chan->f[0])); + assert(!util_is_inf_or_nan(chan->f[1])); + assert(!util_is_inf_or_nan(chan->f[2])); + assert(!util_is_inf_or_nan(chan->f[3])); +} +#endif + + +#ifdef DEBUG +static void +print_chan(const char *msg, const union tgsi_exec_channel *chan) +{ + debug_printf("%s = {%f, %f, %f, %f}\n", + msg, chan->f[0], chan->f[1], chan->f[2], chan->f[3]); +} +#endif + + +#ifdef DEBUG +static void +print_temp(const struct tgsi_exec_machine *mach, uint index) +{ + const struct tgsi_exec_vector *tmp = &mach->Temps[index]; + int i; + debug_printf("Temp[%u] =\n", index); + for (i = 0; i < 4; i++) { + debug_printf(" %c: { %f, %f, %f, %f }\n", + "XYZW"[i], + tmp->xyzw[i].f[0], + tmp->xyzw[i].f[1], + tmp->xyzw[i].f[2], + tmp->xyzw[i].f[3]); + } +} +#endif + + + /** * Initialize machine state by expanding tokens to full instructions, * allocating temporary storage, setting up constants, etc. @@ -278,6 +325,12 @@ tgsi_exec_machine_init( mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; } + +#ifdef DEBUG + /* silence warnings */ + (void) print_chan; + (void) print_temp; +#endif } @@ -1281,6 +1334,10 @@ store_dest( union tgsi_exec_channel *dst; uint execmask = mach->ExecMask; +#ifdef DEBUG + check_inf_or_nan(chan); +#endif + switch (reg->DstRegister.File) { case TGSI_FILE_NULL: dst = &null; @@ -1643,7 +1700,7 @@ exec_tex(struct tgsi_exec_machine *mach, lodBias = 0.0; fetch_texel(mach->Samplers[unit], - &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &ZeroVec, &ZeroVec, lodBias, /* S, T, P, BIAS */ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ break; @@ -1847,7 +1904,7 @@ exec_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: - /* TGSI_OPCODE_FLOOR */ + case TGSI_OPCODE_FLOOR: /* TGSI_OPCODE_FLR */ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 4ffd4efbff..0b4b2a6fb6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -205,8 +205,8 @@ struct tgsi_exec_machine const float (*Consts)[4]; struct tgsi_exec_vector *Inputs; struct tgsi_exec_vector *Outputs; - const struct tgsi_token *Tokens; - unsigned Processor; + const struct tgsi_token *Tokens; /**< Declarations, instructions */ + unsigned Processor; /**< TGSI_PROCESSOR_x */ /* GEOMETRY processor only. */ unsigned *Primitives; diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index 2b8a6f0fb1..37f2b66d1f 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -30,125 +30,125 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = { - { 1, 1, 0, 0, "ARL" }, - { 1, 1, 0, 0, "MOV" }, - { 1, 1, 0, 0, "LIT" }, - { 1, 1, 0, 0, "RCP" }, - { 1, 1, 0, 0, "RSQ" }, - { 1, 1, 0, 0, "EXP" }, - { 1, 1, 0, 0, "LOG" }, - { 1, 2, 0, 0, "MUL" }, - { 1, 2, 0, 0, "ADD" }, - { 1, 2, 0, 0, "DP3" }, - { 1, 2, 0, 0, "DP4" }, - { 1, 2, 0, 0, "DST" }, - { 1, 2, 0, 0, "MIN" }, - { 1, 2, 0, 0, "MAX" }, - { 1, 2, 0, 0, "SLT" }, - { 1, 2, 0, 0, "SGE" }, - { 1, 3, 0, 0, "MAD" }, - { 1, 2, 0, 0, "SUB" }, - { 1, 3, 0, 0, "LERP" }, - { 1, 3, 0, 0, "CND" }, - { 1, 3, 0, 0, "CND0" }, - { 1, 3, 0, 0, "DOT2ADD" }, - { 1, 2, 0, 0, "INDEX" }, - { 1, 1, 0, 0, "NEGATE" }, - { 1, 1, 0, 0, "FRAC" }, - { 1, 3, 0, 0, "CLAMP" }, - { 1, 1, 0, 0, "FLOOR" }, - { 1, 1, 0, 0, "ROUND" }, - { 1, 1, 0, 0, "EXPBASE2" }, - { 1, 1, 0, 0, "LOGBASE2" }, - { 1, 2, 0, 0, "POWER" }, - { 1, 2, 0, 0, "CROSSPRODUCT" }, - { 1, 2, 0, 0, "MULTIPLYMATRIX" }, - { 1, 1, 0, 0, "ABS" }, - { 1, 1, 0, 0, "RCC" }, - { 1, 2, 0, 0, "DPH" }, - { 1, 1, 0, 0, "COS" }, - { 1, 1, 0, 0, "DDX" }, - { 1, 1, 0, 0, "DDY" }, - { 0, 0, 0, 0, "KILP" }, - { 1, 1, 0, 0, "PK2H" }, - { 1, 1, 0, 0, "PK2US" }, - { 1, 1, 0, 0, "PK4B" }, - { 1, 1, 0, 0, "PK4UB" }, - { 1, 2, 0, 0, "RFL" }, - { 1, 2, 0, 0, "SEQ" }, - { 1, 2, 0, 0, "SFL" }, - { 1, 2, 0, 0, "SGT" }, - { 1, 1, 0, 0, "SIN" }, - { 1, 2, 0, 0, "SLE" }, - { 1, 2, 0, 0, "SNE" }, - { 1, 2, 0, 0, "STR" }, - { 1, 2, 1, 0, "TEX" }, - { 1, 4, 1, 0, "TXD" }, - { 1, 2, 1, 0, "TXP" }, - { 1, 1, 0, 0, "UP2H" }, - { 1, 1, 0, 0, "UP2US" }, - { 1, 1, 0, 0, "UP4B" }, - { 1, 1, 0, 0, "UP4UB" }, - { 1, 3, 0, 0, "X2D" }, - { 1, 1, 0, 0, "ARA" }, - { 1, 1, 0, 0, "ARR" }, - { 0, 1, 0, 0, "BRA" }, - { 0, 0, 0, 1, "CAL" }, - { 0, 0, 0, 0, "RET" }, - { 1, 1, 0, 0, "SSG" }, - { 1, 3, 0, 0, "CMP" }, - { 1, 1, 0, 0, "SCS" }, - { 1, 2, 1, 0, "TXB" }, - { 1, 1, 0, 0, "NRM" }, - { 1, 2, 0, 0, "DIV" }, - { 1, 2, 0, 0, "DP2" }, - { 1, 2, 1, 0, "TXL" }, - { 0, 0, 0, 0, "BRK" }, - { 0, 1, 0, 1, "IF" }, - { 0, 0, 0, 0, "LOOP" }, - { 0, 1, 0, 0, "REP" }, - { 0, 0, 0, 1, "ELSE" }, - { 0, 0, 0, 0, "ENDIF" }, - { 0, 0, 0, 0, "ENDLOOP" }, - { 0, 0, 0, 0, "ENDREP" }, - { 0, 1, 0, 0, "PUSHA" }, - { 1, 0, 0, 0, "POPA" }, - { 1, 1, 0, 0, "CEIL" }, - { 1, 1, 0, 0, "I2F" }, - { 1, 1, 0, 0, "NOT" }, - { 1, 1, 0, 0, "TRUNC" }, - { 1, 2, 0, 0, "SHL" }, - { 1, 2, 0, 0, "SHR" }, - { 1, 2, 0, 0, "AND" }, - { 1, 2, 0, 0, "OR" }, - { 1, 2, 0, 0, "MOD" }, - { 1, 2, 0, 0, "XOR" }, - { 1, 3, 0, 0, "SAD" }, - { 1, 2, 1, 0, "TXF" }, - { 1, 2, 1, 0, "TXQ" }, - { 0, 0, 0, 0, "CONT" }, - { 0, 0, 0, 0, "EMIT" }, - { 0, 0, 0, 0, "ENDPRIM" }, - { 0, 0, 0, 1, "BGNLOOP2" }, - { 0, 0, 0, 0, "BGNSUB" }, - { 0, 0, 0, 1, "ENDLOOP2" }, - { 0, 0, 0, 0, "ENDSUB" }, - { 1, 1, 0, 0, "NOISE1" }, - { 1, 1, 0, 0, "NOISE2" }, - { 1, 1, 0, 0, "NOISE3" }, - { 1, 1, 0, 0, "NOISE4" }, - { 0, 0, 0, 0, "NOP" }, - { 1, 2, 0, 0, "M4X3" }, - { 1, 2, 0, 0, "M3X4" }, - { 1, 2, 0, 0, "M3X3" }, - { 1, 2, 0, 0, "M3X2" }, - { 1, 1, 0, 0, "NRM4" }, - { 0, 1, 0, 0, "CALLNZ" }, - { 0, 1, 0, 0, "IFC" }, - { 0, 1, 0, 0, "BREAKC" }, - { 0, 1, 0, 0, "KIL" }, - { 0, 0, 0, 0, "END" }, - { 1, 1, 0, 0, "SWZ" } + { 1, 1, 0, 0, "ARL", NULL, NULL }, + { 1, 1, 0, 0, "MOV", NULL, NULL }, + { 1, 1, 0, 0, "LIT", NULL, NULL }, + { 1, 1, 0, 0, "RCP", "RECIP", NULL }, + { 1, 1, 0, 0, "RSQ", "RECIPSQRT", NULL }, + { 1, 1, 0, 0, "EXP", "EXPP", NULL }, + { 1, 1, 0, 0, "LOG", NULL, NULL }, + { 1, 2, 0, 0, "MUL", NULL, NULL }, + { 1, 2, 0, 0, "ADD", NULL, NULL }, + { 1, 2, 0, 0, "DP3", "DOT3", NULL }, + { 1, 2, 0, 0, "DP4", "DOT4", NULL }, + { 1, 2, 0, 0, "DST", NULL, NULL }, + { 1, 2, 0, 0, "MIN", NULL, NULL }, + { 1, 2, 0, 0, "MAX", NULL, NULL }, + { 1, 2, 0, 0, "SLT", "SETLT", NULL }, + { 1, 2, 0, 0, "SGE", "SETGE", NULL }, + { 1, 3, 0, 0, "MAD", "MADD", NULL }, + { 1, 2, 0, 0, "SUB", NULL, NULL }, + { 1, 3, 0, 0, "LRP", "LERP", NULL }, + { 1, 3, 0, 0, "CND", NULL, NULL }, + { 1, 3, 0, 0, "CND0", NULL, NULL }, + { 1, 3, 0, 0, "DP2A", "DP2ADD", "DOT2ADD" }, + { 1, 2, 0, 0, "INDEX", NULL, NULL }, + { 1, 1, 0, 0, "NEGATE", NULL, NULL }, + { 1, 1, 0, 0, "FRC", "FRAC", NULL }, + { 1, 3, 0, 0, "CLAMP", NULL, NULL }, + { 1, 1, 0, 0, "FLR", "FLOOR", NULL }, + { 1, 1, 0, 0, "ROUND", NULL, NULL }, + { 1, 1, 0, 0, "EX2", "EXPBASE2", NULL }, + { 1, 1, 0, 0, "LG2", "LOGBASE2", "LOGP" }, + { 1, 2, 0, 0, "POW", "POWER", NULL }, + { 1, 2, 0, 0, "XPD", "CRS", "CROSSPRODUCT" }, + { 1, 2, 0, 0, "M4X4", "MULTIPLYMATRIX", NULL }, + { 1, 1, 0, 0, "ABS", NULL, NULL }, + { 1, 1, 0, 0, "RCC", NULL, NULL }, + { 1, 2, 0, 0, "DPH", NULL, NULL }, + { 1, 1, 0, 0, "COS", NULL, NULL }, + { 1, 1, 0, 0, "DDX", "DSX", NULL }, + { 1, 1, 0, 0, "DDY", "DSY", NULL }, + { 0, 0, 0, 0, "KILP", NULL, NULL }, + { 1, 1, 0, 0, "PK2H", NULL, NULL }, + { 1, 1, 0, 0, "PK2US", NULL, NULL }, + { 1, 1, 0, 0, "PK4B", NULL, NULL }, + { 1, 1, 0, 0, "PK4UB", NULL, NULL }, + { 1, 2, 0, 0, "RFL", NULL, NULL }, + { 1, 2, 0, 0, "SEQ", NULL, NULL }, + { 1, 2, 0, 0, "SFL", NULL, NULL }, + { 1, 2, 0, 0, "SGT", NULL, NULL }, + { 1, 1, 0, 0, "SIN", NULL, NULL }, + { 1, 2, 0, 0, "SLE", NULL, NULL }, + { 1, 2, 0, 0, "SNE", NULL, NULL }, + { 1, 2, 0, 0, "STR", NULL, NULL }, + { 1, 2, 1, 0, "TEX", "TEXLD", NULL }, + { 1, 4, 1, 0, "TXD", "TEXLDD", NULL }, + { 1, 2, 1, 0, "TXP", NULL, NULL }, + { 1, 1, 0, 0, "UP2H", NULL, NULL }, + { 1, 1, 0, 0, "UP2US", NULL, NULL }, + { 1, 1, 0, 0, "UP4B", NULL, NULL }, + { 1, 1, 0, 0, "UP4UB", NULL, NULL }, + { 1, 3, 0, 0, "X2D", NULL, NULL }, + { 1, 1, 0, 0, "ARA", NULL, NULL }, + { 1, 1, 0, 0, "ARR", "MOVA", NULL }, + { 0, 1, 0, 0, "BRA", NULL, NULL }, + { 0, 0, 0, 1, "CAL", "CALL", NULL }, + { 0, 0, 0, 0, "RET", NULL, NULL }, + { 1, 1, 0, 0, "SGN", "SSG", NULL }, + { 1, 3, 0, 0, "CMP", NULL, NULL }, + { 1, 1, 0, 0, "SCS", "SINCOS", NULL }, + { 1, 2, 1, 0, "TXB", "TEXLDB", NULL }, + { 1, 1, 0, 0, "NRM", NULL, NULL }, + { 1, 2, 0, 0, "DIV", NULL, NULL }, + { 1, 2, 0, 0, "DP2", NULL, NULL }, + { 1, 2, 1, 0, "TXL", NULL, NULL }, + { 0, 0, 0, 0, "BRK", "BREAK", NULL }, + { 0, 1, 0, 1, "IF", NULL, NULL }, + { 0, 0, 0, 0, "LOOP", NULL, NULL }, + { 0, 1, 0, 0, "REP", NULL, NULL }, + { 0, 0, 0, 1, "ELSE", NULL, NULL }, + { 0, 0, 0, 0, "ENDIF", NULL, NULL }, + { 0, 0, 0, 0, "ENDLOOP", NULL, NULL }, + { 0, 0, 0, 0, "ENDREP", NULL, NULL }, + { 0, 1, 0, 0, "PUSHA", NULL, NULL }, + { 1, 0, 0, 0, "POPA", NULL, NULL }, + { 1, 1, 0, 0, "CEIL", NULL, NULL }, + { 1, 1, 0, 0, "I2F", NULL, NULL }, + { 1, 1, 0, 0, "NOT", NULL, NULL }, + { 1, 1, 0, 0, "INT", "TRUNC", NULL }, + { 1, 2, 0, 0, "SHL", NULL, NULL }, + { 1, 2, 0, 0, "SHR", NULL, NULL }, + { 1, 2, 0, 0, "AND", NULL, NULL }, + { 1, 2, 0, 0, "OR", NULL, NULL }, + { 1, 2, 0, 0, "MOD", NULL, NULL }, + { 1, 2, 0, 0, "XOR", NULL, NULL }, + { 1, 3, 0, 0, "SAD", NULL, NULL }, + { 1, 2, 1, 0, "TXF", NULL, NULL }, + { 1, 2, 1, 0, "TXQ", NULL, NULL }, + { 0, 0, 0, 0, "CONT", NULL, NULL }, + { 0, 0, 0, 0, "EMIT", NULL, NULL }, + { 0, 0, 0, 0, "ENDPRIM", NULL, NULL }, + { 0, 0, 0, 1, "BGNLOOP2", NULL, NULL }, + { 0, 0, 0, 0, "BGNSUB", NULL, NULL }, + { 0, 0, 0, 1, "ENDLOOP2", NULL, NULL }, + { 0, 0, 0, 0, "ENDSUB", NULL, NULL }, + { 1, 1, 0, 0, "NOISE1", NULL, NULL }, + { 1, 1, 0, 0, "NOISE2", NULL, NULL }, + { 1, 1, 0, 0, "NOISE3", NULL, NULL }, + { 1, 1, 0, 0, "NOISE4", NULL, NULL }, + { 0, 0, 0, 0, "NOP", NULL, NULL }, + { 1, 2, 0, 0, "M4X3", NULL, NULL }, + { 1, 2, 0, 0, "M3X4", NULL, NULL }, + { 1, 2, 0, 0, "M3X3", NULL, NULL }, + { 1, 2, 0, 0, "M3X2", NULL, NULL }, + { 1, 1, 0, 0, "NRM4", NULL, NULL }, + { 0, 1, 0, 0, "CALLNZ", NULL, NULL }, + { 0, 1, 0, 0, "IFC", NULL, NULL }, + { 0, 1, 0, 0, "BREAKC", NULL, NULL }, + { 0, 1, 0, 0, "KIL", "TEXKILL", NULL }, + { 0, 0, 0, 0, "END", NULL, NULL }, + { 1, 1, 0, 0, "SWZ", NULL, NULL } }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h index 7230bdaae3..077e25acd7 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.h +++ b/src/gallium/auxiliary/tgsi/tgsi_info.h @@ -41,6 +41,8 @@ struct tgsi_opcode_info boolean is_tex; boolean is_branch; const char *mnemonic; + const char *alt_mnemonic1; + const char *alt_mnemonic2; }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 58fe07c11d..a40fcab212 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -358,9 +358,9 @@ parse_register_dst( /* Parse source register operand. * <register_src> ::= <register_file_bracket_index> `]' | - * <register_file_bracket> <register_dst> `]' | - * <register_file_bracket> <register_dst> `+' <uint> `]' | - * <register_file_bracket> <register_dst> `-' <uint> `]' + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' | + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' | + * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]' */ static boolean parse_register_src( @@ -368,11 +368,13 @@ parse_register_src( uint *file, int *index, uint *ind_file, - int *ind_index ) + int *ind_index, + uint *ind_comp) { const char *cur; uint uindex; + *ind_comp = TGSI_SWIZZLE_X; if (!parse_register_file_bracket( ctx, file )) return FALSE; eat_opt_white( &ctx->cur ); @@ -381,6 +383,32 @@ parse_register_src( if (!parse_register_dst( ctx, ind_file, ind_index )) return FALSE; eat_opt_white( &ctx->cur ); + + if (*ctx->cur == '.') { + ctx->cur++; + eat_opt_white(&ctx->cur); + + switch (uprcase(*ctx->cur)) { + case 'X': + *ind_comp = TGSI_SWIZZLE_X; + break; + case 'Y': + *ind_comp = TGSI_SWIZZLE_Y; + break; + case 'Z': + *ind_comp = TGSI_SWIZZLE_Z; + break; + case 'W': + *ind_comp = TGSI_SWIZZLE_W; + break; + default: + report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'"); + return FALSE; + } + ctx->cur++; + eat_opt_white(&ctx->cur); + } + if (*ctx->cur == '+' || *ctx->cur == '-') { boolean negate; @@ -561,7 +589,9 @@ parse_src_operand( int index; uint ind_file; int ind_index; + uint ind_comp; uint swizzle[4]; + boolean parsed_ext_negate_paren = FALSE; boolean parsed_swizzle; boolean parsed_extswizzle; @@ -574,10 +604,17 @@ parse_src_operand( src->SrcRegisterExtMod.Negate = 1; eat_opt_white( &cur ); ctx->cur = cur; + parsed_ext_negate_paren = TRUE; + } + else if (*cur == '|') { + cur++; + src->SrcRegisterExtMod.Negate = 1; + src->SrcRegisterExtMod.Absolute = 1; + eat_opt_white(&cur); + ctx->cur = cur; } } - - if (*ctx->cur == '|') { + else if (*ctx->cur == '|') { ctx->cur++; eat_opt_white( &ctx->cur ); src->SrcRegisterExtMod.Absolute = 1; @@ -635,7 +672,7 @@ parse_src_operand( } } - if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index )) + if (!parse_register_src(ctx, &file, &index, &ind_file, &ind_index, &ind_comp)) return FALSE; src->SrcRegister.File = file; src->SrcRegister.Index = index; @@ -643,6 +680,10 @@ parse_src_operand( src->SrcRegister.Indirect = 1; src->SrcRegisterInd.File = ind_file; src->SrcRegisterInd.Index = ind_index; + src->SrcRegisterInd.SwizzleX = ind_comp; + src->SrcRegisterInd.SwizzleY = ind_comp; + src->SrcRegisterInd.SwizzleZ = ind_comp; + src->SrcRegisterInd.SwizzleW = ind_comp; } /* Parse optional swizzle. @@ -715,7 +756,7 @@ parse_src_operand( ctx->cur++; } - if (src->SrcRegisterExtMod.Negate) { + if (parsed_ext_negate_paren) { eat_opt_white( &ctx->cur ); if (*ctx->cur != ')') { report_error( ctx, "Expected `)'" ); @@ -741,6 +782,26 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] = }; static boolean +match_inst_mnemonic(const char **pcur, + const struct tgsi_opcode_info *info) +{ + if (str_match_no_case(pcur, info->mnemonic)) { + return TRUE; + } + if (info->alt_mnemonic1) { + if (str_match_no_case(pcur, info->alt_mnemonic1)) { + return TRUE; + } + if (info->alt_mnemonic2) { + if (str_match_no_case(pcur, info->alt_mnemonic2)) { + return TRUE; + } + } + } + return FALSE; +} + +static boolean parse_instruction( struct translate_ctx *ctx, boolean has_label ) @@ -758,7 +819,7 @@ parse_instruction( const char *cur = ctx->cur; info = tgsi_get_opcode_info( i ); - if (str_match_no_case( &cur, info->mnemonic )) { + if (match_inst_mnemonic(&cur, info)) { if (str_match_no_case( &cur, "_SATNV" )) saturate = TGSI_SAT_MINUS_PLUS_ONE; else if (str_match_no_case( &cur, "_SAT" )) |