move redundant code to gen

This commit is contained in:
corey 2024-01-12 19:48:31 -06:00
parent 66e17bc0a6
commit 161d440e8c
10 changed files with 296 additions and 345 deletions

191
gen.c
View File

@ -1,10 +1,12 @@
#include"gen.h"
#include"err.h"
Gen gen_new(void)
{
Gen gen={
.labelno=0,
.stackptr=NULL,
.buildarch=M_X86_64,
};
return gen;
}
@ -112,3 +114,192 @@ Vec gen_i2r(const Vec*tokens)
// move ownership to caller
return stack;
}
bool gen_findret(const PNode*pn,bool found)
{
if(found)return true;
if(!pn)return found;
if(pn->type==PRET)return true;
for(size_t i=0;i<pn->pnodes.size;++i)
if(gen_findret(vec_at(&pn->pnodes,i,const PNode*),found))
return true;
return false;
}
/* static void gen_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str) */
/* { */
/* if(!gen)return; */
/* if(!pn)return; */
/* if(!file)return; */
/* if(!str)return; */
/* */
/* for(size_t i=0;i<str->size;++i) */
/* { */
/* switch(str->buffer[i]) */
/* { */
/* */
/* // Escape codes */
/* case '\\': */
/* if(i<str->size-1) */
/* { */
/* switch(str->buffer[i+1]) */
/* { */
/* case 'n':fputc('\n',file);++i;break; */
/* case 't':fputc('\t',file);++i;break; */
/* case '"':fputc('"',file);++i;break; */
/* case '\\':fputc('\\',file);++i;break; */
/* } */
/* } */
/* break; */
/* */
/* default: */
/* fputc(str->buffer[i],file); */
/* break; */
/* */
/* } */
/* } */
/* fprintf(file,"\n"); */
/* } */
void gen_declare_variable(Gen*gen,PNode*pn,FILE*file)
{
if(pn->tokens.size>1)
{
if(vec_at(&pn->tokens,1,const Tok*)->type!=LOPERATOR||(strcmp(vec_at(&pn->tokens,1,const Tok*)->str.buffer,"=")))
{
err_log("%u: expected either ';' or '='",vec_at(&pn->tokens,1,const Tok*)->line);
}
}
else if(pn->tokens.size==0)
{
err_log("%u: expected identifier",pn->firstline);
return;
}
for(size_t i=0;i<gen->stackptr->vars.size;++i)
{
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->stackptr->vars,i,Var*)->name)==0)
{
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
break;
}
}
if(pn->tokens.size>0)
{
gen->stackptr->stacksize+=4;
Var var={
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
.is_arg=false,
/* .type=I32, */
/* .location=STACK, */
/* .regnum=0, */
.stackloc=gen->stackptr->stacksize,
};
vec_push((Vec*)&gen->stackptr->vars,&var);
// Evaluate initialization expression
if(pn->tokens.size>1)
{
switch(gen->buildarch)
{
case M_I386:
gen_i386_eval(gen,pn,file);
break;
case M_X86_64:
gen_x86_64_eval(gen,pn,file);
break;
}
}
}
}
void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
{
if(!gen)return;
if(!pn)return;
if(!file)return;
size_t stacksize=0;
gen->stackptr=pn;
if(pn->parentnode&&pn->parentnode->parentnode!=NULL)
err_log("%u: nested function declaration",pn->firstline);
for(size_t i=0;i<gen->rootnode->funcs.size;++i)
{
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->rootnode->funcs,i,Func*)->name)==0)
{
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
break;
}
}
Func func={
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
/* .type=I32, */
};
vec_push((Vec*)&gen->rootnode->funcs,&func);
if(pn->tokens.size<2||
vec_at(&pn->tokens,1,Tok*)->subtype!=LLPAREN)
err_log("%u: expected '('",vec_at(&pn->tokens,0,const Tok*)->line);
else
{
/* bool found=false; */
for(size_t i=2;i<pn->tokens.size;++i)
{
/* if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->stackptr->vars,i,Var*)->name)==0) */
/* { */
/* err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer); */
/* found=true; */
/* break; */
/* } */
/* if(!found) */
if(vec_at(&pn->tokens,i,const Tok*)->type==LIDENTIFIER)
{
stacksize+=4;
/* printf("push '%s' to %p\n",vec_at(&pn->tokens,i,const Tok*)->str.buffer, */
/* gen->stackptr); */
Var var={
.name=vec_at(&pn->tokens,i,const Tok*)->str.buffer,
.is_arg=true,
/* .type=I32, */
/* .location=STACK, */
/* .regnum=0, */
.stackloc=stacksize,
};
vec_push((Vec*)&gen->stackptr->vars,&var);
}
}
}
fprintf(file,".global %s\n%s:\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
switch(gen->buildarch)
{
case M_I386:
pn->stacksize+=stacksize;
stacksize+=gen_i386_stacksize(pn);
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); */
break;
case M_X86_64:
pn->stacksize+=stacksize;
stacksize+=gen_x86_64_stacksize(pn);
gen_x86_64_prolog(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); */
break;
}
}

14
gen.h
View File

@ -6,13 +6,19 @@
#pragma once
#include"mem.h"
#include"i386.h"
#include"pnode.h"
#include"x86_64.h"
// Build architecture types
enum {M_I386,M_IR,M_RUN,M_X86_64};
typedef struct Gen
{
size_t labelno;
const PNode*rootnode;
PNode*stackptr;
const PNode*rootnode;
size_t labelno;
uint32_t buildarch;
} Gen;
// Type of elements in evaluation of RPN Vec
@ -27,7 +33,11 @@ typedef struct eval_elem
}val;
}eval_elem;
/* static void gen_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str) */
Gen gen_new(void);
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_free(Gen*gen);
void gen_setrootnode(Gen*gen,PNode*rootnode);

181
i386.c
View File

@ -3,14 +3,6 @@
#include"i386.h"
#include"state.h"
static bool gen_i386_findret(const PNode*pn,bool found);
static void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize);
static void gen_i386_epilog(const PNode*pn,FILE*file);
static size_t gen_i386_stacksize(const PNode*pn);
/* static void gen_i386_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str); */
void gen_i386_declare_function(Gen*gen,PNode*pn,FILE*file);
void gen_i386_declare_variable(Gen*gen,PNode*pn,FILE*file);
void gen_i386(Gen*gen,PNode*pn,FILE*file)
{
@ -35,8 +27,8 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
case PFUNDECL:
{
bool found=false;
gen_i386_declare_function(gen,pn,file);
found=gen_i386_findret(pn,false);
gen_declare_function(gen,pn,file);
found=gen_findret(pn,false);
if(!found)
err_log("%u: no return in function '%s'",vec_at(&pn->tokens,0,const Tok*)->line,
vec_at(&pn->tokens,0,const Tok*)->str.buffer);
@ -44,7 +36,7 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
break;
case PVARDECL:
gen_i386_declare_variable(gen,pn,file);
gen_declare_variable(gen,pn,file);
break;
case PRET:
@ -151,7 +143,7 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
}
else
gen_i386_declare_variable(gen,pn,file);
gen_declare_variable(gen,pn,file);
fprintf(file,".extern %s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
}
}
@ -195,7 +187,7 @@ void gen_i386(Gen*gen,PNode*pn,FILE*file)
//gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
}
static void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize)
void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize)
{
if(!pn)
{
@ -227,7 +219,7 @@ static void gen_i386_prolog(const PNode*pn,FILE*file,size_t stacksize)
}
}
static void gen_i386_epilog(const PNode*pn,FILE*file)
void gen_i386_epilog(const PNode*pn,FILE*file)
{
if(!pn)
{
@ -262,7 +254,7 @@ static void gen_i386_epilog(const PNode*pn,FILE*file)
/* printf("]\n"); */
/* } */
static size_t gen_i386_stacksize(const PNode*pn)
size_t gen_i386_stacksize(const PNode*pn)
{
size_t stacksize=0;
@ -826,162 +818,3 @@ void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file)
vec_free(&stack);
}
void gen_i386_declare_function(Gen*gen,PNode*pn,FILE*file)
{
if(!gen)return;
if(!pn)return;
if(!file)return;
size_t stacksize=0;
gen->stackptr=pn;
if(pn->parentnode&&pn->parentnode->parentnode!=NULL)
err_log("%u: nested function declaration",pn->firstline);
for(size_t i=0;i<gen->rootnode->funcs.size;++i)
{
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->rootnode->funcs,i,Func*)->name)==0)
{
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
break;
}
}
Func func={
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
/* .type=I32, */
};
vec_push((Vec*)&gen->rootnode->funcs,&func);
if(pn->tokens.size<2||
vec_at(&pn->tokens,1,Tok*)->subtype!=LLPAREN)
err_log("%u: expected '('",vec_at(&pn->tokens,0,const Tok*)->line);
else
{
/* bool found=false; */
for(size_t i=2;i<pn->tokens.size;++i)
{
/* if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->stackptr->vars,i,Var*)->name)==0) */
/* { */
/* err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer); */
/* found=true; */
/* break; */
/* } */
/* if(!found) */
if(vec_at(&pn->tokens,i,const Tok*)->type==LIDENTIFIER)
{
stacksize+=4;
/* printf("push '%s' to %p\n",vec_at(&pn->tokens,i,const Tok*)->str.buffer, */
/* gen->stackptr); */
Var var={
.name=vec_at(&pn->tokens,i,const Tok*)->str.buffer,
.is_arg=true,
/* .type=I32, */
/* .location=STACK, */
/* .regnum=0, */
.stackloc=stacksize,
};
vec_push((Vec*)&gen->stackptr->vars,&var);
}
}
}
fprintf(file,".global %s\n%s:\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
pn->stacksize+=stacksize;
stacksize+=gen_i386_stacksize(pn);
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); */
}
void gen_i386_declare_variable(Gen*gen,PNode*pn,FILE*file)
{
if(pn->tokens.size>1)
{
if(vec_at(&pn->tokens,1,const Tok*)->type!=LOPERATOR||(strcmp(vec_at(&pn->tokens,1,const Tok*)->str.buffer,"=")))
{
err_log("%u: expected either ';' or '='",vec_at(&pn->tokens,1,const Tok*)->line);
}
}
else if(pn->tokens.size==0)
{
err_log("%u: expected identifier",pn->firstline);
return;
}
for(size_t i=0;i<gen->stackptr->vars.size;++i)
{
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->stackptr->vars,i,Var*)->name)==0)
{
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
break;
}
}
if(pn->tokens.size>0)
{
gen->stackptr->stacksize+=4;
Var var={
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
.is_arg=false,
/* .type=I32, */
/* .location=STACK, */
/* .regnum=0, */
.stackloc=gen->stackptr->stacksize,
};
vec_push((Vec*)&gen->stackptr->vars,&var);
// Evaluate initialization expression
if(pn->tokens.size>1)
gen_i386_eval(gen,pn,file);
}
}
/* static void gen_i386_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str) */
/* { */
/* if(!gen)return; */
/* if(!pn)return; */
/* if(!file)return; */
/* if(!str)return; */
/* */
/* for(size_t i=0;i<str->size;++i) */
/* { */
/* switch(str->buffer[i]) */
/* { */
/* */
/* // Escape codes */
/* case '\\': */
/* if(i<str->size-1) */
/* { */
/* switch(str->buffer[i+1]) */
/* { */
/* case 'n':fputc('\n',file);++i;break; */
/* case 't':fputc('\t',file);++i;break; */
/* case '"':fputc('"',file);++i;break; */
/* case '\\':fputc('\\',file);++i;break; */
/* } */
/* } */
/* break; */
/* */
/* default: */
/* fputc(str->buffer[i],file); */
/* break; */
/* */
/* } */
/* } */
/* fprintf(file,"\n"); */
/* } */
static bool gen_i386_findret(const PNode*pn,bool found)
{
if(found)return true;
if(!pn)return found;
if(pn->type==PRET)return true;
for(size_t i=0;i<pn->pnodes.size;++i)
if(gen_i386_findret(vec_at(&pn->pnodes,i,const PNode*),found))
return true;
return false;
}

13
i386.h
View File

@ -1,9 +1,14 @@
#pragma once
#include<stdio.h>
#include"state.h"
#include"mem.h"
#include"gen.h"
#include"pnode.h"
struct Gen;
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);
void gen_i386(Gen*gen,PNode*pn,FILE*file);
void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file);

4
ir.h
View File

@ -8,4 +8,6 @@
#include"state.h"
#include"mem.h"
void gen_ir(Gen*gen,const PNode*pn,FILE*file);
struct Gen;
void gen_ir(struct Gen*gen,const PNode*pn,FILE*file);

6
main.c
View File

@ -21,7 +21,6 @@ int main(int argc,char**argv)
int skip_arg=0;
uint32_t buildarch=M_X86_64;
//state=state_new();
Vec args=vec_new(sizeof(char*));
// Ensure cleanup is called
@ -144,6 +143,7 @@ int main(int argc,char**argv)
state=state_new();
state.gen.rootnode=&state.parser.root;
state.gen.buildarch=buildarch;
state.infile=fopen(*vec_at(&args,i,const char**),"r");
if(!state.infile)
@ -190,10 +190,10 @@ int main(int argc,char**argv)
// Generate code
if(generate)
{
state_set_outfile(&state,(char*)*vec_at(&args,i,const char**),setoutfile,setoutfile_name,buildarch);
state_set_outfile(&state,(char*)*vec_at(&args,i,const char**),setoutfile,setoutfile_name,state.gen.buildarch);
// Generate code based on buildarch
switch(buildarch)
switch(state.gen.buildarch)
{
case M_IR:

4
run.h
View File

@ -9,4 +9,6 @@
#include"state.h"
#include"mem.h"
void gen_run(Gen*gen,const PNode*pn,FILE*file);
struct Gen;
void gen_run(struct Gen*gen,const PNode*pn,FILE*file);

View File

@ -18,9 +18,6 @@
#include"x86_64.h"
#include"i386.h"
// Build architecture types
enum {M_I386,M_IR,M_RUN,M_X86_64};
// State for par source file
typedef struct State
{
@ -32,7 +29,6 @@ typedef struct State
FILE*infile;
FILE*outfile;
char*infilename;
uint32_t buildarch;
} State;
extern State state;

211
x86_64.c
View File

@ -3,13 +3,11 @@
#include"x86_64.h"
#include"state.h"
static bool gen_x86_64_findret(const PNode*pn,bool found);
static size_t gen_x86_64_stacksize(const PNode*pn);
static void gen_x86_64_epilog(const PNode*pn,FILE*file);
static void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize);
/* static void gen_x86_64_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str); */
void gen_x86_64_declare_function(Gen*gen,PNode*pn,FILE*file);
void gen_x86_64_declare_variable(Gen*gen,PNode*pn,FILE*file);
const char*const gen_x86_64_registers_abi_wordsize[]={"rdi","rsi","rdx","rcx","r8d","r9d"};
char*gen_x86_64_sp(void){return"rsp";}
char*gen_x86_64_bp(void){return"rbp";}
char*gen_x86_64_scratch1(void){return"r8d";};
void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
{
@ -36,7 +34,7 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
{
bool found=false;
gen_x86_64_declare_function(gen,pn,file);
found=gen_x86_64_findret(pn,false);
found=gen_findret(pn,false);
if(!found)
err_log("%u: no return in function '%s'",vec_at(&pn->tokens,0,const Tok*)->line,
vec_at(&pn->tokens,0,const Tok*)->str.buffer);
@ -44,7 +42,7 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
break;
case PVARDECL:
gen_x86_64_declare_variable(gen,pn,file);
gen_declare_variable(gen,pn,file);
break;
case PRET:
@ -151,7 +149,7 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
}
else
gen_x86_64_declare_variable(gen,pn,file);
gen_declare_variable(gen,pn,file);
fprintf(file,".extern %s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
}
}
@ -195,7 +193,7 @@ void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
//gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
}
static void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize)
void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize)
{
if(!pn)
{
@ -209,10 +207,10 @@ static void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize)
return;
}
fprintf(file,"\tpushq %%rbp\n");
fprintf(file,"\tpushq %%%s\n",gen_x86_64_bp());
fprintf(file,"\tpushq %%rdx\n");
fprintf(file,"\tmovq %%rsp,%%rbp\n");
fprintf(file,"\tsubq $%lu,%%rsp\n",stacksize);
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"};
@ -220,14 +218,12 @@ static void gen_x86_64_prolog(const PNode*pn,FILE*file,size_t stacksize)
{
if(i<sizeof(reg_order_sysv)/sizeof(const char*)&&vec_at(&pn->vars,i,Var*)->is_arg)
{
fprintf(file,"\tmovl %%%s,-%lu(%%rbp)\n",
reg_order_sysv[i],
vec_at(&pn->vars,i,Var*)->stackloc);
fprintf(file,"\tmovl %%%s,-%lu(%%%s)\n",reg_order_sysv[i],vec_at(&pn->vars,i,Var*)->stackloc,gen_x86_64_bp());
}
}
}
static void gen_x86_64_epilog(const PNode*pn,FILE*file)
void gen_x86_64_epilog(const PNode*pn,FILE*file)
{
if(!pn)
{
@ -241,9 +237,9 @@ static void gen_x86_64_epilog(const PNode*pn,FILE*file)
return;
}
fprintf(file,"\tmovq %%rbp,%%rsp\n");
fprintf(file,"\tmovq %%%s,%%%s\n",gen_x86_64_bp(),gen_x86_64_sp());
fprintf(file,"\tpopq %%rdx\n");
fprintf(file,"\tpopq %%rbp\n");
fprintf(file,"\tpopq %%%s\n",gen_x86_64_bp());
}
@ -262,7 +258,7 @@ static void gen_x86_64_epilog(const PNode*pn,FILE*file)
/* printf("]\n"); */
/* } */
static size_t gen_x86_64_stacksize(const PNode*pn)
size_t gen_x86_64_stacksize(const PNode*pn)
{
size_t stacksize=0;
@ -495,15 +491,15 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%r8d\n",elem[1].val.i32);
fprintf(file,"\timull %%r8d\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1());
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%r8d\n",elem[1].val.i32);
fprintf(file,"\tidiv %%r8d\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1());
fprintf(file,"\tidiv %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
@ -523,30 +519,30 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
break;
case '+':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl $%d,%%r8d\n",elem[1].val.i32);
fprintf(file,"\timull %%r8d\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1());
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl $%d,%%r8d\n",elem[1].val.i32);
fprintf(file,"\tidivl %%r8d\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1());
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
@ -563,35 +559,35 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
{
case '=':
fprintf(file,"\tmovl $%d,-%lu(%%rbp)\n",elem[0].val.i32,var_stackloc[1]);
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tmovl $%d,%%r8d\n",elem[0].val.i32);
fprintf(file,"\timul %%r8d\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1());
fprintf(file,"\timul %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tmovl $%d,%%r8d\n",elem[0].val.i32);
fprintf(file,"\tidivl %%r8d\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1());
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1());
vec_push(&stack,&e);
break;
@ -608,35 +604,35 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
{
case '=':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl %%eax,-%lu(%%rbp)\n",var_stackloc[1]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\taddl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tsubl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\timull -%lu(%%rbp)\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '/':
puts("here");
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tidivl -%lu(%%rbp)\n",var_stackloc[0]);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
@ -653,29 +649,29 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%rbp)\n",var_stackloc[0]);
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\taddl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%rbp),%%eax\n",var_stackloc[0]);
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%rbp)\n",var_stackloc[0]);
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%rbp)\n",var_stackloc[0]);
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp());
vec_push(&stack,&e);
break;
@ -731,29 +727,29 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%rbp)\n",var_stackloc[1]);
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\taddl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%rbp),%%eax\n",var_stackloc[1]);
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%rbp)\n",var_stackloc[1]);
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%rbp)\n",var_stackloc[1]);
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp());
vec_push(&stack,&e);
break;
@ -808,7 +804,7 @@ void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
e.type=EVAR;
var_stackloc=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
fprintf(file,"\tmovl -%lu(%%rbp),%%eax\n",var_stackloc);
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc,gen_x86_64_bp());
found=true;
break;
}
@ -895,92 +891,3 @@ void gen_x86_64_declare_function(Gen*gen,PNode*pn,FILE*file)
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
/* gen_x86_64_epilog(pn,file); */
}
void gen_x86_64_declare_variable(Gen*gen,PNode*pn,FILE*file)
{
if(pn->tokens.size>1)
{
if(vec_at(&pn->tokens,1,const Tok*)->type!=LOPERATOR||(strcmp(vec_at(&pn->tokens,1,const Tok*)->str.buffer,"=")))
{
err_log("%u: expected either ';' or '='",vec_at(&pn->tokens,1,const Tok*)->line);
}
}
else if(pn->tokens.size==0)
{
err_log("%u: expected identifier",pn->firstline);
return;
}
for(size_t i=0;i<gen->stackptr->vars.size;++i)
{
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->stackptr->vars,i,Var*)->name)==0)
{
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
break;
}
}
if(pn->tokens.size>0)
{
gen->stackptr->stacksize+=4;
Var var={
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
.is_arg=false,
/* .type=I32, */
/* .location=STACK, */
/* .regnum=0, */
.stackloc=gen->stackptr->stacksize,
};
vec_push((Vec*)&gen->stackptr->vars,&var);
// Evaluate initialization expression
if(pn->tokens.size>1)
gen_x86_64_eval(gen,pn,file);
}
}
/* static void gen_x86_64_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str) */
/* { */
/* if(!gen)return; */
/* if(!pn)return; */
/* if(!file)return; */
/* if(!str)return; */
/* */
/* for(size_t i=0;i<str->size;++i) */
/* { */
/* switch(str->buffer[i]) */
/* { */
/* */
/* // Escape codes */
/* case '\\': */
/* if(i<str->size-1) */
/* { */
/* switch(str->buffer[i+1]) */
/* { */
/* case 'n':fputc('\n',file);++i;break; */
/* case 't':fputc('\t',file);++i;break; */
/* case '"':fputc('"',file);++i;break; */
/* case '\\':fputc('\\',file);++i;break; */
/* } */
/* } */
/* break; */
/* */
/* default: */
/* fputc(str->buffer[i],file); */
/* break; */
/* */
/* } */
/* } */
/* fprintf(file,"\n"); */
/* } */
static bool gen_x86_64_findret(const PNode*pn,bool found)
{
if(found)return true;
if(!pn)return found;
if(pn->type==PRET)return true;
for(size_t i=0;i<pn->pnodes.size;++i)
if(gen_x86_64_findret(vec_at(&pn->pnodes,i,const PNode*),found))
return true;
return false;
}

View File

@ -1,9 +1,14 @@
#pragma once
#include<stdio.h>
#include"state.h"
#include"mem.h"
#include"gen.h"
#include"pnode.h"
void gen_x86_64(Gen*gen,PNode*pn,FILE*file);
void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file);
struct Gen;
size_t gen_x86_64_stacksize(const PNode*pn);
void gen_x86_64(struct Gen*gen,PNode*pn,FILE*file);
void gen_x86_64_declare_function(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);