summaryrefslogtreecommitdiff
path: root/arch/powerpc/test_asm.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2024-03-05 19:50:13 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2024-03-05 20:34:34 -0500
commite093c21ed880ac3eb72119be15093ee04f8ce299 (patch)
tree9f720ebdc0ae415734b1199ed341668c69710a94 /arch/powerpc/test_asm.cpp
parent0609276712622908254065546102381466033141 (diff)
Move architecture modules into the API repo
Diffstat (limited to 'arch/powerpc/test_asm.cpp')
-rw-r--r--arch/powerpc/test_asm.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/arch/powerpc/test_asm.cpp b/arch/powerpc/test_asm.cpp
new file mode 100644
index 00000000..7f391792
--- /dev/null
+++ b/arch/powerpc/test_asm.cpp
@@ -0,0 +1,184 @@
+/* this is meant to be linked up against assembler.cpp for stress test and
+ benchmarking
+
+g++ -std=c++11 -O0 -g -I capstone/include -L./build/capstone test_asm.cpp assembler.cpp -o test_asm -lcapstone
+
+*/
+
+/* */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+
+/* c++ stuff */
+#include <map>
+#include <string>
+#include <vector>
+using namespace std;
+
+/* capstone stuff */
+#include <capstone/capstone.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "assembler.h"
+
+/*****************************************************************************/
+/* main */
+/*****************************************************************************/
+
+#define TEST_ADDR 0xCAFEBAB0
+
+int main(int ac, char **av)
+{
+ int rc = -1;
+ uint32_t insWord = 0x800000A;
+ uint8_t encoding[4];
+
+ /* statistics crap */
+ string srcWorstTime, srcWorstFails;
+ clock_t t0, t1;
+ double tdelta, tavg=0, tsum=0, tworst=0;
+ int tcount = 0;
+ uint32_t insWordWorstTime, insWordWorstFails;
+ int failsWorst = 0;
+
+ srand(time(NULL));
+
+ /* decide mode */
+ #define MODE_FILE 0
+ #define MODE_RANDOM 1
+ #define MODE_SINGLE 2
+ int mode;
+ if(ac > 1) {
+ struct stat st;
+ stat(av[1], &st);
+ if(S_ISREG(st.st_mode)) {
+ printf("FILE MODE!\n");
+ mode = MODE_FILE;
+ }
+ else if(!strcmp(av[1], "random")) {
+ printf("RANDOM MODE!\n");
+ mode = MODE_RANDOM;
+ }
+ else {
+ printf("SINGLE MODE!\n");
+ mode = MODE_SINGLE;
+ }
+ }
+ else {
+ printf("need args!\n");
+ return -1;
+ }
+
+ if(mode == MODE_FILE) {
+ char *line;
+ string src, err;
+ size_t len;
+
+ /* read file */
+ FILE *fp = fopen(av[1], "r");
+ if(!fp) {
+ printf("ERROR: fopen(%s)\n", av[1]);
+ return -1;
+ }
+ while(getline(&line, &len, fp) != -1)
+ src += line;
+ fclose(fp);
+
+ /* assemble */
+ vector<uint8_t> result;
+ if(assemble_multiline(src, result, err)) {
+ printf("error: %s", err.c_str());
+ return -1;
+ }
+
+ /* result */
+ printf("result: ");
+ for(int i=0; i<result.size(); ++i)
+ printf("%02X ", result[i]);
+ printf("\n");
+
+ return 0;
+ }
+
+ if(mode == MODE_SINGLE) {
+ t0 = clock();
+
+ int failures;
+ string err;
+ if(assemble_single(av[1], TEST_ADDR, encoding, err, failures)) {
+ printf("ERROR: %s", err.c_str());
+ return -1;
+ }
+ tdelta = (double)(clock()-t0)/CLOCKS_PER_SEC;
+
+ printf("assemble_single() duration: %fs (%f assembles/sec)\n", tdelta, 1/tdelta);
+ printf("converged after %d failures\n", failures);
+
+ printf("result: ");
+ for(int i=0; i<4; ++i)
+ printf("%02X ", encoding[i]);
+ printf("\n");
+
+ return 0;
+ }
+
+ if(mode == MODE_RANDOM) {
+ int failures;
+ string src, err;
+
+ while(1) {
+ /* generate random word, disassemble with capstone */
+ insWord = (rand()<<16) | rand();
+ if(0 != disasm_capstone((uint8_t *)&insWord, TEST_ADDR, src, err)) {
+ printf("ERROR: %s\n", err.c_str());
+ return -1;
+ }
+ if(src == "undefined")
+ continue;
+ printf("%08X: %s\n", insWord, src.c_str());
+
+ /* try to assemble it back to the instruction word */
+ t0 = clock();
+ if(assemble_single(src, TEST_ADDR, encoding, err, failures)) {
+ printf("ERROR: %s", err.c_str());
+ return -1;
+ }
+
+ /* benchmarking */
+ tdelta = (double)(clock()-t0)/CLOCKS_PER_SEC;
+ tsum += tdelta;
+ tcount += 1;
+ tavg = tsum/tcount;
+ printf("assemble_single() duration: %fs, average: %fs (%f assembles/second)\n",
+ tdelta, tavg, 1/tavg);
+
+ if(tdelta > tworst) {
+ insWordWorstTime = insWord;
+ srcWorstTime = src;
+ tworst = tdelta;
+ }
+
+ if(failures > failsWorst) {
+ insWordWorstFails = insWord;
+ failsWorst = failures;
+ srcWorstFails = src;
+ }
+
+ printf("worst time: %f held by %08X: %s\n", tworst, insWordWorstTime, srcWorstTime.c_str());
+ printf("worst fails: %d held by %08X: %s\n", failsWorst, insWordWorstFails, srcWorstFails.c_str());
+ }
+
+ return 0;
+ }
+
+ rc = 0;
+ cleanup:
+ return rc;
+}
+