aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/suite/synctools/strinforeduce
diff options
context:
space:
mode:
Diffstat (limited to 'capstone/suite/synctools/strinforeduce')
-rw-r--r--capstone/suite/synctools/strinforeduce/Makefile10
-rw-r--r--capstone/suite/synctools/strinforeduce/README15
-rwxr-xr-xcapstone/suite/synctools/strinforeduce/instrinfo2.py55
-rw-r--r--capstone/suite/synctools/strinforeduce/strinforeduce.cpp183
4 files changed, 263 insertions, 0 deletions
diff --git a/capstone/suite/synctools/strinforeduce/Makefile b/capstone/suite/synctools/strinforeduce/Makefile
new file mode 100644
index 000000000..d533f9a11
--- /dev/null
+++ b/capstone/suite/synctools/strinforeduce/Makefile
@@ -0,0 +1,10 @@
+all: full reduce
+
+full:
+ g++ strinforeduce.cpp -o strinforeduce
+
+reduce:
+ g++ -DCAPSTONE_X86_REDUCE strinforeduce.cpp -o strinforeduce_reduce
+
+clean:
+ rm -rf strinforeduce strinforeduce_reduce
diff --git a/capstone/suite/synctools/strinforeduce/README b/capstone/suite/synctools/strinforeduce/README
new file mode 100644
index 000000000..e4ba5cf9d
--- /dev/null
+++ b/capstone/suite/synctools/strinforeduce/README
@@ -0,0 +1,15 @@
+- Run instroinfo2.py on X86GenInstrInfo.inc & X86GenInstrInfo_reduce.inc
+
+ $ ./instrinfo2.py ../tablegen/X86GenInstrInfo.inc > X86GenInstrInfo.inc
+ $ ./instrinfo2.py ../tablegen/X86GenInstrInfo_reduce.inc > X86GenInstrInfo_reduce.inc
+
+- Compile
+
+ $ make
+
+- Run
+
+ $ ./strinforeduce > X86Lookup16.inc
+ $ ./strinforeduce_reduce > X86Lookup16_reduce.inc
+
+- Then copy X86Lookup16*.inc to Capstone dir arch/X86/
diff --git a/capstone/suite/synctools/strinforeduce/instrinfo2.py b/capstone/suite/synctools/strinforeduce/instrinfo2.py
new file mode 100755
index 000000000..6c52bdcd7
--- /dev/null
+++ b/capstone/suite/synctools/strinforeduce/instrinfo2.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+# convert LLVM GenInstrInfo.inc for Capstone disassembler.
+# by Nguyen Anh Quynh, 2019
+
+import sys
+
+if len(sys.argv) == 1:
+ print("Syntax: %s <GenInstrInfo.inc>" %sys.argv[0])
+ sys.exit(1)
+
+
+count = 0
+last_line = None
+
+f = open(sys.argv[1])
+lines = f.readlines()
+f.close()
+
+# 1st enum is register enum
+for line in lines:
+ line = line.rstrip()
+
+ # skip all MCPhysReg line
+ if 'static const MCPhysReg ' in line:
+ continue
+
+ # skip all MCOperandInfo line
+ if 'static const MCOperandInfo ' in line:
+ continue
+
+ # skip InitX86MCInstrInfo()
+ if 'static inline void InitX86MCInstrInfo' in line:
+ continue
+
+ if 'II->InitMCInstrInfo' in line:
+ last_line = line
+ continue
+
+ # skip the next line after II->InitMCInstrInfo
+ if last_line:
+ last_line = None
+ continue
+
+
+ if 'extern const MCInstrDesc ' in line:
+ count += 1
+ continue
+
+ if count == 1:
+ if line == '};':
+ # done with first enum
+ count += 1
+ continue
+ else:
+ print(line)
diff --git a/capstone/suite/synctools/strinforeduce/strinforeduce.cpp b/capstone/suite/synctools/strinforeduce/strinforeduce.cpp
new file mode 100644
index 000000000..e44110520
--- /dev/null
+++ b/capstone/suite/synctools/strinforeduce/strinforeduce.cpp
@@ -0,0 +1,183 @@
+// By Martin Tofall, Obsidium Software
+#define GET_INSTRINFO_ENUM
+#define GET_INSTRINFO_MC_DESC
+
+#ifdef CAPSTONE_X86_REDUCE
+#include "X86GenInstrInfo_reduce.inc"
+#else
+#include "X86GenInstrInfo.inc"
+#endif
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string>
+
+static const char *x86DisassemblerGetInstrName(unsigned Opcode)
+{
+ return &llvm::X86InstrNameData[llvm::X86InstrNameIndices[Opcode]];
+}
+
+static bool is16BitEquivalent(const char* orig, const char* equiv)
+{
+ size_t i;
+
+ for (i = 0;; i++) {
+ if (orig[i] == '\0' && equiv[i] == '\0')
+ return true;
+
+ if (orig[i] == '\0' || equiv[i] == '\0')
+ return false;
+
+ if (orig[i] != equiv[i]) {
+ if ((orig[i] == 'Q' || orig[i] == 'L') && equiv[i] == 'W')
+ continue;
+
+ if ((orig[i] == '6' || orig[i] == '3') && equiv[i] == '1')
+ continue;
+
+ if ((orig[i] == '4' || orig[i] == '2') && equiv[i] == '6')
+ continue;
+
+ return false;
+ }
+ }
+}
+
+// static const char *header = "#ifdef GET_INSTRINFO_MC_DESC\n#undef GET_INSTRINFO_MC_DESC\n\n"
+static const char *header =
+ "typedef struct x86_op_id_pair {\n"\
+ "\tuint16_t first;\n" \
+ "\tuint16_t second;\n" \
+ "} x86_op_id_pair;\n\n" \
+ "static const x86_op_id_pair x86_16_bit_eq_tbl[] = {\n";
+static const char *footer = "};\n\n";
+
+static const char *header_lookup = "static const uint16_t x86_16_bit_eq_lookup[] = {\n";
+//static const char *footer_lookup = "};\n\n#endif\n";
+static const char *footer_lookup = "};\n";
+
+static bool is16BitEquivalent_old(unsigned id1, unsigned id2)
+{
+ return (is16BitEquivalent(x86DisassemblerGetInstrName(id1), x86DisassemblerGetInstrName(id2))) != false;
+}
+
+//#include "reduced.h"
+
+#if 0
+static bool is16BitEquivalent_new(unsigned orig, unsigned equiv)
+{
+ size_t i;
+ uint16_t idx;
+
+ if (orig == equiv)
+ return true; // emulate old behaviour
+
+ if ((idx = x86_16_bit_eq_lookup[orig]) != 0) {
+ for (i = idx - 1; x86_16_bit_eq_tbl[i].first == orig; ++i) {
+ if (x86_16_bit_eq_tbl[i].second == equiv)
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif
+
+int main()
+{
+ size_t size_names = sizeof(llvm::X86InstrNameData);
+ size_t size_indices = sizeof(llvm::X86InstrNameIndices);
+ size_t size_total = size_names + size_indices;
+
+#if 1
+ printf("%s", header);
+
+ size_t eq_count = 0;
+ std::string str_lookup;
+ bool got_i = false;
+
+ for (size_t i = 0; i < llvm::X86::INSTRUCTION_LIST_END; ++i) {
+ const char *name1 = x86DisassemblerGetInstrName(i);
+ for (size_t j = 0; j < llvm::X86::INSTRUCTION_LIST_END; ++j) {
+ const char *name2 = x86DisassemblerGetInstrName(j);
+ if (i != j && is16BitEquivalent(name1, name2) != false) {
+ //printf("Found equivalent %d and %d\n", i, j);
+ printf("\t{ %zu, %zu },\n", i, j);
+ if (!got_i) {
+ char buf[16];
+ sprintf(buf, "\t%zu,\n", eq_count + 1);
+ str_lookup += buf;
+
+ got_i = true;
+ }
+ ++eq_count;
+ }
+ }
+
+ if (!got_i) {
+ //char buf[32];
+ //sprintf(buf, "\t0, //%d\n", i);
+ //str_lookup += buf;
+ str_lookup += "\t0,\n";
+ }
+
+ // reset got_i
+ got_i = false;
+ }
+
+ printf("%s", footer);
+ printf("%s", header_lookup);
+ printf("%s", str_lookup.c_str());
+ printf("%s", footer_lookup);
+
+ // printf("%zu equivalents total\n", eq_count);
+ // size_t size_new = eq_count * 4 + llvm::X86::INSTRUCTION_LIST_END * 2;
+ // printf("before: %zu, after: %zu, %zu bytes saved\n", size_total, size_new, size_total - size_new);
+#endif
+
+#if 0
+ for (size_t i = 0; i < llvm::X86::INSTRUCTION_LIST_END; ++i) {
+ for (size_t j = 0; j < llvm::X86::INSTRUCTION_LIST_END; ++j) {
+ if (is16BitEquivalent_new(i, j) != is16BitEquivalent_old(i, j)) {
+ bool old_result = is16BitEquivalent_old(i, j);
+ bool new_result = is16BitEquivalent_new(i, j);
+ printf("ERROR!\n");
+ }
+ }
+ }
+#endif
+
+#if 0
+ static const size_t BENCH_LOOPS = 50;
+
+ size_t eq_count = 0;
+ DWORD time = GetTickCount();
+ for (size_t l = 0; l < BENCH_LOOPS; ++l) {
+ for (size_t i = 0; i < llvm::X86::INSTRUCTION_LIST_END; ++i) {
+ for (size_t j = 0; j < llvm::X86::INSTRUCTION_LIST_END; ++j)
+ if (is16BitEquivalent_new(i, j))
+ ++eq_count;
+ }
+ }
+
+ time = GetTickCount() - time;
+ printf("new: %f msecs\n", static_cast<float>(time) / static_cast<float>(BENCH_LOOPS));
+
+ eq_count = 0;
+ time = GetTickCount();
+ for (size_t l = 0; l < BENCH_LOOPS; ++l) {
+ for (size_t i = 0; i < llvm::X86::INSTRUCTION_LIST_END; ++i) {
+ for (size_t j = 0; j < llvm::X86::INSTRUCTION_LIST_END; ++j)
+ if (is16BitEquivalent_old(i, j))
+ ++eq_count;
+ }
+ }
+
+ time = GetTickCount() - time;
+ printf("old: %f msecs\n", static_cast<float>(time) / static_cast<float>(BENCH_LOOPS));
+#endif
+
+ return 0;
+}
+