summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Krol <michal@tungstengraphics.com>2008-07-20 21:23:04 +0200
committerMichal Krol <michal@tungstengraphics.com>2008-07-20 21:23:04 +0200
commit73e1d0be756537376495547bc1e798805884b8ef (patch)
tree2c0b11916bde6ef4f2a3d13571a68bc293f6aa5d
parent613f0df64dd2c2db71dd73b595225016ae596576 (diff)
tgsi: Add support for indirect addressing in dump, sanity and text modules.
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c53
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_sanity.c86
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_text.c147
3 files changed, 215 insertions, 71 deletions
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index a9d500c8cf..94180f7e50 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -265,17 +265,48 @@ static const char *modulate_names[TGSI_MODULATE_COUNT] =
};
static void
-_dump_register(
+_dump_register_prefix(
uint file,
uint first,
uint last )
{
+
+
+}
+
+static void
+_dump_register(
+ uint file,
+ int first,
+ int last )
+{
ENM( file, file_names );
CHR( '[' );
- UID( first );
+ SID( first );
if (first != last) {
TXT( ".." );
- UID( last );
+ SID( last );
+ }
+ CHR( ']' );
+}
+
+static void
+_dump_register_ind(
+ uint file,
+ int index,
+ uint ind_file,
+ int ind_index )
+{
+ ENM( file, file_names );
+ CHR( '[' );
+ ENM( ind_file, file_names );
+ CHR( '[' );
+ SID( ind_index );
+ CHR( ']' );
+ if (index != 0) {
+ if (index > 0)
+ CHR( '+' );
+ SID( index );
}
CHR( ']' );
}
@@ -432,17 +463,11 @@ tgsi_dump_instruction(
CHR( '-' );
if (src->SrcRegister.Indirect) {
- /* TODO: Tidy up
- */
- ENM( src->SrcRegister.File, file_names );
- CHR( '[' );
- TXT( "ADDR[0]" );
- if (src->SrcRegister.Index != 0) {
- if (src->SrcRegister.Index > 0)
- CHR( '+' );
- SID( src->SrcRegister.Index );
- }
- CHR( ']' );
+ _dump_register_ind(
+ src->SrcRegister.File,
+ src->SrcRegister.Index,
+ src->SrcRegisterInd.File,
+ src->SrcRegisterInd.Index );
}
else {
_dump_register(
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
index a4edbb6d08..f11de815b0 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
@@ -39,8 +39,9 @@ struct sanity_check_ctx
{
struct tgsi_iterate_context iter;
- reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8];
- reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8];
+ reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG];
+ reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG];
+ boolean regs_ind_used[TGSI_FILE_COUNT];
uint num_imms;
uint num_instructions;
uint index_of_END;
@@ -83,18 +84,31 @@ static boolean
is_register_declared(
struct sanity_check_ctx *ctx,
uint file,
- uint index )
+ int index )
{
- assert( index < MAX_REGISTERS );
+ assert( index >= 0 && index < MAX_REGISTERS );
return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
}
static boolean
+is_any_register_declared(
+ struct sanity_check_ctx *ctx,
+ uint file )
+{
+ uint i;
+
+ for (i = 0; i < MAX_REGISTERS / BITS_IN_REG_FLAG; i++)
+ if (ctx->regs_decl[file][i])
+ return TRUE;
+ return FALSE;
+}
+
+static boolean
is_register_used(
struct sanity_check_ctx *ctx,
uint file,
- uint index )
+ int index )
{
assert( index < MAX_REGISTERS );
@@ -102,6 +116,28 @@ is_register_used(
}
static boolean
+check_register_usage(
+ struct sanity_check_ctx *ctx,
+ uint file,
+ int index,
+ boolean indirect )
+{
+ if (!check_file_name( ctx, file ))
+ return FALSE;
+ if (indirect) {
+ if (!is_any_register_declared( ctx, file ))
+ report_error( ctx, "Undeclared source register" );
+ ctx->regs_ind_used[file] = TRUE;
+ }
+ else {
+ if (!is_register_declared( ctx, file, index ))
+ report_error( ctx, "Undeclared destination register" );
+ ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+ }
+ return TRUE;
+}
+
+static boolean
iter_instruction(
struct tgsi_iterate_context *iter,
struct tgsi_full_instruction *inst )
@@ -122,28 +158,25 @@ iter_instruction(
* Mark the registers as used.
*/
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
- uint file;
- uint index;
-
- file = inst->FullDstRegisters[i].DstRegister.File;
- if (!check_file_name( ctx, file ))
- return TRUE;
- index = inst->FullDstRegisters[i].DstRegister.Index;
- if (!is_register_declared( ctx, file, index ))
- report_error( ctx, "Undeclared destination register" );
- ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+ check_register_usage(
+ ctx,
+ inst->FullDstRegisters[i].DstRegister.File,
+ inst->FullDstRegisters[i].DstRegister.Index,
+ FALSE );
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
- uint file;
- uint index;
-
- file = inst->FullSrcRegisters[i].SrcRegister.File;
- if (!check_file_name( ctx, file ))
- return TRUE;
- index = inst->FullSrcRegisters[i].SrcRegister.Index;
- if (!is_register_declared( ctx, file, index ))
- report_error( ctx, "Undeclared source register" );
- ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+ check_register_usage(
+ ctx,
+ inst->FullSrcRegisters[i].SrcRegister.File,
+ inst->FullSrcRegisters[i].SrcRegister.Index,
+ inst->FullSrcRegisters[i].SrcRegister.Indirect );
+ if (inst->FullSrcRegisters[i].SrcRegister.Indirect) {
+ check_register_usage(
+ ctx,
+ inst->FullSrcRegisters[i].SrcRegisterInd.File,
+ inst->FullSrcRegisters[i].SrcRegisterInd.Index,
+ FALSE );
+ }
}
ctx->num_instructions++;
@@ -228,7 +261,7 @@ epilog(
uint i;
for (i = 0; i < MAX_REGISTERS; i++) {
- if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i )) {
+ if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) {
report_warning( ctx, "Register never used" );
}
}
@@ -256,6 +289,7 @@ tgsi_sanity_check(
memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) );
+ memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) );
ctx.num_imms = 0;
ctx.num_instructions = 0;
ctx.index_of_END = ~0;
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c
index 9ed0f52fc7..2a50315463 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c
@@ -226,24 +226,21 @@ static const char *file_names[TGSI_FILE_COUNT] =
};
static boolean
-parse_file(
- struct translate_ctx *ctx,
- uint *file )
+parse_file( const char **pcur, uint *file )
{
uint i;
for (i = 0; i < TGSI_FILE_COUNT; i++) {
- const char *cur = ctx->cur;
+ const char *cur = *pcur;
if (str_match_no_case( &cur, file_names[i] )) {
if (!is_digit_alpha_underscore( cur )) {
- ctx->cur = cur;
+ *pcur = cur;
*file = i;
return TRUE;
}
}
}
- report_error( ctx, "Unknown register file" );
return FALSE;
}
@@ -290,41 +287,57 @@ parse_opt_writemask(
return TRUE;
}
-/* Parse register part common for decls and operands.
- * <register_prefix> ::= <file> `[' <index>
+/* <register_file_bracket> ::= <file> `['
*/
static boolean
-parse_register_prefix(
+parse_register_file_bracket(
struct translate_ctx *ctx,
- uint *file,
- uint *index )
+ uint *file )
{
- if (!parse_file( ctx, file ))
+ if (!parse_file( &ctx->cur, file )) {
+ report_error( ctx, "Unknown register file" );
return FALSE;
+ }
eat_opt_white( &ctx->cur );
if (*ctx->cur != '[') {
report_error( ctx, "Expected `['" );
return FALSE;
}
ctx->cur++;
+ return TRUE;
+}
+
+/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
+ */
+static boolean
+parse_register_file_bracket_index(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, index )) {
- report_error( ctx, "Expected literal integer" );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
return FALSE;
}
+ *index = (int) uindex;
return TRUE;
}
-/* Parse register operand.
- * <register> ::= <register_prefix> `]'
+/* Parse destination register operand.
+ * <register_dst> ::= <register_file_bracket_index> `]'
*/
static boolean
-parse_register(
+parse_register_dst(
struct translate_ctx *ctx,
uint *file,
- uint *index )
+ int *index )
{
- if (!parse_register_prefix( ctx, file, index ))
+ if (!parse_register_file_bracket_index( ctx, file, index ))
return FALSE;
eat_opt_white( &ctx->cur );
if (*ctx->cur != ']') {
@@ -332,30 +345,95 @@ parse_register(
return FALSE;
}
ctx->cur++;
- /* TODO: Modulate suffix */
+ return TRUE;
+}
+
+/* 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> `]'
+ */
+static boolean
+parse_register_src(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index,
+ uint *ind_file,
+ int *ind_index )
+{
+ const char *cur;
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ cur = ctx->cur;
+ if (parse_file( &cur, ind_file )) {
+ if (!parse_register_dst( ctx, ind_file, ind_index ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur == '+' || *ctx->cur == '-') {
+ boolean negate;
+
+ negate = *ctx->cur == '-';
+ ctx->cur++;
+ eat_opt_white( &ctx->cur );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ if (negate)
+ *index = -(int) uindex;
+ else
+ *index = (int) uindex;
+ }
+ else {
+ *index = 0;
+ }
+ }
+ else {
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ *index = (int) uindex;
+ *ind_file = TGSI_FILE_NULL;
+ *ind_index = 0;
+ }
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ']') {
+ report_error( ctx, "Expected `]'" );
+ return FALSE;
+ }
+ ctx->cur++;
return TRUE;
}
/* Parse register declaration.
- * <register> ::= <register_prefix> `]' | <register_prefix> `..' <index> `]'
+ * <register_dcl> ::= <register_file_bracket_index> `]' |
+ * <register_file_bracket_index> `..' <index> `]'
*/
static boolean
parse_register_dcl(
struct translate_ctx *ctx,
uint *file,
- uint *first,
- uint *last )
+ int *first,
+ int *last )
{
- if (!parse_register_prefix( ctx, file, first ))
+ if (!parse_register_file_bracket_index( ctx, file, first ))
return FALSE;
eat_opt_white( &ctx->cur );
if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
+ uint uindex;
+
ctx->cur += 2;
eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, last )) {
+ if (!parse_uint( &ctx->cur, &uindex )) {
report_error( ctx, "Expected literal integer" );
return FALSE;
}
+ *last = (int) uindex;
eat_opt_white( &ctx->cur );
}
else {
@@ -386,11 +464,11 @@ parse_dst_operand(
struct tgsi_full_dst_register *dst )
{
uint file;
- uint index;
+ int index;
uint writemask;
const char *cur;
- if (!parse_register( ctx, &file, &index ))
+ if (!parse_register_dst( ctx, &file, &index ))
return FALSE;
cur = ctx->cur;
@@ -426,7 +504,9 @@ parse_src_operand(
const char *cur;
float value;
uint file;
- uint index;
+ int index;
+ uint ind_file;
+ int ind_index;
if (*ctx->cur == '-') {
cur = ctx->cur;
@@ -498,10 +578,15 @@ parse_src_operand(
}
}
- if (!parse_register( ctx, &file, &index ))
+ if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index ))
return FALSE;
src->SrcRegister.File = file;
src->SrcRegister.Index = index;
+ if (ind_file != TGSI_FILE_NULL) {
+ src->SrcRegister.Indirect = 1;
+ src->SrcRegisterInd.File = ind_file;
+ src->SrcRegisterInd.Index = ind_index;
+ }
/* Parse optional swizzle
*/
@@ -864,8 +949,8 @@ static boolean parse_declaration( struct translate_ctx *ctx )
{
struct tgsi_full_declaration decl;
uint file;
- uint first;
- uint last;
+ int first;
+ int last;
uint writemask;
const char *cur;
uint advance;