Holy fucking shit I don't want to work on this. Sibly, you son of a ...

This commit is contained in:
Michael Fabain Dirks
2016-05-07 22:49:54 +02:00
parent b75ca4142c
commit aa22d21fb5
2577 changed files with 166501 additions and 194685 deletions
+159 -158
View File
@@ -4,270 +4,271 @@
#include "tile.h"
//reduce to 3 for stress test
static const int NUM_REGS=6;
static const int NUM_REGS = 6;
static const string regs[]=
{"???","eax","ecx","edx","edi","esi","ebx"};
static const string regs[] =
{ "???","eax","ecx","edx","edi","esi","ebx" };
//array of 'used' flags
static bool regUsed[NUM_REGS+1];
static bool regUsed[NUM_REGS + 1];
//size of locals in function
static int frameSize,maxFrameSize;
static int frameSize, maxFrameSize;
//code fragments
static vector<string> codeFrags,dataFrags;
static vector<string> codeFrags, dataFrags;
//name of function
static string funcLabel;
static void resetRegs(){
for( int n=1;n<=NUM_REGS;++n ) regUsed[n]=false;
static void resetRegs() {
for (int n = 1; n <= NUM_REGS; ++n) regUsed[n] = false;
}
static int allocReg( int n ){
if( !n || regUsed[n] ){
for( n=NUM_REGS;n>=1 && regUsed[n];--n ){}
if( !n ) return 0;
static int allocReg(int n) {
if (!n || regUsed[n]) {
for (n = NUM_REGS; n >= 1 && regUsed[n]; --n) {}
if (!n) return 0;
}
regUsed[n]=true;
regUsed[n] = true;
return n;
}
static void freeReg( int n ){
regUsed[n]=false;
static void freeReg(int n) {
regUsed[n] = false;
}
static void pushReg( int n ){
frameSize+=4;
if( frameSize>maxFrameSize ) maxFrameSize=frameSize;
char buff[32];itoa( frameSize,buff,10 );
string s="\tmov\t[ebp-";s+=buff;s+="],";s+=regs[n];s+='\n';
codeFrags.push_back( s );
static void pushReg(int n) {
frameSize += 4;
if (frameSize > maxFrameSize) maxFrameSize = frameSize;
char buff[32];
_itoa(frameSize, buff, 10);
string s = "\tmov\t[ebp-"; s += buff; s += "],"; s += regs[n]; s += '\n';
codeFrags.push_back(s);
}
static void popReg( int n ){
char buff[32];itoa( frameSize,buff,10 );
string s="\tmov\t";s+=regs[n];s+=",[ebp-";s+=buff;s+="]\n";
codeFrags.push_back( s );
frameSize-=4;
static void popReg(int n) {
char buff[32]; _itoa(frameSize, buff, 10);
string s = "\tmov\t"; s += regs[n]; s += ",[ebp-"; s += buff; s += "]\n";
codeFrags.push_back(s);
frameSize -= 4;
}
static void moveReg( int d,int s ){
string t="\tmov\t"+regs[d]+','+regs[s]+'\n';
codeFrags.push_back( t );
static void moveReg(int d, int s) {
string t = "\tmov\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t);
}
static void swapRegs( int d,int s ){
string t="\txchg\t"+regs[d]+','+regs[s]+'\n';
codeFrags.push_back( t );
static void swapRegs(int d, int s) {
string t = "\txchg\t" + regs[d] + ',' + regs[s] + '\n';
codeFrags.push_back(t);
}
Tile::Tile( const string &a,Tile *l,Tile *r )
:assem(a),l(l),r(r),want_l(0),want_r(0),hits(0),need(0),argFrame(0){
Tile::Tile(const string &a, Tile *l, Tile *r)
:assem(a), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) {
}
Tile::Tile( const string &a,const string &a2,Tile *l,Tile *r )
:assem(a),assem2(a2),l(l),r(r),want_l(0),want_r(0),hits(0),need(0),argFrame(0){
Tile::Tile(const string &a, const string &a2, Tile *l, Tile *r)
: assem(a), assem2(a2), l(l), r(r), want_l(0), want_r(0), hits(0), need(0), argFrame(0) {
}
Tile::~Tile(){
delete l;delete r;
Tile::~Tile() {
delete l; delete r;
}
void Tile::label(){
if( !l ){
need=1;
}else if( !r ){
void Tile::label() {
if (!l) {
need = 1;
} else if (!r) {
l->label();
need=l->need;
}else{
l->label();r->label();
if( l->need==r->need ) need=l->need+1;
else if( l->need>r->need ) need=l->need;
else need=r->need;
need = l->need;
} else {
l->label(); r->label();
if (l->need == r->need) need = l->need + 1;
else if (l->need > r->need) need = l->need;
else need = r->need;
}
}
int Tile::eval( int want ){
int Tile::eval(int want) {
//save any hit registers
int spill=hits;
if( want_l ) spill|=1<<want_l;
if( want_r ) spill|=1<<want_r;
if( spill ){
for( int n=1;n<=NUM_REGS;++n ){
if( spill&(1<<n) ){
if( regUsed[n] ) pushReg( n );
else spill&=~(1<<n);
int spill = hits;
if (want_l) spill |= 1 << want_l;
if (want_r) spill |= 1 << want_r;
if (spill) {
for (int n = 1; n <= NUM_REGS; ++n) {
if (spill&(1 << n)) {
if (regUsed[n]) pushReg(n);
else spill &= ~(1 << n);
}
}
}
//if tile needs an argFrame...
if( argFrame ){
codeFrags.push_back( "-"+itoa(argFrame) );
if (argFrame) {
codeFrags.push_back("-" + itoa(argFrame));
}
int got_l=0,got_r=0;
if( want_l ) want=want_l;
int got_l = 0, got_r = 0;
if (want_l) want = want_l;
string *as=&assem;
string *as = &assem;
if( !l ){
got_l=allocReg( want );
}else if( !r ){
got_l=l->eval( want );
}else{
if( l->need>=NUM_REGS && r->need>=NUM_REGS ){
got_r=r->eval( 0 );
pushReg( got_r );freeReg( got_r );
got_l=l->eval( want );
got_r=allocReg( want_r );popReg( got_r );
}else if( r->need>l->need ){
got_r=r->eval( want_r );
got_l=l->eval( want );
}else{
got_l=l->eval( want );
got_r=r->eval( want_r );
if( assem2.size() ) as=&assem2;
if (!l) {
got_l = allocReg(want);
} else if (!r) {
got_l = l->eval(want);
} else {
if (l->need >= NUM_REGS && r->need >= NUM_REGS) {
got_r = r->eval(0);
pushReg(got_r); freeReg(got_r);
got_l = l->eval(want);
got_r = allocReg(want_r); popReg(got_r);
} else if (r->need > l->need) {
got_r = r->eval(want_r);
got_l = l->eval(want);
} else {
got_l = l->eval(want);
got_r = r->eval(want_r);
if (assem2.size()) as = &assem2;
}
if( want_l==got_r || want_r==got_l ){
swapRegs( got_l,got_r );
int t=got_l;got_l=got_r;got_r=t;
if (want_l == got_r || want_r == got_l) {
swapRegs(got_l, got_r);
int t = got_l; got_l = got_r; got_r = t;
}
}
if( !want_l ) want_l=got_l;
else if( want_l!=got_l ) moveReg( want_l,got_l );
if (!want_l) want_l = got_l;
else if (want_l != got_l) moveReg(want_l, got_l);
if( !want_r ) want_r=got_r;
else if( want_r!=got_r ) moveReg( want_r,got_r );
if (!want_r) want_r = got_r;
else if (want_r != got_r) moveReg(want_r, got_r);
int i;
while( (i=as->find( "%l" ))!=string::npos ) as->replace( i,2,regs[want_l] );
while( (i=as->find( "%r" ))!=string::npos ) as->replace( i,2,regs[want_r] );
while ((i = as->find("%l")) != string::npos) as->replace(i, 2, regs[want_l]);
while ((i = as->find("%r")) != string::npos) as->replace(i, 2, regs[want_r]);
codeFrags.push_back( *as );
codeFrags.push_back(*as);
freeReg( got_r );
if( want_l!=got_l ) moveReg( got_l,want_l );
freeReg(got_r);
if (want_l != got_l) moveReg(got_l, want_l);
//cleanup argFrame
if( argFrame ){
if (argFrame) {
//***** Not needed for STDCALL *****
// codeFrags.push_back( "+"+itoa(argFrame) );
}
//restore spilled regs
if( spill ){
for( int n=NUM_REGS;n>=1;--n ){
if( spill&(1<<n) ) popReg( n );
if (spill) {
for (int n = NUM_REGS; n >= 1; --n) {
if (spill&(1 << n)) popReg(n);
}
}
return got_l;
}
void Codegen_x86::flush(){
void Codegen_x86::flush() {
vector<string>::iterator it;
for( it=dataFrags.begin();it!=dataFrags.end();++it ) out<<*it;
for (it = dataFrags.begin(); it != dataFrags.end(); ++it) out << *it;
dataFrags.clear();
}
void Codegen_x86::enter( const string &l,int frameSize ){
void Codegen_x86::enter(const string &l, int frameSize) {
inCode=true;
::frameSize=maxFrameSize=frameSize;
codeFrags.clear();funcLabel=l;
inCode = true;
::frameSize = maxFrameSize = frameSize;
codeFrags.clear(); funcLabel = l;
}
void Codegen_x86::code( TNode *stmt ){
void Codegen_x86::code(TNode *stmt) {
resetRegs();
Tile *q=munch( stmt );
Tile *q = munch(stmt);
q->label();
q->eval( 0 );
q->eval(0);
delete q;
delete stmt;
}
static string fixEsp( int esp_off ){
if( esp_off<0 ) return "\tsub\tesp,"+itoa(-esp_off)+"\n";
return "\tadd\tesp,"+itoa(esp_off)+"\n";
static string fixEsp(int esp_off) {
if (esp_off < 0) return "\tsub\tesp," + itoa(-esp_off) + "\n";
return "\tadd\tesp," + itoa(esp_off) + "\n";
}
void Codegen_x86::leave( TNode *cleanup,int pop_sz ){
if( cleanup ){
void Codegen_x86::leave(TNode *cleanup, int pop_sz) {
if (cleanup) {
resetRegs();
allocReg( EAX );
Tile *q=munch( cleanup );
allocReg(EAX);
Tile *q = munch(cleanup);
q->label();
q->eval( 0 );
q->eval(0);
delete q;
}
out<<"\t.align\t16\n";
out << "\t.align\t16\n";
if( funcLabel.size() ) out<<funcLabel<<'\n';
if (funcLabel.size()) out << funcLabel << '\n';
out<<"\tpush\tebx\n";
out<<"\tpush\tesi\n";
out<<"\tpush\tedi\n";
out<<"\tpush\tebp\n";
out<<"\tmov\tebp,esp\n";
if( maxFrameSize ) out<<"\tsub\tesp,"<<maxFrameSize<<'\n';
out << "\tpush\tebx\n";
out << "\tpush\tesi\n";
out << "\tpush\tedi\n";
out << "\tpush\tebp\n";
out << "\tmov\tebp,esp\n";
if (maxFrameSize) out << "\tsub\tesp," << maxFrameSize << '\n';
int esp_off=0;
vector<string>::iterator it=codeFrags.begin();
for( it=codeFrags.begin();it!=codeFrags.end();++it ){
const string &t=*it;
if( t[0]=='+' ){
esp_off+=atoi(t.substr(1));
}else if( t[0]=='-' ){
int esp_off = 0;
vector<string>::iterator it = codeFrags.begin();
for (it = codeFrags.begin(); it != codeFrags.end(); ++it) {
const string &t = *it;
if (t[0] == '+') {
esp_off += atoi(t.substr(1));
} else if (t[0] == '-') {
//***** Still needed for STDCALL *****
esp_off-=atoi(t.substr(1));
}else{
if( esp_off ){
out<<fixEsp( esp_off );
esp_off=0;
esp_off -= atoi(t.substr(1));
} else {
if (esp_off) {
out << fixEsp(esp_off);
esp_off = 0;
}
out<<*it;
out << *it;
}
}
if( esp_off ) out<<fixEsp( esp_off );
if (esp_off) out << fixEsp(esp_off);
out<<"\tmov\tesp,ebp\n";
out<<"\tpop\tebp\n";
out<<"\tpop\tedi\n";
out<<"\tpop\tesi\n";
out<<"\tpop\tebx\n";
out<<"\tret\tword "<<pop_sz<<"\n";
out << "\tmov\tesp,ebp\n";
out << "\tpop\tebp\n";
out << "\tpop\tedi\n";
out << "\tpop\tesi\n";
out << "\tpop\tebx\n";
out << "\tret\tword " << pop_sz << "\n";
delete cleanup;
inCode=false;
inCode = false;
}
void Codegen_x86::label( const string &l ){
string t=l+'\n';
if( inCode ) codeFrags.push_back( t );
else dataFrags.push_back( t );
void Codegen_x86::label(const string &l) {
string t = l + '\n';
if (inCode) codeFrags.push_back(t);
else dataFrags.push_back(t);
}
void Codegen_x86::align_data( int n ){
char buff[32];itoa( n,buff,10 );
dataFrags.push_back( string( "\t.align\t" )+buff+'\n' );
void Codegen_x86::align_data(int n) {
char buff[32]; _itoa(n, buff, 10);
dataFrags.push_back(string("\t.align\t") + buff + '\n');
}
void Codegen_x86::i_data( int i,const string &l ){
if( l.size() ) dataFrags.push_back( l );
char buff[32];itoa( i,buff,10 );
dataFrags.push_back( string( "\t.dd\t" )+buff+'\n' );
void Codegen_x86::i_data(int i, const string &l) {
if (l.size()) dataFrags.push_back(l);
char buff[32]; _itoa(i, buff, 10);
dataFrags.push_back(string("\t.dd\t") + buff + '\n');
}
void Codegen_x86::s_data( const string &s,const string &l ){
if( l.size() ) dataFrags.push_back( l );
dataFrags.push_back( string( "\t.db\t\"" )+s+"\",0\n" );
void Codegen_x86::s_data(const string &s, const string &l) {
if (l.size()) dataFrags.push_back(l);
dataFrags.push_back(string("\t.db\t\"") + s + "\",0\n");
}
void Codegen_x86::p_data( const string &p,const string &l ){
if( l.size() ) dataFrags.push_back( l );
dataFrags.push_back( string( "\t.dd\t" )+p+'\n' );
void Codegen_x86::p_data(const string &p, const string &l) {
if (l.size()) dataFrags.push_back(l);
dataFrags.push_back(string("\t.dd\t") + p + '\n');
}