2
* Copyright © 2022 Imagination Technologies Ltd.
4
* Permission is hereby granted, free of charge, to any person obtaining a copy
5
* of this software and associated documentation files (the "Software"), to deal
6
* in the Software without restriction, including without limitation the rights
7
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
* copies of the Software, and to permit persons to whom the Software is
9
* furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
#include "pvr_rogue_pds_defs.h"
30
#include "pvr_rogue_pds_disasm.h"
31
#include "pvr_rogue_pds_encode.h"
34
#define X(lop, str) #str,
35
static const char *const LOP[] = { PVR_PDS_LOP };
38
static void pvr_pds_disassemble_operand(struct pvr_operand *op,
42
#define X(enum, str, size) { #str, #size },
43
static const char *const regs[][2] = { PVR_PDS_OPERAND_TYPES };
46
if (op->type == LITERAL_NUM) {
51
(unsigned long long)op->literal);
52
} else if (op->type == UNRESOLVED) {
53
snprintf(instr_str, instr_len, "UNRESOLVED");
64
static void pvr_pds_disassemble_instruction_add64(struct pvr_add *add,
72
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
73
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
74
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
78
"%-16s%s%s = %s %s %s %s",
85
add->alum ? "[signed]" : "");
88
static void pvr_pds_disassemble_instruction_add32(struct pvr_add *add,
96
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
97
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
98
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
102
"%-16s%s%s = %s %s %s %s",
107
add->sna ? "-" : "+",
109
add->alum ? "[signed]" : "");
113
pvr_pds_disassemble_instruction_sftlp32(struct pvr_sftlp *instruction,
122
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
123
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
124
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
127
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
129
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
131
if (instruction->lop == LOP_NONE) {
134
"%-16s%s%s = %s %s %s",
136
instruction->cc ? "? " : "",
139
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
141
} else if (instruction->lop == LOP_NOT) {
144
"%-16s%s%s = (~%s) %s %s",
146
instruction->cc ? "? " : "",
149
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
154
"%-16s%s%s = (%s %s %s) %s %s",
156
instruction->cc ? "? " : "",
159
LOP[instruction->lop],
161
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
166
static void pvr_pds_disassemble_instruction_stm(struct pvr_stm *instruction,
177
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
178
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
179
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
180
pvr_pds_disassemble_operand(instruction->src3, src3, sizeof(src3));
182
if (instruction->ccs_global)
183
snprintf(stm_pred, sizeof(stm_pred), "overflow_any");
184
else if (instruction->ccs_so)
185
snprintf(stm_pred, sizeof(stm_pred), "overflow_current");
191
"%-16s%s%s%s stm%u = %s, %s, %s, %s",
193
instruction->cc ? "? " : "",
195
instruction->tst ? " (TST only)" : "",
196
instruction->stream_out,
203
static void pds_disassemble_instruction_stmc(struct pvr_stmc *instruction,
209
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
215
instruction->cc ? "? " : "",
220
pvr_pds_disassemble_instruction_sftlp64(struct pvr_sftlp *instruction,
229
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
230
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
231
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
234
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
236
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
238
if (instruction->lop == LOP_NONE) {
241
"%-16s%s%s = %s %s %s",
243
instruction->cc ? "? " : "",
246
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
248
} else if (instruction->lop == LOP_NOT) {
251
"%-16s%s%s = (~%s) %s %s",
253
instruction->cc ? "? " : "",
256
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
261
"%-16s%s%s = (%s %s %s) %s %s",
263
instruction->cc ? "? " : "",
266
LOP[instruction->lop],
268
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
273
static void pvr_pds_disassemble_instruction_cmp(struct pvr_cmp *cmp,
279
static const char *const COP[] = { "=", ">", "<", "!=" };
281
pvr_pds_disassemble_operand(cmp->src0, src0, sizeof(src0));
287
(unsigned long long)cmp->src1->literal);
289
pvr_pds_disassemble_operand(cmp->src1, src1, sizeof(src1));
294
"%-16s%sP0 = (%s %s %s)",
302
static void pvr_pds_disassemble_instruction_ldst(struct pvr_ldst *ins,
306
char src0[PVR_PDS_MAX_INST_STR_LEN];
308
pvr_pds_disassemble_operand(ins->src0, src0, sizeof(src0));
313
"%-16s%s%s: mem(%s) <= src(%s)",
322
"%-16s%s%s: dst(%s) <= mem(%s)",
331
static void pvr_pds_disassemble_simple(struct pvr_simple *simple,
336
snprintf(instr_str, instr_len, "%-16s%s", type, simple->cc ? "? " : "");
339
static void pvr_pds_disassemble_instruction_limm(struct pvr_limm *limm,
343
int32_t imm = (uint32_t)limm->src0->literal;
344
char dst[PVR_PDS_MAX_INST_STR_LEN];
346
pvr_pds_disassemble_operand(limm->dst, dst, sizeof(dst));
356
pchGReg = "instance";
364
"%-16s%s%s = G%d (%s)",
366
limm->cc ? "? " : "",
375
limm->cc ? "? " : "",
381
static void pvr_pds_disassemble_instruction_ddmad(struct pvr_ddmad *ddmad,
385
char src0[PVR_PDS_MAX_INST_STR_LEN];
386
char src1[PVR_PDS_MAX_INST_STR_LEN];
387
char src2[PVR_PDS_MAX_INST_STR_LEN];
388
char src3[PVR_PDS_MAX_INST_STR_LEN];
390
pvr_pds_disassemble_operand(ddmad->src0, src0, sizeof(src0));
391
pvr_pds_disassemble_operand(ddmad->src1, src1, sizeof(src1));
392
pvr_pds_disassemble_operand(ddmad->src2, src2, sizeof(src2));
393
pvr_pds_disassemble_operand(ddmad->src3, src3, sizeof(src3));
397
"%-16s%sdoutd = (%s * %s) + %s, %s%s",
399
ddmad->cc ? "? " : "",
404
ddmad->END ? "; HALT" : "");
407
static void pvr_pds_disassemble_predicate(uint32_t predicate,
409
size_t buffer_length)
412
case PVR_ROGUE_PDSINST_PREDICATE_P0:
413
snprintf(buffer, buffer_length, "%s", "p0");
415
case PVR_ROGUE_PDSINST_PREDICATE_IF0:
416
snprintf(buffer, buffer_length, "%s", "if0");
418
case PVR_ROGUE_PDSINST_PREDICATE_IF1:
419
snprintf(buffer, buffer_length, "%s", "if1");
421
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_0:
422
snprintf(buffer, buffer_length, "%s", "so_overflow_0");
424
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_1:
425
snprintf(buffer, buffer_length, "%s", "so_overflow_1");
427
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_2:
428
snprintf(buffer, buffer_length, "%s", "so_overflow_2");
430
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_3:
431
snprintf(buffer, buffer_length, "%s", "so_overflow_3");
433
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_GLOBAL:
434
snprintf(buffer, buffer_length, "%s", "so_overflow_any");
436
case PVR_ROGUE_PDSINST_PREDICATE_KEEP:
437
snprintf(buffer, buffer_length, "%s", "keep");
439
case PVR_ROGUE_PDSINST_PREDICATE_OOB:
440
snprintf(buffer, buffer_length, "%s", "oob");
443
snprintf(buffer, buffer_length, "%s", "<ERROR>");
448
static void pvr_pds_disassemble_instruction_bra(struct pvr_bra *bra,
455
pvr_pds_disassemble_predicate(bra->srcc->predicate,
458
pvr_pds_disassemble_predicate(bra->setc->predicate,
462
if (bra->setc->predicate != PVR_ROGUE_PDSINST_PREDICATE_KEEP) {
465
"%-16sif %s%s %d ( setc = %s )",
467
bra->srcc->negate ? "! " : "",
476
bra->srcc->negate ? "! " : "",
482
static void pvr_pds_disassemble_instruction_mad(struct pvr_mad *mad,
486
char src0[PVR_PDS_MAX_INST_STR_LEN];
487
char src1[PVR_PDS_MAX_INST_STR_LEN];
488
char src2[PVR_PDS_MAX_INST_STR_LEN];
489
char dst[PVR_PDS_MAX_INST_STR_LEN];
491
pvr_pds_disassemble_operand(mad->src0, src0, sizeof(src0));
492
pvr_pds_disassemble_operand(mad->src1, src1, sizeof(src1));
493
pvr_pds_disassemble_operand(mad->src2, src2, sizeof(src2));
494
pvr_pds_disassemble_operand(mad->dst, dst, sizeof(dst));
498
"%-16s%s%s = (%s * %s) %s %s%s",
504
mad->sna ? "-" : "+",
506
mad->alum ? " [signed]" : "");
509
static void pvr_pds_disassemble_instruction_dout(struct pvr_dout *dout,
513
char src0[PVR_PDS_MAX_INST_STR_LEN];
514
char src1[PVR_PDS_MAX_INST_STR_LEN];
516
#define X(dout_dst, str) #str,
517
static const char *const dst[] = { PVR_PDS_DOUT_DSTS };
520
pvr_pds_disassemble_operand(dout->src0, src0, sizeof(src0));
521
pvr_pds_disassemble_operand(dout->src1, src1, sizeof(src1));
526
"%-16s%s%s = %s, %s%s",
528
dout->cc ? "? " : "",
532
dout->END ? "; HALT" : "");
536
void pvr_pds_disassemble_instruction(char *instr_str,
538
struct pvr_instruction *instruction)
543
"Instruction was not disassembled properly\n");
547
switch (instruction->type) {
549
pvr_pds_disassemble_instruction_limm((struct pvr_limm *)instruction,
554
pvr_pds_disassemble_instruction_add64((struct pvr_add *)instruction,
559
pvr_pds_disassemble_instruction_add32((struct pvr_add *)instruction,
564
pvr_pds_disassemble_instruction_cmp((struct pvr_cmp *)instruction,
569
pvr_pds_disassemble_instruction_mad((struct pvr_mad *)instruction,
574
pvr_pds_disassemble_instruction_bra((struct pvr_bra *)instruction,
579
pvr_pds_disassemble_instruction_ddmad((struct pvr_ddmad *)instruction,
584
pvr_pds_disassemble_instruction_dout((struct pvr_dout *)instruction,
590
pvr_pds_disassemble_instruction_ldst((struct pvr_ldst *)instruction,
595
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
601
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
607
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
613
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
619
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
625
pvr_pds_disassemble_instruction_sftlp32((struct pvr_sftlp *)instruction,
630
pvr_pds_disassemble_instruction_sftlp64((struct pvr_sftlp *)instruction,
635
pvr_pds_disassemble_instruction_stm((struct pvr_stm *)instruction,
640
pds_disassemble_instruction_stmc((struct pvr_stmc *)instruction,
645
snprintf(instr_str, instr_len, "Printing not implemented\n");
650
#if defined(DUMP_PDS)
651
void pvr_pds_print_instruction(uint32_t instr)
653
char instruction_str[1024];
654
struct pvr_instruction *decoded =
655
pvr_pds_disassemble_instruction2(0, 0, instr);
658
mesa_logd("%X\n", instr);
660
pvr_pds_disassemble_instruction(instruction_str,
661
sizeof(instruction_str),
663
mesa_logd("\t0x%08x, /* %s */\n", instr, instruction_str);