capstone/suite/synctools/strinforeduce/strinforeduce.cpp

184 lines
4.5 KiB
C++

// 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;
}