/* This generates a source code file for x86 instruction formats. Thanks NASM! */ #include #include #include #include using namespace std; static const char* optype(const string& s) { if (s == "AL") return "AL"; if (s == "AX") return "AX"; if (s == "EAX") return "EAX"; if (s == "CL") return "CL"; if (s == "CX") return "CX"; if (s == "ECX") return "ECX"; if (s == "imm") return "IMM"; if (s == "imm8") return "IMM8"; if (s == "imm16") return "IMM16"; if (s == "imm32") return "IMM32"; if (s == "reg") return "REG"; if (s == "reg8") return "REG8"; if (s == "reg16") return "REG16"; if (s == "reg32") return "REG32"; if (s == "mem") return "MEM"; if (s == "mem8") return "MEM8"; if (s == "mem16") return "MEM16"; if (s == "mem32") return "MEM32"; if (s == "r/m") return "R_M"; if (s == "r/m8") return "R_M8"; if (s == "r/m16") return "R_M16"; if (s == "r/m32") return "R_M32"; if (s == "fpureg") return "FPUREG"; if (s == "ST0") return "ST0"; return 0; } void __cdecl main() { string name, lhs, rhs, byte, bytes, flags, last; ifstream in("nasm_insts.txt"); ofstream out("insts.cpp"); out << "//\n//This is generated code - do not modify!!!!!\n//\n"; out << "\n#include \"insts.hpp\"\n\n"; out << "Inst insts[]={\n"; for (; !in.eof(); in.ignore(INT_MAX, '\n')) { name.resize(0); in >> name; if (!name.size() || name[0] == '/') continue; lhs.resize(0); rhs.resize(0); const char *lop = "NONE", *rop = "NONE"; while (isspace(in.peek())) in.get(); getline(in, lhs, ';'); if (int i = lhs.size()) { while (i && isspace(lhs[i - 1])) --i; if (i) { lhs.resize(i); i = lhs.find(','); if (i != string::npos) { rhs = lhs.substr(i + 1); lhs = lhs.substr(0, i); } lop = optype(lhs); if (!lop) continue; if (rhs.size() && !(rop = optype(rhs))) continue; } } bytes.resize(0); flags = '0'; bool fail = false; while (!fail) { in >> byte; if (byte[0] == '[') break; if (byte == "/r") flags += "|_R"; else if (byte == "/0") flags += "|_0"; else if (byte == "/1") flags += "|_1"; else if (byte == "/2") flags += "|_2"; else if (byte == "/3") flags += "|_3"; else if (byte == "/4") flags += "|_4"; else if (byte == "/5") flags += "|_5"; else if (byte == "/6") flags += "|_6"; else if (byte == "/7") flags += "|_7"; else if (byte == "o16") flags += "|O16"; else if (byte == "o32") flags += "|O32"; else if (byte == "ow/od") flags += "|OW_OD"; else if (byte == "ib") flags += "|IB"; else if (byte == "iw") flags += "|IW"; else if (byte == "id") flags += "|ID"; else if (byte == "rw/rd") flags += "|RW_RD"; else if (isxdigit(byte[0])) { string sub = byte.substr(2); if (sub.size()) { if (sub == "+r") flags += "|PLUSREG"; else if (sub == "+cc") flags += "|PLUSCC"; else fail = true; } bytes = bytes + "\\x" + byte[0] + byte[1]; } else fail = true; } if (fail) continue; if (flags.find("0|") == 0) flags = flags.substr(2); for (size_t k = 0; k < name.size(); ++k) name[k] = tolower(name[k]); if (name == last) name = "0"; else { last = name; name = '\"' + name + '\"'; } char bf[4]; _itoa(bytes.size() / 3, bf, 16); bytes = "\\x" + string(bf) + bytes; out << name << ',' << lop << ',' << rop << ',' << flags << ",\"" << bytes << "\",\n"; } out << "\"\",0,0,0,0\n};\n"; out.flush(); out.close(); cout << "All done!\n"; _getch(); }