tgsi: Add support for indirect addressing in dump, sanity and text modules.
authorMichal Krol <michal@tungstengraphics.com>
Sun, 20 Jul 2008 19:23:04 +0000 (21:23 +0200)
committerMichal Krol <michal@tungstengraphics.com>
Sun, 20 Jul 2008 19:23:04 +0000 (21:23 +0200)
src/gallium/auxiliary/tgsi/util/tgsi_dump.c
src/gallium/auxiliary/tgsi/util/tgsi_sanity.c
src/gallium/auxiliary/tgsi/util/tgsi_text.c

index a9d500c8cf7247de40d76dc587a9192ff5edae87..94180f7e50785773c8b83da1796bd5ec4b42d66b 100644 (file)
@@ -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(
index a4edbb6d08f674beeac3248b0efa22d5d2024a8b..f11de815b06be911a8f635bd4a2b09dec125ef78 100644 (file)
@@ -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;
index 9ed0f52fc7c0abcd8d56de457b8e51b37258dc7a..2a503154630de3d8c8cbb65f0978d139f095ab46 100644 (file)
@@ -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;