summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/tgsi
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/tgsi')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt79
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c61
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c238
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c79
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" ))