#include "cgstd.h" #include "cgmodule_x86.h" #include "cgfixfp_x86.h" static bool USE_NASM=false; //NASM doesn't seem to work at all CGModule_X86::CGModule_X86( ostream &o ):CGModule(o){ } void CGModule_X86::setSeg( string t ){ if( seg==t ) return; seg=t; if( USE_NASM ){ out<<"\tsection\t."<(f); assert( frame ); int k,n_use[7]={0}; for( k=0;kregs.size();++k ){ CGReg *r=frame->regs[k]; if( r->isint() && r->id>=14 && r->color>=0 && r->color<7 ) ++n_use[r->color]; } if( frame->extern_jsrs ){ n_use[3]=n_use[4]=n_use[5]=-1; } int local_sz=frame->local_sz; //create frame out<fun->sym->value<<":\n"; out<<"\tpush\tebp\n"; out<<"\tmov\tebp,esp\n"; emitSubEsp( local_sz ); //push callee save if( n_use[3] ) out<<"\tpush\tebx\n"; if( n_use[4] ) out<<"\tpush\tesi\n"; if( n_use[5] ) out<<"\tpush\tedi\n"; CGAsm *as; for( as=frame->assem.begin;as!=frame->assem.end;as=as->succ ){ if( as->stm && as->stm->ret() ){ //pop callee save if( n_use[5] ) out<<"\tpop\tedi\n"; if( n_use[4] ) out<<"\tpop\tesi\n"; if( n_use[3] ) out<<"\tpop\tebx\n"; out<<"\tmov\tesp,ebp\n"; out<<"\tpop\tebp\n"; } const char *p=as->assem; if( !p ) continue; out<4096 ){ out<<"\tsub\tesp,4092\n\tpush\teax\n"; sz-=4096; } if( sz ) out<<"\tsub\tesp,"<(f); assert( frame ); int k,n_use[7]={0}; for( k=0;kregs.size();++k ){ CGReg *r=frame->regs[k]; if( r->isint() && r->id>=14 && r->color>=0 && r->color<7 ) ++n_use[r->color]; } int save_sz=8; //ret address+ebp if( n_use[3] ) save_sz+=4; //ebx if( n_use[4] ) save_sz+=4; //esi if( n_use[5] ) save_sz+=4; //edi int local_sz=frame->local_sz; int param_sz=frame->param_sz; int frame_sz=param_sz+local_sz+save_sz; frame_sz=(frame_sz+15)&~15; param_sz=frame_sz-(local_sz+save_sz); //create frame out<fun->sym->value<<":\n"; //push ebp out<<"\tpush\tebp\n"; out<<"\tmov\tebp,esp\n"; if( save_sz>8 ){ emitSubEsp( local_sz ); if( n_use[3] ) out<<"\tpush\tebx\n"; if( n_use[4] ) out<<"\tpush\tesi\n"; if( n_use[5] ) out<<"\tpush\tedi\n"; emitSubEsp( param_sz ); }else{ emitSubEsp( local_sz+param_sz ); } CGAsm *as; for( as=frame->assem.begin;as!=frame->assem.end;as=as->succ ){ if( as->stm && as->stm->ret() ){ //pop callee save if( save_sz>8 ){ if( param_sz ) out<<"\tadd\tesp,"<assem; if( !p ) continue; out<exps.size()==1 ){ switch( d->exps[0]->type ){ case CG_INT8: case CG_CSTRING: align=1; break; case CG_INT16: align=2; break; case CG_INT64:case CG_FLOAT64: align=8; break; } } if( align!=1 ){ out<<"\talign\t"<value<<":\n"; for( int k=0;kexps.size();++k ){ CGExp *e=d->exps[k]; if( CGLit *t=e->lit() ){ if( t->type==CG_INT8 ){ out<<"\tdb\t"<int_value)<<'\n'; }else if( t->type==CG_INT16 ){ out<<"\tdw\t"<int_value)<<'\n'; }else if( t->type==CG_INT32 ){ out<<"\tdd\t"<int_value)<<'\n'; }else if( t->type==CG_INT64 ){ out<<"\tdd\t"<int_value)<<','<int_value>>int64(32))<<'\n'; }else if( t->type==CG_FLOAT32 ){ float f=t->float_value; int n=*(int*)&f; out<<"\tdd\t0x"<float_value; // out<<"\tdd\t0x"<type==CG_FLOAT64 ){ double f=t->float_value; int64 n=*(int64*)&f; out<<"\tdd\t0x"<>int64(32))<float_value; //#if __APPLE__ && __BIG_ENDIAN__ // out<<"\tdd\t0x"<type==CG_CSTRING ){ bstring s=t->string_value; out<<"\tdb\t\""; for( int k=0;ktype==CG_BSTRING ){ bstring s=t->string_value; out<<"\tdd\t"<type==CG_BINFILE ){ string file=tostring(t->string_value); out<<"\tfile\t\""+file+"\"\n"; }else if( t->type==CG_LABEL ){ out<string_value)<<":\n"; }else{ assert(0); } }else if( CGSym *t=e->sym() ){ out<<"\tdd\t"<value<<'\n'; }else if( CGLea *t=e->lea() ){ CGMem *m=t->exp->mem(); assert(m); if( CGReg *t=m->exp->reg() ){ out<<"\tdd\t"<offset<<'\n'; }else if( CGSym *t=m->exp->sym() ){ assert(t); if( m->offset ){ out<<"\tdd\t"<value<<'+'<offset<<'\n'; }else{ out<<"\tdd\t"<value<<'\n'; } }else{ assert(0); } }else{ fail( "cgmodule_x86::emitData - unrecognized data format" ); } } } void CGModule_X86::emitFooter(){ }