move prolog and epilog to gen

This commit is contained in:
corey 2024-01-12 21:32:42 -06:00
parent 8c8acf88b1
commit 948520f551
6 changed files with 174 additions and 111 deletions

139
gen.c
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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);

View File

@ -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;

View File

@ -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);