Files
Michael Fabian 'Xaymar' Dirks c4947bd12a compiler: Move and modernize
compiler is blitzcc, what I previously called compiler is now compiler_lib
2019-01-19 18:28:07 +01:00

195 lines
3.6 KiB
C++

/*
This generates a source code file for x86 instruction formats.
Thanks NASM!
*/
#include <conio.h>
#include <fstream>
#include <iostream>
#include <string>
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();
}