From 73e1d0be756537376495547bc1e798805884b8ef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 21:23:04 +0200 Subject: [PATCH] tgsi: Add support for indirect addressing in dump, sanity and text modules. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 53 +++++-- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 86 ++++++---- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 147 ++++++++++++++---- 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 a9d500c8cf7..94180f7e507 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 a4edbb6d08f..f11de815b06 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,24 +84,59 @@ 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 ); return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } +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, @@ -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 9ed0f52fc7c..2a503154630 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. - * ::= `[' +/* ::= `[' */ 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; +} + +/* ::= + */ +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. - * ::= `]' +/* Parse destination register operand. + * ::= `]' */ 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. + * ::= `]' | + * `]' | + * `+' `]' | + * `-' `]' + */ +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. - * ::= `]' | `..' `]' + * ::= `]' | + * `..' `]' */ 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; -- 2.30.2