667 lines
21 KiB
C
667 lines
21 KiB
C
/*
|
|
* Copyright © 2022 Imagination Technologies Ltd.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "pvr_rogue_pds_defs.h"
|
|
#include "pvr_rogue_pds_disasm.h"
|
|
#include "pvr_rogue_pds_encode.h"
|
|
#include "util/log.h"
|
|
|
|
#define X(lop, str) #str,
|
|
static const char *const LOP[] = { PVR_PDS_LOP };
|
|
#undef X
|
|
|
|
static void pvr_pds_disassemble_operand(struct pvr_operand *op,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
#define X(enum, str, size) { #str, #size },
|
|
static const char *const regs[][2] = { PVR_PDS_OPERAND_TYPES };
|
|
#undef X
|
|
|
|
if (op->type == LITERAL_NUM) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%s (%llu)",
|
|
regs[op->type][0],
|
|
(unsigned long long)op->literal);
|
|
} else if (op->type == UNRESOLVED) {
|
|
snprintf(instr_str, instr_len, "UNRESOLVED");
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%s[%u].%s",
|
|
regs[op->type][0],
|
|
op->absolute_address,
|
|
regs[op->type][1]);
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_add64(struct pvr_add *add,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char dst[32];
|
|
char src0[32];
|
|
char src1[32];
|
|
|
|
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %s %s %s %s",
|
|
"ADD64",
|
|
add->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
add->sna ? "-" : "+",
|
|
src1,
|
|
add->alum ? "[signed]" : "");
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_add32(struct pvr_add *add,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char dst[32];
|
|
char src0[32];
|
|
char src1[32];
|
|
|
|
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %s %s %s %s",
|
|
"ADD32",
|
|
add->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
add->sna ? "-" : "+",
|
|
src1,
|
|
add->alum ? "[signed]" : "");
|
|
}
|
|
|
|
static void
|
|
pvr_pds_disassemble_instruction_sftlp32(struct pvr_sftlp *instruction,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char dst[32];
|
|
char src0[32];
|
|
char src1[32];
|
|
char src2[32];
|
|
|
|
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
|
|
|
|
if (instruction->IM)
|
|
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
|
|
else
|
|
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
|
|
|
if (instruction->lop == LOP_NONE) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %s %s %s",
|
|
"SFTLP32",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
} else if (instruction->lop == LOP_NOT) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = (~%s) %s %s",
|
|
"SFTLP32",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = (%s %s %s) %s %s",
|
|
"SFTLP32",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
LOP[instruction->lop],
|
|
src1,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_stm(struct pvr_stm *instruction,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[32];
|
|
char src1[32];
|
|
char src2[32];
|
|
char src3[32];
|
|
|
|
char stm_pred[64];
|
|
|
|
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
|
pvr_pds_disassemble_operand(instruction->src3, src3, sizeof(src3));
|
|
|
|
if (instruction->ccs_global)
|
|
snprintf(stm_pred, sizeof(stm_pred), "overflow_any");
|
|
else if (instruction->ccs_so)
|
|
snprintf(stm_pred, sizeof(stm_pred), "overflow_current");
|
|
else
|
|
stm_pred[0] = 0;
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s%s stm%u = %s, %s, %s, %s",
|
|
"STM",
|
|
instruction->cc ? "? " : "",
|
|
stm_pred,
|
|
instruction->tst ? " (TST only)" : "",
|
|
instruction->stream_out,
|
|
src0,
|
|
src1,
|
|
src2,
|
|
src3);
|
|
}
|
|
|
|
static void pds_disassemble_instruction_stmc(struct pvr_stmc *instruction,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[32];
|
|
|
|
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s %s",
|
|
"STMC",
|
|
instruction->cc ? "? " : "",
|
|
src0);
|
|
}
|
|
|
|
static void
|
|
pvr_pds_disassemble_instruction_sftlp64(struct pvr_sftlp *instruction,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char dst[32];
|
|
char src0[32];
|
|
char src1[32];
|
|
char src2[32];
|
|
|
|
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
|
|
|
|
if (instruction->IM)
|
|
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
|
|
else
|
|
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
|
|
|
if (instruction->lop == LOP_NONE) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %s %s %s",
|
|
"SFTLP64",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
} else if (instruction->lop == LOP_NOT) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = (~%s) %s %s",
|
|
"SFTLP64",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = (%s %s %s) %s %s",
|
|
"SFTLP64",
|
|
instruction->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
LOP[instruction->lop],
|
|
src1,
|
|
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
|
src2);
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_cmp(struct pvr_cmp *cmp,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[32];
|
|
char src1[32];
|
|
static const char *const COP[] = { "=", ">", "<", "!=" };
|
|
|
|
pvr_pds_disassemble_operand(cmp->src0, src0, sizeof(src0));
|
|
|
|
if (cmp->IM) {
|
|
snprintf(src1,
|
|
sizeof(src1),
|
|
"%#04llx",
|
|
(unsigned long long)cmp->src1->literal);
|
|
} else {
|
|
pvr_pds_disassemble_operand(cmp->src1, src1, sizeof(src1));
|
|
}
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%sP0 = (%s %s %s)",
|
|
"CMP",
|
|
cmp->cc ? "? " : "",
|
|
src0,
|
|
COP[cmp->cop],
|
|
src1);
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_ldst(struct pvr_ldst *ins,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
|
|
|
pvr_pds_disassemble_operand(ins->src0, src0, sizeof(src0));
|
|
|
|
if (ins->st) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s: mem(%s) <= src(%s)",
|
|
"ST",
|
|
ins->cc ? "? " : "",
|
|
src0,
|
|
"?",
|
|
"?");
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s: dst(%s) <= mem(%s)",
|
|
"ld",
|
|
ins->cc ? "? " : "",
|
|
src0,
|
|
"?",
|
|
"?");
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_simple(struct pvr_simple *simple,
|
|
const char *type,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
snprintf(instr_str, instr_len, "%-16s%s", type, simple->cc ? "? " : "");
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_limm(struct pvr_limm *limm,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
int32_t imm = (uint32_t)limm->src0->literal;
|
|
char dst[PVR_PDS_MAX_INST_STR_LEN];
|
|
|
|
pvr_pds_disassemble_operand(limm->dst, dst, sizeof(dst));
|
|
|
|
if (limm->GR) {
|
|
char *pchGReg;
|
|
|
|
switch (imm) {
|
|
case 0:
|
|
pchGReg = "cluster";
|
|
break;
|
|
case 1:
|
|
pchGReg = "instance";
|
|
break;
|
|
default:
|
|
pchGReg = "unknown";
|
|
}
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = G%d (%s)",
|
|
"LIMM",
|
|
limm->cc ? "? " : "",
|
|
dst,
|
|
imm,
|
|
pchGReg);
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %#04x",
|
|
"LIMM",
|
|
limm->cc ? "? " : "",
|
|
dst,
|
|
imm);
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_ddmad(struct pvr_ddmad *ddmad,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src2[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src3[PVR_PDS_MAX_INST_STR_LEN];
|
|
|
|
pvr_pds_disassemble_operand(ddmad->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(ddmad->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(ddmad->src2, src2, sizeof(src2));
|
|
pvr_pds_disassemble_operand(ddmad->src3, src3, sizeof(src3));
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%sdoutd = (%s * %s) + %s, %s%s",
|
|
"DDMAD",
|
|
ddmad->cc ? "? " : "",
|
|
src0,
|
|
src1,
|
|
src2,
|
|
src3,
|
|
ddmad->END ? "; HALT" : "");
|
|
}
|
|
|
|
static void pvr_pds_disassemble_predicate(uint32_t predicate,
|
|
char *buffer,
|
|
size_t buffer_length)
|
|
{
|
|
switch (predicate) {
|
|
case PVR_ROGUE_PDSINST_PREDICATE_P0:
|
|
snprintf(buffer, buffer_length, "%s", "p0");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_IF0:
|
|
snprintf(buffer, buffer_length, "%s", "if0");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_IF1:
|
|
snprintf(buffer, buffer_length, "%s", "if1");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_0:
|
|
snprintf(buffer, buffer_length, "%s", "so_overflow_0");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_1:
|
|
snprintf(buffer, buffer_length, "%s", "so_overflow_1");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_2:
|
|
snprintf(buffer, buffer_length, "%s", "so_overflow_2");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_3:
|
|
snprintf(buffer, buffer_length, "%s", "so_overflow_3");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_GLOBAL:
|
|
snprintf(buffer, buffer_length, "%s", "so_overflow_any");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_KEEP:
|
|
snprintf(buffer, buffer_length, "%s", "keep");
|
|
break;
|
|
case PVR_ROGUE_PDSINST_PREDICATE_OOB:
|
|
snprintf(buffer, buffer_length, "%s", "oob");
|
|
break;
|
|
default:
|
|
snprintf(buffer, buffer_length, "%s", "<ERROR>");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_bra(struct pvr_bra *bra,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char setc_pred[32];
|
|
char srcc_pred[32];
|
|
|
|
pvr_pds_disassemble_predicate(bra->srcc->predicate,
|
|
srcc_pred,
|
|
sizeof(srcc_pred));
|
|
pvr_pds_disassemble_predicate(bra->setc->predicate,
|
|
setc_pred,
|
|
sizeof(setc_pred));
|
|
|
|
if (bra->setc->predicate != PVR_ROGUE_PDSINST_PREDICATE_KEEP) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16sif %s%s %d ( setc = %s )",
|
|
"BRA",
|
|
bra->srcc->negate ? "! " : "",
|
|
srcc_pred,
|
|
bra->address,
|
|
setc_pred);
|
|
} else {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16sif %s%s %d",
|
|
"BRA",
|
|
bra->srcc->negate ? "! " : "",
|
|
srcc_pred,
|
|
bra->address);
|
|
}
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_mad(struct pvr_mad *mad,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src2[PVR_PDS_MAX_INST_STR_LEN];
|
|
char dst[PVR_PDS_MAX_INST_STR_LEN];
|
|
|
|
pvr_pds_disassemble_operand(mad->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(mad->src1, src1, sizeof(src1));
|
|
pvr_pds_disassemble_operand(mad->src2, src2, sizeof(src2));
|
|
pvr_pds_disassemble_operand(mad->dst, dst, sizeof(dst));
|
|
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = (%s * %s) %s %s%s",
|
|
"MAD",
|
|
mad->cc ? "? " : "",
|
|
dst,
|
|
src0,
|
|
src1,
|
|
mad->sna ? "-" : "+",
|
|
src2,
|
|
mad->alum ? " [signed]" : "");
|
|
}
|
|
|
|
static void pvr_pds_disassemble_instruction_dout(struct pvr_dout *dout,
|
|
char *instr_str,
|
|
size_t instr_len)
|
|
{
|
|
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
|
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
|
|
|
#define X(dout_dst, str) #str,
|
|
static const char *const dst[] = { PVR_PDS_DOUT_DSTS };
|
|
#undef X
|
|
|
|
pvr_pds_disassemble_operand(dout->src0, src0, sizeof(src0));
|
|
pvr_pds_disassemble_operand(dout->src1, src1, sizeof(src1));
|
|
|
|
{
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"%-16s%s%s = %s, %s%s",
|
|
"DOUT",
|
|
dout->cc ? "? " : "",
|
|
dst[dout->dst],
|
|
src0,
|
|
src1,
|
|
dout->END ? "; HALT" : "");
|
|
}
|
|
}
|
|
|
|
void pvr_pds_disassemble_instruction(char *instr_str,
|
|
size_t instr_len,
|
|
struct pvr_instruction *instruction)
|
|
{
|
|
if (!instruction) {
|
|
snprintf(instr_str,
|
|
instr_len,
|
|
"Instruction was not disassembled properly\n");
|
|
return;
|
|
}
|
|
|
|
switch (instruction->type) {
|
|
case INS_LIMM:
|
|
pvr_pds_disassemble_instruction_limm((struct pvr_limm *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_ADD64:
|
|
pvr_pds_disassemble_instruction_add64((struct pvr_add *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_ADD32:
|
|
pvr_pds_disassemble_instruction_add32((struct pvr_add *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_CMP:
|
|
pvr_pds_disassemble_instruction_cmp((struct pvr_cmp *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_MAD:
|
|
pvr_pds_disassemble_instruction_mad((struct pvr_mad *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_BRA:
|
|
pvr_pds_disassemble_instruction_bra((struct pvr_bra *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_DDMAD:
|
|
pvr_pds_disassemble_instruction_ddmad((struct pvr_ddmad *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_DOUT:
|
|
pvr_pds_disassemble_instruction_dout((struct pvr_dout *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_LD:
|
|
case INS_ST:
|
|
pvr_pds_disassemble_instruction_ldst((struct pvr_ldst *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_WDF:
|
|
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
|
"WDF",
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_LOCK:
|
|
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
|
"LOCK",
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_RELEASE:
|
|
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
|
"RELEASE",
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_HALT:
|
|
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
|
"HALT",
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_NOP:
|
|
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
|
"NOP",
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_SFTLP32:
|
|
pvr_pds_disassemble_instruction_sftlp32((struct pvr_sftlp *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_SFTLP64:
|
|
pvr_pds_disassemble_instruction_sftlp64((struct pvr_sftlp *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_STM:
|
|
pvr_pds_disassemble_instruction_stm((struct pvr_stm *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
case INS_STMC:
|
|
pds_disassemble_instruction_stmc((struct pvr_stmc *)instruction,
|
|
instr_str,
|
|
instr_len);
|
|
break;
|
|
default:
|
|
snprintf(instr_str, instr_len, "Printing not implemented\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if defined(DUMP_PDS)
|
|
void pvr_pds_print_instruction(uint32_t instr)
|
|
{
|
|
char instruction_str[1024];
|
|
struct pvr_instruction *decoded =
|
|
pvr_pds_disassemble_instruction2(0, 0, instr);
|
|
|
|
if (!decoded) {
|
|
mesa_logd("%X\n", instr);
|
|
} else {
|
|
pvr_pds_disassemble_instruction(instruction_str,
|
|
sizeof(instruction_str),
|
|
decoded);
|
|
mesa_logd("\t0x%08x, /* %s */\n", instr, instruction_str);
|
|
}
|
|
}
|
|
#endif
|