move prolog and epilog to gen
This commit is contained in:
parent
8c8acf88b1
commit
948520f551
139
gen.c
139
gen.c
@ -301,7 +301,8 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
|
||||
case M_I386:
|
||||
pn->stacksize+=stacksize;
|
||||
stacksize+=gen_i386_stacksize(pn);
|
||||
gen_i386_prolog(pn,file,stacksize);
|
||||
gen_prolog(gen,pn,file,stacksize);
|
||||
/* gen_i386_prolog(pn,file,stacksize); */
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
/* gen_i386_epilog(pn,file); */
|
||||
@ -310,7 +311,8 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
|
||||
case M_X86_64:
|
||||
pn->stacksize+=stacksize;
|
||||
stacksize+=gen_x86_64_stacksize(pn);
|
||||
gen_x86_64_prolog(pn,file,stacksize);
|
||||
/* gen_x86_64_prolog(pn,file,stacksize); */
|
||||
gen_prolog(gen,pn,file,stacksize);
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
/* gen_x86_64_epilog(pn,file); */
|
||||
@ -358,3 +360,136 @@ void gen_eval_analyze(const PNode*pn)
|
||||
vec_free(&rpn_stack);
|
||||
vec_free(&stack);
|
||||
}
|
||||
|
||||
void gen_prolog(Gen*gen,const PNode*pn,FILE*file,size_t stacksize)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
// Array of function pointers
|
||||
// to different buildarch
|
||||
// primitives
|
||||
|
||||
size_t which=0;
|
||||
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_X86_64:
|
||||
which=0;
|
||||
break;
|
||||
|
||||
case M_I386:
|
||||
which=1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
char*(*gen_bp)(void);
|
||||
char*(*gen_sp)(void);
|
||||
|
||||
if(which==0)
|
||||
gen_sp=gen_x86_64_sp;
|
||||
else if(which==1)
|
||||
gen_sp=gen_i386_sp;
|
||||
|
||||
if(which==0)
|
||||
gen_bp=gen_x86_64_bp;
|
||||
else if(which==1)
|
||||
gen_bp=gen_i386_bp;
|
||||
|
||||
const char*const*registers_abi_wordsize[2]={gen_x86_64_registers_abi_wordsize,
|
||||
gen_i386_registers_abi_wordsize};
|
||||
|
||||
const char*const mov_wordsize[2]={gen_x86_64_mov_wordsize,
|
||||
gen_i386_mov_wordsize};
|
||||
|
||||
const char*const push_wordsize[2]={gen_x86_64_push_wordsize,
|
||||
gen_i386_push_wordsize};
|
||||
|
||||
const char*const sub_wordsize[2]={gen_x86_64_sub_wordsize,
|
||||
gen_i386_sub_wordsize};
|
||||
|
||||
fprintf(file,"\t%s %%%s\n",push_wordsize[which],gen_bp());
|
||||
if(gen->buildarch==M_X86_64)
|
||||
fprintf(file,"\t%s %%%s\n",push_wordsize[which],registers_abi_wordsize[which][2]);
|
||||
fprintf(file,"\t%s %%%s,%%%s\n",mov_wordsize[which],gen_sp(),gen_bp());
|
||||
fprintf(file,"\t%s $%lu,%%%s\n",sub_wordsize[which],stacksize,gen_sp());
|
||||
|
||||
// Move argument variables to stack
|
||||
//const char*reg_order_sysv[]={"edi","esi","edx","ecx","r8d","r9d"};
|
||||
for(size_t i=0;i<pn->vars.size;++i)
|
||||
if(i<6&&vec_at(&pn->vars,i,Var*)->is_arg)
|
||||
fprintf(file,"\t%s %%%s,-%lu(%%%s)\n",mov_wordsize[which],registers_abi_wordsize[which][i],vec_at(&pn->vars,i,Var*)->stackloc,gen_bp());
|
||||
}
|
||||
|
||||
void gen_epilog(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
// Array of function pointers
|
||||
// to different buildarch
|
||||
// primitives
|
||||
|
||||
size_t which=0;
|
||||
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_X86_64:
|
||||
which=0;
|
||||
break;
|
||||
|
||||
case M_I386:
|
||||
which=1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
char*(*gen_bp)(void);
|
||||
char*(*gen_sp)(void);
|
||||
|
||||
if(which==0)
|
||||
gen_sp=gen_x86_64_sp;
|
||||
else if(which==1)
|
||||
gen_sp=gen_i386_sp;
|
||||
|
||||
if(which==0)
|
||||
gen_bp=gen_x86_64_bp;
|
||||
else if(which==1)
|
||||
gen_bp=gen_i386_bp;
|
||||
|
||||
const char*const*registers_abi_wordsize[2]={gen_x86_64_registers_abi_wordsize,
|
||||
gen_i386_registers_abi_wordsize};
|
||||
|
||||
const char*const mov_wordsize[2]={gen_x86_64_mov_wordsize,
|
||||
gen_i386_mov_wordsize};
|
||||
|
||||
const char*const pop_wordsize[2]={gen_x86_64_pop_wordsize,
|
||||
gen_i386_pop_wordsize};
|
||||
|
||||
fprintf(file,"\t%s %%%s,%%%s\n",mov_wordsize[which],gen_bp(),gen_sp());
|
||||
if(gen->buildarch==M_X86_64)
|
||||
fprintf(file,"\t%s %%%s\n",pop_wordsize[which],registers_abi_wordsize[which][2]);
|
||||
fprintf(file,"\t%s %%%s\n",pop_wordsize[which],gen_bp());
|
||||
|
||||
}
|
||||
|
2
gen.h
2
gen.h
@ -39,7 +39,9 @@ Vec gen_i2r(const Vec*tokens);
|
||||
bool gen_findret(const PNode*pn,bool found);
|
||||
void gen_declare_function(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_declare_variable(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_epilog(Gen*gen,const PNode*pn,FILE*file);
|
||||
void gen_eval_analyze(const PNode*pn);
|
||||
void gen_free(Gen*gen);
|
||||
void gen_prolog(Gen*gen,const PNode*pn,FILE*file,size_t stacksize);
|
||||
void gen_setrootnode(Gen*gen,PNode*rootnode);
|
||||
void vec_print_tokens(Vec*tokens);
|
||||
|
64
i386.c
64
i386.c
@ -3,6 +3,16 @@
|
||||
#include"i386.h"
|
||||
#include"state.h"
|
||||
|
||||
const char*const gen_i386_registers_abi_wordsize[6]={"edi","esi","edx","ecx","e8d","e9d"};
|
||||
const char*const gen_i386_mov_wordsize="movl";
|
||||
const char*const gen_i386_push_wordsize="pushl";
|
||||
const char*const gen_i386_sub_wordsize="subl";
|
||||
const char*const gen_i386_pop_wordsize="popl";
|
||||
|
||||
char*gen_i386_sp(void){return"esp";}
|
||||
char*gen_i386_bp(void){return"ebp";}
|
||||
char*gen_i386_scratch1(void){return"e8d";};
|
||||
|
||||
void gen_i386(Gen*gen,PNode*pn,FILE*file)
|
||||
{
|
||||
|
||||
@ -56,7 +66,7 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
|
||||
else
|
||||
gen_i386_eval(gen,pn,file);
|
||||
}
|
||||
gen_i386_epilog(pn,file);
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
/*****
|
||||
* IMPORTANT:
|
||||
@ -187,58 +197,6 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
|
||||
//gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
||||
void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_i386_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_i386_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file,"\tpushl %%ebp\n");
|
||||
/* fprintf(file,"\tpushl %%edx\n"); */
|
||||
fprintf(file,"\tmovl %%esp,%%ebp\n");
|
||||
fprintf(file,"\tsubl $%lu,%%esp\n",stacksize);
|
||||
|
||||
// Move argument variables to stack
|
||||
const char*reg_order_sysv[]={"edi","esi","edx","ecx","r8d","r9d"};
|
||||
for(size_t i=0;i<pn->vars.size;++i)
|
||||
{
|
||||
if(i<sizeof(reg_order_sysv)/sizeof(const char*)&&vec_at(&pn->vars,i,Var*)->is_arg)
|
||||
{
|
||||
fprintf(file,"\tmovl %%%s,-%lu(%%ebp)\n",
|
||||
reg_order_sysv[i],
|
||||
vec_at(&pn->vars,i,Var*)->stackloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gen_i386_epilog(const PNode*pn,FILE*file)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_i386_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_i386_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file,"\tmovl %%ebp,%%esp\n");
|
||||
/* fprintf(file,"\tpopl %%edx\n"); */
|
||||
fprintf(file,"\tpopl %%ebp\n");
|
||||
|
||||
}
|
||||
|
||||
// Convert to infix, then evaluate
|
||||
void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
|
11
i386.h
11
i386.h
@ -6,8 +6,15 @@
|
||||
|
||||
struct Gen;
|
||||
|
||||
extern const char*const gen_i386_registers_abi_wordsize[6];
|
||||
extern const char*const gen_i386_mov_wordsize;
|
||||
extern const char*const gen_i386_push_wordsize;
|
||||
extern const char*const gen_i386_sub_wordsize;
|
||||
extern const char*const gen_i386_pop_wordsize;
|
||||
|
||||
char*gen_i386_bp(void);
|
||||
char*gen_i386_scratch1(void);
|
||||
char*gen_i386_sp(void);
|
||||
size_t gen_i386_stacksize(const PNode*pn);
|
||||
void gen_i386(struct Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_i386_epilog(const PNode*pn,FILE*file);
|
||||
void gen_i386_eval(struct Gen*gen,const PNode*pn,FILE*file);
|
||||
void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize);
|
||||
|
58
x86_64.c
58
x86_64.c
@ -4,7 +4,11 @@
|
||||
#include"x86_64.h"
|
||||
#include"state.h"
|
||||
|
||||
const char*const gen_x86_64_registers_abi_wordsize[]={"rdi","rsi","rdx","rcx","r8d","r9d"};
|
||||
const char*const gen_x86_64_registers_abi_wordsize[6]={"rdi","rsi","rdx","rcx","r8d","r9d"};
|
||||
const char*const gen_x86_64_mov_wordsize="movq";
|
||||
const char*const gen_x86_64_push_wordsize="pushq";
|
||||
const char*const gen_x86_64_sub_wordsize="subq";
|
||||
const char*const gen_x86_64_pop_wordsize="popq";
|
||||
|
||||
char*gen_x86_64_sp(void){return"rsp";}
|
||||
char*gen_x86_64_bp(void){return"rbp";}
|
||||
@ -63,7 +67,7 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
|
||||
else
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
}
|
||||
gen_x86_64_epilog(pn,file);
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
/*****
|
||||
* IMPORTANT:
|
||||
@ -194,56 +198,6 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
|
||||
//gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
||||
void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_x86_64_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_x86_64_prolog");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file,"\tpushq %%%s\n",gen_x86_64_bp());
|
||||
fprintf(file,"\tpushq %%rdx\n");
|
||||
fprintf(file,"\tmovq %%%s,%%%s\n",gen_x86_64_sp(),gen_x86_64_bp());
|
||||
fprintf(file,"\tsubq $%lu,%%%s\n",stacksize,gen_x86_64_sp());
|
||||
|
||||
// Move argument variables to stack
|
||||
const char*reg_order_sysv[]={"edi","esi","edx","ecx","r8d","r9d"};
|
||||
for(size_t i=0;i<pn->vars.size;++i)
|
||||
{
|
||||
if(i<sizeof(reg_order_sysv)/sizeof(const char*)&&vec_at(&pn->vars,i,Var*)->is_arg)
|
||||
{
|
||||
fprintf(file,"\tmovl %%%s,-%lu(%%%s)\n",reg_order_sysv[i],vec_at(&pn->vars,i,Var*)->stackloc,gen_x86_64_bp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gen_x86_64_epilog(const PNode*pn,FILE*file)
|
||||
{
|
||||
if(!pn)
|
||||
{
|
||||
err_log("NULL PNode passed to gen_x86_64_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_x86_64_epilog");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file,"\tmovq %%%s,%%%s\n",gen_x86_64_bp(),gen_x86_64_sp());
|
||||
fprintf(file,"\tpopq %%rdx\n");
|
||||
fprintf(file,"\tpopq %%%s\n",gen_x86_64_bp());
|
||||
|
||||
}
|
||||
|
||||
size_t gen_x86_64_stacksize(const PNode*pn)
|
||||
{
|
||||
size_t stacksize=0;
|
||||
|
11
x86_64.h
11
x86_64.h
@ -6,8 +6,15 @@
|
||||
|
||||
struct Gen;
|
||||
|
||||
extern const char*const gen_x86_64_registers_abi_wordsize[6];
|
||||
extern const char*const gen_x86_64_mov_wordsize;
|
||||
extern const char*const gen_x86_64_push_wordsize;
|
||||
extern const char*const gen_x86_64_sub_wordsize;
|
||||
extern const char*const gen_x86_64_pop_wordsize;
|
||||
|
||||
char*gen_x86_64_bp(void);
|
||||
char*gen_x86_64_scratch1(void);
|
||||
char*gen_x86_64_sp(void);
|
||||
size_t gen_x86_64_stacksize(const PNode*pn);
|
||||
void gen_x86_64(struct Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_x86_64_epilog(const PNode*pn,FILE*file);
|
||||
void gen_x86_64_eval(struct Gen*gen,const PNode*pn,FILE*file);
|
||||
void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize);
|
||||
|
Loading…
Reference in New Issue
Block a user