diff options
Diffstat (limited to 'capstone/suite/synctools/strinforeduce')
-rw-r--r-- | capstone/suite/synctools/strinforeduce/Makefile | 10 | ||||
-rw-r--r-- | capstone/suite/synctools/strinforeduce/README | 15 | ||||
-rwxr-xr-x | capstone/suite/synctools/strinforeduce/instrinfo2.py | 55 | ||||
-rw-r--r-- | capstone/suite/synctools/strinforeduce/strinforeduce.cpp | 183 |
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; +} + |