1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2003 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "util/log.h" 29bf215546Sopenharmony_ci#include "util/ralloc.h" 30bf215546Sopenharmony_ci#include "util/u_debug.h" 31bf215546Sopenharmony_ci#include "i915_debug.h" 32bf215546Sopenharmony_ci#include "i915_debug_private.h" 33bf215546Sopenharmony_ci#include "i915_reg.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#define PRINTF ralloc_asprintf_append 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic const char *opcodes[0x20] = { 38bf215546Sopenharmony_ci "NOP", "ADD", "MOV", "MUL", "MAD", "DP2ADD", "DP3", "DP4", 39bf215546Sopenharmony_ci "FRC", "RCP", "RSQ", "EXP", "LOG", "CMP", "MIN", "MAX", 40bf215546Sopenharmony_ci "FLR", "MOD", "TRC", "SGE", "SLT", "TEXLD", "TEXLDP", "TEXLDB", 41bf215546Sopenharmony_ci "TEXKILL", "DCL", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f", 42bf215546Sopenharmony_ci}; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic const int args[0x20] = { 45bf215546Sopenharmony_ci 0, /* 0 nop */ 46bf215546Sopenharmony_ci 2, /* 1 add */ 47bf215546Sopenharmony_ci 1, /* 2 mov */ 48bf215546Sopenharmony_ci 2, /* 3 m ul */ 49bf215546Sopenharmony_ci 3, /* 4 mad */ 50bf215546Sopenharmony_ci 3, /* 5 dp2add */ 51bf215546Sopenharmony_ci 2, /* 6 dp3 */ 52bf215546Sopenharmony_ci 2, /* 7 dp4 */ 53bf215546Sopenharmony_ci 1, /* 8 frc */ 54bf215546Sopenharmony_ci 1, /* 9 rcp */ 55bf215546Sopenharmony_ci 1, /* a rsq */ 56bf215546Sopenharmony_ci 1, /* b exp */ 57bf215546Sopenharmony_ci 1, /* c log */ 58bf215546Sopenharmony_ci 3, /* d cmp */ 59bf215546Sopenharmony_ci 2, /* e min */ 60bf215546Sopenharmony_ci 2, /* f max */ 61bf215546Sopenharmony_ci 1, /* 10 flr */ 62bf215546Sopenharmony_ci 1, /* 11 mod */ 63bf215546Sopenharmony_ci 1, /* 12 trc */ 64bf215546Sopenharmony_ci 2, /* 13 sge */ 65bf215546Sopenharmony_ci 2, /* 14 slt */ 66bf215546Sopenharmony_ci 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 67bf215546Sopenharmony_ci}; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic const char *regname[0x8] = { 70bf215546Sopenharmony_ci "R", "T", "CONST", "S", "OC", "OD", "U", "UNKNOWN", 71bf215546Sopenharmony_ci}; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic void 74bf215546Sopenharmony_ciprint_reg_type_nr(char **stream, unsigned type, unsigned nr) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci switch (type) { 77bf215546Sopenharmony_ci case REG_TYPE_T: 78bf215546Sopenharmony_ci switch (nr) { 79bf215546Sopenharmony_ci case T_DIFFUSE: 80bf215546Sopenharmony_ci PRINTF(stream, "T_DIFFUSE"); 81bf215546Sopenharmony_ci return; 82bf215546Sopenharmony_ci case T_SPECULAR: 83bf215546Sopenharmony_ci PRINTF(stream, "T_SPECULAR"); 84bf215546Sopenharmony_ci return; 85bf215546Sopenharmony_ci case T_FOG_W: 86bf215546Sopenharmony_ci PRINTF(stream, "T_FOG_W"); 87bf215546Sopenharmony_ci return; 88bf215546Sopenharmony_ci default: 89bf215546Sopenharmony_ci PRINTF(stream, "T_TEX%d", nr); 90bf215546Sopenharmony_ci return; 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci case REG_TYPE_OC: 93bf215546Sopenharmony_ci if (nr == 0) { 94bf215546Sopenharmony_ci PRINTF(stream, "oC"); 95bf215546Sopenharmony_ci return; 96bf215546Sopenharmony_ci } 97bf215546Sopenharmony_ci break; 98bf215546Sopenharmony_ci case REG_TYPE_OD: 99bf215546Sopenharmony_ci if (nr == 0) { 100bf215546Sopenharmony_ci PRINTF(stream, "oD"); 101bf215546Sopenharmony_ci return; 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci break; 104bf215546Sopenharmony_ci default: 105bf215546Sopenharmony_ci break; 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci PRINTF(stream, "%s[%d]", regname[type], nr); 109bf215546Sopenharmony_ci} 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci#define REG_SWIZZLE_MASK 0x7777 112bf215546Sopenharmony_ci#define REG_NEGATE_MASK 0x8888 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci#define REG_SWIZZLE_XYZW \ 115bf215546Sopenharmony_ci ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ 116bf215546Sopenharmony_ci (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_cistatic void 119bf215546Sopenharmony_ciprint_reg_neg_swizzle(char **stream, unsigned reg) 120bf215546Sopenharmony_ci{ 121bf215546Sopenharmony_ci int i; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && 124bf215546Sopenharmony_ci (reg & REG_NEGATE_MASK) == 0) 125bf215546Sopenharmony_ci return; 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci PRINTF(stream, "."); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci for (i = 3; i >= 0; i--) { 130bf215546Sopenharmony_ci if (reg & (1 << ((i * 4) + 3))) 131bf215546Sopenharmony_ci PRINTF(stream, "-"); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci switch ((reg >> (i * 4)) & 0x7) { 134bf215546Sopenharmony_ci case 0: 135bf215546Sopenharmony_ci PRINTF(stream, "x"); 136bf215546Sopenharmony_ci break; 137bf215546Sopenharmony_ci case 1: 138bf215546Sopenharmony_ci PRINTF(stream, "y"); 139bf215546Sopenharmony_ci break; 140bf215546Sopenharmony_ci case 2: 141bf215546Sopenharmony_ci PRINTF(stream, "z"); 142bf215546Sopenharmony_ci break; 143bf215546Sopenharmony_ci case 3: 144bf215546Sopenharmony_ci PRINTF(stream, "w"); 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci case 4: 147bf215546Sopenharmony_ci PRINTF(stream, "0"); 148bf215546Sopenharmony_ci break; 149bf215546Sopenharmony_ci case 5: 150bf215546Sopenharmony_ci PRINTF(stream, "1"); 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci default: 153bf215546Sopenharmony_ci PRINTF(stream, "?"); 154bf215546Sopenharmony_ci break; 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci } 157bf215546Sopenharmony_ci} 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_cistatic void 160bf215546Sopenharmony_ciprint_src_reg(char **stream, unsigned dword) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci unsigned nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; 163bf215546Sopenharmony_ci unsigned type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; 164bf215546Sopenharmony_ci print_reg_type_nr(stream, type, nr); 165bf215546Sopenharmony_ci print_reg_neg_swizzle(stream, dword); 166bf215546Sopenharmony_ci} 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_cistatic void 169bf215546Sopenharmony_ciprint_dest_reg(char **stream, unsigned dword) 170bf215546Sopenharmony_ci{ 171bf215546Sopenharmony_ci unsigned nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; 172bf215546Sopenharmony_ci unsigned type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; 173bf215546Sopenharmony_ci print_reg_type_nr(stream, type, nr); 174bf215546Sopenharmony_ci if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) 175bf215546Sopenharmony_ci return; 176bf215546Sopenharmony_ci PRINTF(stream, "."); 177bf215546Sopenharmony_ci if (dword & A0_DEST_CHANNEL_X) 178bf215546Sopenharmony_ci PRINTF(stream, "x"); 179bf215546Sopenharmony_ci if (dword & A0_DEST_CHANNEL_Y) 180bf215546Sopenharmony_ci PRINTF(stream, "y"); 181bf215546Sopenharmony_ci if (dword & A0_DEST_CHANNEL_Z) 182bf215546Sopenharmony_ci PRINTF(stream, "z"); 183bf215546Sopenharmony_ci if (dword & A0_DEST_CHANNEL_W) 184bf215546Sopenharmony_ci PRINTF(stream, "w"); 185bf215546Sopenharmony_ci} 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci#define GET_SRC0_REG(r0, r1) ((r0 << 14) | (r1 >> A1_SRC0_CHANNEL_W_SHIFT)) 188bf215546Sopenharmony_ci#define GET_SRC1_REG(r0, r1) ((r0 << 8) | (r1 >> A2_SRC1_CHANNEL_W_SHIFT)) 189bf215546Sopenharmony_ci#define GET_SRC2_REG(r) (r) 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_cistatic void 192bf215546Sopenharmony_ciprint_arith_op(char **stream, unsigned opcode, const unsigned *program) 193bf215546Sopenharmony_ci{ 194bf215546Sopenharmony_ci if (opcode != A0_NOP) { 195bf215546Sopenharmony_ci print_dest_reg(stream, program[0]); 196bf215546Sopenharmony_ci if (program[0] & A0_DEST_SATURATE) 197bf215546Sopenharmony_ci PRINTF(stream, " = SATURATE "); 198bf215546Sopenharmony_ci else 199bf215546Sopenharmony_ci PRINTF(stream, " = "); 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci PRINTF(stream, "%s ", opcodes[opcode]); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci print_src_reg(stream, GET_SRC0_REG(program[0], program[1])); 205bf215546Sopenharmony_ci if (args[opcode] == 1) 206bf215546Sopenharmony_ci return; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci PRINTF(stream, ", "); 209bf215546Sopenharmony_ci print_src_reg(stream, GET_SRC1_REG(program[1], program[2])); 210bf215546Sopenharmony_ci if (args[opcode] == 2) 211bf215546Sopenharmony_ci return; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci PRINTF(stream, ", "); 214bf215546Sopenharmony_ci print_src_reg(stream, GET_SRC2_REG(program[2])); 215bf215546Sopenharmony_ci return; 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_cistatic void 219bf215546Sopenharmony_ciprint_tex_op(char **stream, unsigned opcode, const unsigned *program) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci print_dest_reg(stream, program[0] | A0_DEST_CHANNEL_ALL); 222bf215546Sopenharmony_ci PRINTF(stream, " = "); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci PRINTF(stream, "%s ", opcodes[opcode]); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci PRINTF(stream, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci print_reg_type_nr(stream, 229bf215546Sopenharmony_ci (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK, 230bf215546Sopenharmony_ci (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); 231bf215546Sopenharmony_ci} 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistatic void 234bf215546Sopenharmony_ciprint_texkil_op(char **stream, unsigned opcode, const unsigned *program) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci PRINTF(stream, "TEXKIL "); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci print_reg_type_nr(stream, 239bf215546Sopenharmony_ci (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK, 240bf215546Sopenharmony_ci (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); 241bf215546Sopenharmony_ci} 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_cistatic void 244bf215546Sopenharmony_ciprint_dcl_op(char **stream, unsigned opcode, const unsigned *program) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci unsigned type = (program[0] >> D0_TYPE_SHIFT) & REG_TYPE_MASK; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci PRINTF(stream, "%s ", opcodes[opcode]); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci unsigned dest_dword = program[0]; 251bf215546Sopenharmony_ci if (type == REG_TYPE_S) 252bf215546Sopenharmony_ci dest_dword |= A0_DEST_CHANNEL_ALL; 253bf215546Sopenharmony_ci print_dest_reg(stream, dest_dword); 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci if (type == REG_TYPE_S) { 256bf215546Sopenharmony_ci switch (program[0] & D0_SAMPLE_TYPE_MASK) { 257bf215546Sopenharmony_ci case D0_SAMPLE_TYPE_2D: 258bf215546Sopenharmony_ci PRINTF(stream, " 2D"); 259bf215546Sopenharmony_ci break; 260bf215546Sopenharmony_ci case D0_SAMPLE_TYPE_VOLUME: 261bf215546Sopenharmony_ci PRINTF(stream, " 3D"); 262bf215546Sopenharmony_ci break; 263bf215546Sopenharmony_ci case D0_SAMPLE_TYPE_CUBE: 264bf215546Sopenharmony_ci PRINTF(stream, " CUBE"); 265bf215546Sopenharmony_ci break; 266bf215546Sopenharmony_ci default: 267bf215546Sopenharmony_ci PRINTF(stream, " XXX bad type"); 268bf215546Sopenharmony_ci break; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci} 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_civoid 274bf215546Sopenharmony_cii915_disassemble_program(const unsigned *program, unsigned sz) 275bf215546Sopenharmony_ci{ 276bf215546Sopenharmony_ci unsigned i; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci mesa_logi("\t\tBEGIN"); 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci assert((program[0] & 0x1ff) + 2 == sz); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci program++; 283bf215546Sopenharmony_ci for (i = 1; i < sz; i += 3, program += 3) { 284bf215546Sopenharmony_ci unsigned opcode = program[0] & (0x1f << 24); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci char *stream = ralloc_strdup(NULL, ""); 287bf215546Sopenharmony_ci if ((int)opcode >= A0_NOP && opcode <= A0_SLT) 288bf215546Sopenharmony_ci print_arith_op(&stream, opcode >> 24, program); 289bf215546Sopenharmony_ci else if (opcode >= T0_TEXLD && opcode < T0_TEXKILL) 290bf215546Sopenharmony_ci print_tex_op(&stream, opcode >> 24, program); 291bf215546Sopenharmony_ci else if (opcode == T0_TEXKILL) 292bf215546Sopenharmony_ci print_texkil_op(&stream, opcode >> 24, program); 293bf215546Sopenharmony_ci else if (opcode == D0_DCL) 294bf215546Sopenharmony_ci print_dcl_op(&stream, opcode >> 24, program); 295bf215546Sopenharmony_ci else 296bf215546Sopenharmony_ci ralloc_asprintf_append(&stream, "\t\t Unknown opcode 0x%x\n", opcode); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci mesa_logi("\t\t %s ", stream); 299bf215546Sopenharmony_ci ralloc_free(stream); 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci mesa_logi("\t\tEND"); 303bf215546Sopenharmony_ci} 304