blitz3d/asm_makeinsts/main.cpp

140 lines
3.3 KiB
C++

/*
This generates a source code file for x86 instruction formats.
Thanks NASM!
*/
#include <conio.h>
#include <string>
#include <fstream>
#include <iostream>
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 main(){
string name,lhs,rhs,byte,bytes,flags,last;
ifstream in( "nasm_insts.txt" );
ofstream out( "..\\compiler\\assem_x86\\asm_insts.cpp" );
out<<"//\n//This is generated code - do not modify!!!!!\n//\n";
out<<"\n#include \"..\\std.h\"\n\n";
out<<"\n#include \"insts.h\"\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( int 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();
}