i915_debug_fp.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 
00029 #include "i915_reg.h"
00030 #include "i915_debug.h"
00031 #include "pipe/p_winsys.h"
00032 #include "util/u_memory.h"
00033 
00034 
00035 static void
00036 PRINTF(
00037    struct debug_stream  *stream,
00038    const char           *fmt,
00039                         ... )
00040 {
00041    va_list  args;
00042 
00043    va_start( args, fmt );
00044    debug_vprintf( fmt, args );
00045    va_end( args );
00046 }
00047 
00048 
00049 static const char *opcodes[0x20] = {
00050    "NOP",
00051    "ADD",
00052    "MOV",
00053    "MUL",
00054    "MAD",
00055    "DP2ADD",
00056    "DP3",
00057    "DP4",
00058    "FRC",
00059    "RCP",
00060    "RSQ",
00061    "EXP",
00062    "LOG",
00063    "CMP",
00064    "MIN",
00065    "MAX",
00066    "FLR",
00067    "MOD",
00068    "TRC",
00069    "SGE",
00070    "SLT",
00071    "TEXLD",
00072    "TEXLDP",
00073    "TEXLDB",
00074    "TEXKILL",
00075    "DCL",
00076    "0x1a",
00077    "0x1b",
00078    "0x1c",
00079    "0x1d",
00080    "0x1e",
00081    "0x1f",
00082 };
00083 
00084 
00085 static const int args[0x20] = {
00086    0,                           /* 0 nop */
00087    2,                           /* 1 add */
00088    1,                           /* 2 mov */
00089    2,                           /* 3 m ul */
00090    3,                           /* 4 mad */
00091    3,                           /* 5 dp2add */
00092    2,                           /* 6 dp3 */
00093    2,                           /* 7 dp4 */
00094    1,                           /* 8 frc */
00095    1,                           /* 9 rcp */
00096    1,                           /* a rsq */
00097    1,                           /* b exp */
00098    1,                           /* c log */
00099    3,                           /* d cmp */
00100    2,                           /* e min */
00101    2,                           /* f max */
00102    1,                           /* 10 flr */
00103    1,                           /* 11 mod */
00104    1,                           /* 12 trc */
00105    2,                           /* 13 sge */
00106    2,                           /* 14 slt */
00107    1,
00108    1,
00109    1,
00110    1,
00111    0,
00112    0,
00113    0,
00114    0,
00115    0,
00116    0,
00117    0,
00118 };
00119 
00120 
00121 static const char *regname[0x8] = {
00122    "R",
00123    "T",
00124    "CONST",
00125    "S",
00126    "OC",
00127    "OD",
00128    "U",
00129    "UNKNOWN",
00130 };
00131 
00132 static void
00133 print_reg_type_nr(struct debug_stream *stream, unsigned type, unsigned nr)
00134 {
00135    switch (type) {
00136    case REG_TYPE_T:
00137       switch (nr) {
00138       case T_DIFFUSE:
00139          PRINTF(stream, "T_DIFFUSE");
00140          return;
00141       case T_SPECULAR:
00142          PRINTF(stream, "T_SPECULAR");
00143          return;
00144       case T_FOG_W:
00145          PRINTF(stream, "T_FOG_W");
00146          return;
00147       default:
00148          PRINTF(stream, "T_TEX%d", nr);
00149          return;
00150       }
00151    case REG_TYPE_OC:
00152       if (nr == 0) {
00153          PRINTF(stream, "oC");
00154          return;
00155       }
00156       break;
00157    case REG_TYPE_OD:
00158       if (nr == 0) {
00159          PRINTF(stream, "oD");
00160          return;
00161       }
00162       break;
00163    default:
00164       break;
00165    }
00166 
00167    PRINTF(stream, "%s[%d]", regname[type], nr);
00168 }
00169 
00170 #define REG_SWIZZLE_MASK 0x7777
00171 #define REG_NEGATE_MASK 0x8888
00172 
00173 #define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) |  \
00174                       (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) |      \
00175                       (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) |      \
00176                       (SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
00177 
00178 
00179 static void
00180 print_reg_neg_swizzle(struct debug_stream *stream, unsigned reg)
00181 {
00182    int i;
00183 
00184    if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW &&
00185        (reg & REG_NEGATE_MASK) == 0)
00186       return;
00187 
00188    PRINTF(stream, ".");
00189 
00190    for (i = 3; i >= 0; i--) {
00191       if (reg & (1 << ((i * 4) + 3)))
00192          PRINTF(stream, "-");
00193 
00194       switch ((reg >> (i * 4)) & 0x7) {
00195       case 0:
00196          PRINTF(stream, "x");
00197          break;
00198       case 1:
00199          PRINTF(stream, "y");
00200          break;
00201       case 2:
00202          PRINTF(stream, "z");
00203          break;
00204       case 3:
00205          PRINTF(stream, "w");
00206          break;
00207       case 4:
00208          PRINTF(stream, "0");
00209          break;
00210       case 5:
00211          PRINTF(stream, "1");
00212          break;
00213       default:
00214          PRINTF(stream, "?");
00215          break;
00216       }
00217    }
00218 }
00219 
00220 
00221 static void
00222 print_src_reg(struct debug_stream *stream, unsigned dword)
00223 {
00224    unsigned nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK;
00225    unsigned type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK;
00226    print_reg_type_nr(stream, type, nr);
00227    print_reg_neg_swizzle(stream, dword);
00228 }
00229 
00230 
00231 static void
00232 print_dest_reg(struct debug_stream *stream, unsigned dword)
00233 {
00234    unsigned nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK;
00235    unsigned type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK;
00236    print_reg_type_nr(stream, type, nr);
00237    if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL)
00238       return;
00239    PRINTF(stream, ".");
00240    if (dword & A0_DEST_CHANNEL_X)
00241       PRINTF(stream, "x");
00242    if (dword & A0_DEST_CHANNEL_Y)
00243       PRINTF(stream, "y");
00244    if (dword & A0_DEST_CHANNEL_Z)
00245       PRINTF(stream, "z");
00246    if (dword & A0_DEST_CHANNEL_W)
00247       PRINTF(stream, "w");
00248 }
00249 
00250 
00251 #define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT))
00252 #define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT))
00253 #define GET_SRC2_REG(r)      (r)
00254 
00255 
00256 static void
00257 print_arith_op(struct debug_stream *stream, 
00258                unsigned opcode, const unsigned * program)
00259 {
00260    if (opcode != A0_NOP) {
00261       print_dest_reg(stream, program[0]);
00262       if (program[0] & A0_DEST_SATURATE)
00263          PRINTF(stream, " = SATURATE ");
00264       else
00265          PRINTF(stream, " = ");
00266    }
00267 
00268    PRINTF(stream, "%s ", opcodes[opcode]);
00269 
00270    print_src_reg(stream, GET_SRC0_REG(program[0], program[1]));
00271    if (args[opcode] == 1) {
00272       PRINTF(stream, "\n");
00273       return;
00274    }
00275 
00276    PRINTF(stream, ", ");
00277    print_src_reg(stream, GET_SRC1_REG(program[1], program[2]));
00278    if (args[opcode] == 2) {
00279       PRINTF(stream, "\n");
00280       return;
00281    }
00282 
00283    PRINTF(stream, ", ");
00284    print_src_reg(stream, GET_SRC2_REG(program[2]));
00285    PRINTF(stream, "\n");
00286    return;
00287 }
00288 
00289 
00290 static void
00291 print_tex_op(struct debug_stream *stream, 
00292              unsigned opcode, const unsigned * program)
00293 {
00294    print_dest_reg(stream, program[0] | A0_DEST_CHANNEL_ALL);
00295    PRINTF(stream, " = ");
00296 
00297    PRINTF(stream, "%s ", opcodes[opcode]);
00298 
00299    PRINTF(stream, "S[%d],", program[0] & T0_SAMPLER_NR_MASK);
00300 
00301    print_reg_type_nr(stream, 
00302                      (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) &
00303                      REG_TYPE_MASK,
00304                      (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK);
00305    PRINTF(stream, "\n");
00306 }
00307 
00308 static void
00309 print_texkil_op(struct debug_stream *stream, 
00310                 unsigned opcode, const unsigned * program)
00311 {
00312    PRINTF(stream, "TEXKIL ");
00313 
00314    print_reg_type_nr(stream, 
00315                      (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) &
00316                      REG_TYPE_MASK,
00317                      (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK);
00318    PRINTF(stream, "\n");
00319 }
00320 
00321 static void
00322 print_dcl_op(struct debug_stream *stream, 
00323              unsigned opcode, const unsigned * program)
00324 {
00325    PRINTF(stream, "%s ", opcodes[opcode]);
00326    print_dest_reg(stream, 
00327                   program[0] | A0_DEST_CHANNEL_ALL);
00328    PRINTF(stream, "\n");
00329 }
00330 
00331 
00332 void
00333 i915_disassemble_program(struct debug_stream *stream, 
00334                          const unsigned * program, unsigned sz)
00335 {
00336    unsigned i;
00337 
00338    PRINTF(stream, "\t\tBEGIN\n");
00339 
00340    assert((program[0] & 0x1ff) + 2 == sz);
00341 
00342    program++;
00343    for (i = 1; i < sz; i += 3, program += 3) {
00344       unsigned opcode = program[0] & (0x1f << 24);
00345 
00346       PRINTF(stream, "\t\t");
00347 
00348       if ((int) opcode >= A0_NOP && opcode <= A0_SLT)
00349          print_arith_op(stream, opcode >> 24, program);
00350       else if (opcode >= T0_TEXLD && opcode < T0_TEXKILL)
00351          print_tex_op(stream, opcode >> 24, program);
00352       else if (opcode == T0_TEXKILL)
00353          print_texkil_op(stream, opcode >> 24, program);
00354       else if (opcode == D0_DCL)
00355          print_dcl_op(stream, opcode >> 24, program);
00356       else
00357          PRINTF(stream, "Unknown opcode 0x%x\n", opcode);
00358    }
00359 
00360    PRINTF(stream, "\t\tEND\n\n");
00361 }
00362 
00363 

Generated on Tue Sep 29 06:25:16 2009 for Gallium3D by  doxygen 1.5.4