summaryrefslogtreecommitdiff
path: root/arch/powerpc/test_disasm.cpp
diff options
context:
space:
mode:
authorGalen Williamson <galen@vector35.com>2024-12-16 13:40:25 -0500
committerGalen Williamson <galen@vector35.com>2024-12-16 13:40:25 -0500
commit8ea98cab89afb0c14073141f30203486d1333b07 (patch)
treea749ae52d4c590c06876b0e02656ad811883b082 /arch/powerpc/test_disasm.cpp
parentb34ddd03f71c8637a80a264a3ea757b8295d482b (diff)
[ppc] merges PR Vector35/binaryninja-api#5176 (adds support for "psq" Quantized Floating Point instructions, fixes/completes 64-bit instruction/register support)
Diffstat (limited to 'arch/powerpc/test_disasm.cpp')
-rw-r--r--arch/powerpc/test_disasm.cpp78
1 files changed, 66 insertions, 12 deletions
diff --git a/arch/powerpc/test_disasm.cpp b/arch/powerpc/test_disasm.cpp
index 5ee7d1dd..cd70a6aa 100644
--- a/arch/powerpc/test_disasm.cpp
+++ b/arch/powerpc/test_disasm.cpp
@@ -15,22 +15,39 @@ g++ -std=c++11 -O0 -g -I capstone/include -L./build/capstone test_disasm.cpp dis
#include <stdlib.h>
#include <time.h>
+#include <unistd.h>
+
#include "disassembler.h"
int print_errors = 1;
+int cs_mode_local = 0;
+size_t address_size_ = 4;
+// data in default with strtoul is little endian
+bool littleendian = true;
int disas_instr_word(uint32_t instr_word, char *buf)
{
int rc = -1;
- struct decomp_result res;
+ struct decomp_result res = {0};
struct cs_insn *insn = &(res.insn);
struct cs_detail *detail = &(res.detail);
struct cs_ppc *ppc = &(detail->ppc);
- if(powerpc_decompose((const uint8_t *)&instr_word, 4, 0, true, &res, false)) {
- if(print_errors) printf("ERROR: powerpc_decompose()\n");
- goto cleanup;
+ if(powerpc_decompose((const uint8_t *)&instr_word, 4, 0, littleendian, &res, address_size_, cs_mode_local)) {
+ if(print_errors)
+ {
+ if (DoesQualifyForLocalDisassembly((uint8_t*)&instr_word, !littleendian) != PPC_INS_INVALID)
+ {
+ size_t instsz = 4;
+ PerformLocalDisassembly((uint8_t*)&instr_word, 0, instsz, &res, !littleendian);
+ }
+ else
+ {
+ printf("ERROR: powerpc_decompose()\n");
+ goto cleanup;
+ }
+ }
}
/* MEGA DETAILS, IF YOU WANT 'EM */
@@ -79,7 +96,7 @@ int disas_instr_word(uint32_t instr_word, char *buf)
printf("reg: %s\n", cs_reg_name(res.handle, op.reg));
break;
case PPC_OP_IMM:
- printf("imm: 0x%X\n", op.imm);
+ printf("imm: 0x%llx\n", op.imm);
break;
case PPC_OP_MEM:
printf("mem (%s + %d)\n", cs_reg_name(res.handle, op.mem.base),
@@ -106,21 +123,58 @@ int disas_instr_word(uint32_t instr_word, char *buf)
return rc;
}
+void usage(const char* av0)
+{
+ printf("usage: %s [-p] [-q] [-s] [-b] repl/send\n", av0);
+ printf("p for ppc_ps, q for ppc_qpx, s for ppc_spe\n");
+ printf("b for big endian interprettation\n");
+ printf("send argument \"repl\" or \"speed\"\n");
+}
+
int main(int ac, char **av)
{
int rc = -1;
char buf[256];
+ int index;
+ char* disasm_cmd = 0;
+ int c;
- #define BATCH 10000000
+#define BATCH 10000000
+ opterr = 0;
- powerpc_init();
+ while ((c = getopt(ac, av, "qspb")) != -1)
+ {
+ switch (c)
+ {
+ case 'q':
+ cs_mode_local = CS_MODE_QPX;
+ break;
+ case 's':
+ cs_mode_local = CS_MODE_SPE;
+ break;
+ case 'p':
+ cs_mode_local = CS_MODE_PS;
+ break;
+ case 'b':
+ littleendian = false;
+ break;
+ default:
+ usage(av[0]);
+ goto cleanup;
+ }
+ }
- if(ac <= 1) {
- printf("send argument \"repl\" or \"speed\"\n");
+ if (optind >= ac)
+ {
+ usage(av[0]);
goto cleanup;
}
- if(!strcasecmp(av[1], "repl")) {
+ disasm_cmd = av[optind];
+
+ powerpc_init(cs_mode_local);
+
+ if(!strcasecmp(disasm_cmd, "repl")) {
printf("REPL mode!\n");
printf("example inputs (write the words as if after endian fetch):\n");
printf("93e1fffc\n");
@@ -148,7 +202,7 @@ int main(int ac, char **av)
printf("%s\n", buf);
}
}
- else if(!strcasecmp(av[1], "speed")) {
+ else if(!strcasecmp(disasm_cmd, "speed")) {
printf("SPEED TEST THAT COUNTS QUICK RETURNS FROM BAD INSTRUCTIONS AS DISASSEMBLED\n");
print_errors = 0;
uint32_t instr_word = 0x780b3f7c;
@@ -167,7 +221,7 @@ int main(int ac, char **av)
printf("current rate: %f instructions per second\n", (float)BATCH/ellapsed);
}
}
- else if(!strcasecmp(av[1], "speed2")) {
+ else if(!strcasecmp(disasm_cmd, "speed2")) {
printf("SPEED TEST THAT IS GIVEN NO CREDIT FOR QUICK RETURNS FROM BAD INSTRUCTIONS\n");
print_errors = 0;
uint32_t instr_word = 0x780b3f7c;