gen: use wordsize for all types

This commit is contained in:
corey 2024-02-02 08:23:49 -06:00
parent 245522d2f3
commit 6cef6c8b41
8 changed files with 93 additions and 63 deletions

116
gen.c
View File

@ -98,7 +98,7 @@ void gen_declare_variable(Gen*gen,PNode*pn,FILE*file)
// Add var to PNode, parse tokens
if(pn->tokens.size>0)
{
gen->stackptr->stacksize+=4;
gen->stackptr->stacksize+=gen->ld.wordsize;
const Tok*vartok=vec_at(&pn->tokens,0,const Tok*);
Var var={
.name=vartok->str.buffer,
@ -143,6 +143,7 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
};
vec_push((Vec*)&gen->rootnode->funcs,&func);
// Setup stack, find variables
if(pn->tokens.size<2||
vec_at(&pn->tokens,1,Tok*)->subtype!=LLPAREN)
@ -153,7 +154,7 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
{
if(vec_at(&pn->tokens,i,const Tok*)->type==LIDENTIFIER)
{
stacksize+=4;
stacksize+=gen->ld.wordsize;
Var var={
.name=vec_at(&pn->tokens,i,const Tok*)->str.buffer,
.is_arg=true,
@ -164,7 +165,7 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
if(gen->buildarch==M_I386)
{
var.stackloc=-var.stackloc;
var.stackloc+=4;
var.stackloc+=gen->ld.wordsize;
}
vec_push((Vec*)&gen->stackptr->vars,&var);
}
@ -178,7 +179,7 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
{
case M_I386:
stacksize+=gen_stacksize(pn);
stacksize+=gen_stacksize(gen,pn);
gen_prolog(gen,pn,file,stacksize);
for(size_t i=0;i<pn->pnodes.size;++i)
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
@ -186,7 +187,7 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
case M_X86_64:
pn->stacksize+=stacksize;
stacksize+=gen_stacksize(pn);
stacksize+=gen_stacksize(gen,pn);
gen_prolog(gen,pn,file,stacksize);
for(size_t i=0;i<pn->pnodes.size;++i)
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
@ -258,7 +259,7 @@ void gen_prolog(Gen*gen,const PNode*pn,FILE*file,size_t stacksize)
if(gen->buildarch==M_X86_64)
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,%d(%%%s)\n",gen->ld.mov_32,gen->ld.registers_abi_32[i],vec_at(&pn->vars,i,Var*)->stackloc,gen->ld.bp);
fprintf(file,"\t%s %%%s,%d(%%%s)\n",gen->ld.mov_wordsize,gen->ld.registers_abi_wordsize[i],vec_at(&pn->vars,i,Var*)->stackloc,gen->ld.bp);
}
void gen_epilog(Gen*gen,const PNode*pn,FILE*file)
@ -282,19 +283,19 @@ void gen_epilog(Gen*gen,const PNode*pn,FILE*file)
}
size_t gen_stacksize(const PNode*pn)
size_t gen_stacksize(const Gen*gen,const PNode*pn)
{
size_t stacksize=0;
if(pn->pnodes.size==0)
{
if(pn->type==PVARDECL)
return stacksize+sizeof(uint32_t);
return stacksize+gen->ld.wordsize;
else return 0;
}
for(size_t i=0;i<pn->pnodes.size;++i)
stacksize+=gen_stacksize(vec_at(&pn->pnodes,i,PNode*));
stacksize+=gen_stacksize(gen,vec_at(&pn->pnodes,i,PNode*));
return stacksize;
}
@ -354,13 +355,6 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
if(gen->rootnode==pn)
fprintf(file,".text\n");
switch(gen->buildarch)
{
case M_X86_64:gen->ld=(LangDef)gen_x86_64_langdef();break;
case M_I386:gen->ld=(LangDef)gen_i386_langdef();break;
default:err_log("Undefined generator language");break;
}
switch(pn->type)
{
@ -387,7 +381,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
if(pn->tokens.size<2)
err_log("%u: expected integer",vec_at(&pn->tokens,0,const Tok*)->line);
else
fprintf(file,"\t%s -%s,%%%s\n",gen->ld.mov_32,vec_at(&pn->tokens,1,const Tok*)->str.buffer,gen->ld.acc_32);
fprintf(file,"\t%s -%s,%%%s\n",gen->ld.mov_wordsize,vec_at(&pn->tokens,1,const Tok*)->str.buffer,gen->ld.acc_wordsize);
}
/* else if(vec_at(&pn->tokens,0,const Tok*)->type!=LINTEGER) */
/* { */
@ -413,7 +407,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
if(pn->tokens.size>1)
{
gen_eval(gen,pn,file);
fprintf(file,"\tcmpl $0,%%%s\n",gen->ld.acc_32);
fprintf(file,"\t%s $0,%%%s\n",gen->ld.cmp_wordsize,gen->ld.acc_wordsize);
}
size_t labelno_cache=gen->labelno;
++gen->labelno;
@ -434,7 +428,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
if(pn->tokens.size>1)
{
gen_eval(gen,pn,file);
fprintf(file,"\tcmpl $0,%%%s\n",gen->ld.acc_32);
fprintf(file,"\tcmpl $0,%%%s\n",gen->ld.acc_wordsize);
}
fprintf(file,"\tjz .L%02lu\n",pwhile_label2);
@ -866,7 +860,7 @@ eval_lastelem:
{
fprintf(file,"\tcall %s\n",e.val.name);
if(gen->buildarch==M_I386)
fprintf(file,"\taddl $%lu,%%%s\n",funarg_max*4,gen->ld.sp);
fprintf(file,"\t%s $%lu,%%%s\n",gen->ld.sub_wordsize,funarg_max*gen->ld.wordsize,gen->ld.sp);
}
vec_pop(&stack);
@ -875,7 +869,7 @@ eval_lastelem:
if(e.type==EE_I32)
{
value=e.val.i32;
fprintf(file,"\t%s $%d,%%%s\n",gen->ld.mov_32,value,gen->ld.acc_32);
fprintf(file,"\t%s $%d,%%%s\n",gen->ld.mov_wordsize,value,gen->ld.acc_wordsize);
}
else if(e.type==EE_IDENT||
@ -913,7 +907,7 @@ eval_lastelem:
break;
case EE_VAR:
fprintf(file,"\t%s %d(%%%s),%%%s\n",gen->ld.mov_32,e.vstackloc,gen->ld.bp,gen->ld.acc_32);
fprintf(file,"\t%s %d(%%%s),%%%s\n",gen->ld.mov_wordsize,e.vstackloc,gen->ld.bp,gen->ld.acc_wordsize);
break;
default:
@ -929,9 +923,9 @@ eval_lastelem:
if(funarg_no<funarg_max)
{
if(gen->buildarch==M_X86_64)
fprintf(file,"\t%s %%%s,%%%s\n",gen->ld.mov_32,gen->ld.acc_32,gen->ld.registers_abi_32[funarg_max-funarg_no-1]);
fprintf(file,"\t%s %%%s,%%%s\n",gen->ld.mov_wordsize,gen->ld.acc_wordsize,gen->ld.registers_abi_wordsize[funarg_max-funarg_no-1]);
else if(gen->buildarch==M_I386)
fprintf(file,"\tpushl %%%s\n",gen->ld.acc_32);
fprintf(file,"\tpushl %%%s\n",gen->ld.acc_wordsize);
}
/* else */
/* { */
@ -981,7 +975,7 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
case EE_FUNC: sprintf(operands[i],"%s",elem[i].val.name); break;
case EE_IDENT: sprintf(operands[i],"%s",elem[i].val.name); break;
case EE_I32: sprintf(operands[i],"$%d",elem[i].val.i32); break;
case EE_ACC: sprintf(operands[i],"%%%s",gen->ld.acc_32); break;
case EE_ACC: sprintf(operands[i],"%%%s",gen->ld.acc_wordsize); break;
//ERROR
//default: sprintf(operands[i],"???"); break;
}
@ -992,19 +986,19 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
// Convert operator name to instruction name
if(curtok->subtype==LADD)
sprintf(operator,"%s",gen->ld.add_32);
sprintf(operator,"%s",gen->ld.add_wordsize);
else if(curtok->subtype==LSMINUS)
sprintf(operator,"%s",gen->ld.sub_32);
sprintf(operator,"%s",gen->ld.sub_wordsize);
else if(curtok->subtype==LSMUL)
sprintf(operator,"%s",gen->ld.mul_32);
sprintf(operator,"%s",gen->ld.mul_wordsize);
else if(curtok->subtype==LSDIV)
sprintf(operator,"%s",gen->ld.div_32);
sprintf(operator,"%s",gen->ld.div_wordsize);
else if(curtok->subtype==LASSIGN)
sprintf(operator,"%s",gen->ld.mov_32);
sprintf(operator,"%s",gen->ld.mov_wordsize);
else if(curtok->subtype==LSREF)
sprintf(operator,"%s",gen->ld.lea_wordsize);
else if(curtok->subtype==LSDEREF)
sprintf(operator,"%s",gen->ld.mov_32);
sprintf(operator,"%s",gen->ld.mov_wordsize);
// Print output
if(gen->showeval)
@ -1016,14 +1010,14 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
// Move result to accumulator
if(elem[1].type!=EE_ACC)
printf("%s %s, %s\n",gen->ld.mov_32,operands[0],operands[1]);
printf("%s %s, %s\n",gen->ld.mov_wordsize,operands[0],operands[1]);
}
}
// Set up for multiply/divide instructions
if(curtok->subtype==LSDIV||curtok->subtype==LSMUL)
if(!(elem[0].type==EE_I32&&elem[0].type==EE_I32))
opos+=sprintf(output_buffer+opos,"\txorl %%%s,%%%s\n",gen->ld.registers_abi_32[2],gen->ld.registers_abi_32[2]);
opos+=sprintf(output_buffer+opos,"\t%s %%%s,%%%s\n",gen->ld.xor_wordsize,gen->ld.registers_abi_wordsize[2],gen->ld.registers_abi_wordsize[2]);
// Set up addressing mode
addrmode=AM(elem[0].type,elem[1].type);
@ -1039,18 +1033,18 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
switch(elem[0].type)
{
case EE_VAR:
opos+=sprintf(output_buffer+opos,"\tcmpl $0,%s\n",operands[0]);
opos+=sprintf(output_buffer+opos,"\t%s $0,%s\n",gen->ld.cmp_wordsize,operands[0]);
break;
case EE_I32:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\tcmpl $0,%%%s\n",gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s $0,%%%s\n",gen->ld.cmp_wordsize,gen->ld.acc_wordsize);
break;
case EE_ACC:
opos+=sprintf(output_buffer+opos,"\tcmpl $0,%%%s\n",gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s $0,%%%s\n",gen->ld.cmp_wordsize,gen->ld.acc_wordsize);
break;
}
opos+=sprintf(output_buffer+opos,"\tsete %%al\n");
opos+=sprintf(output_buffer+opos,"\tmovzbl %%al,%%%s\n",gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\tmovzbl %%al,%%%s\n",gen->ld.acc_wordsize);
tmpelem=(eval_elem){.type=EE_ACC,.val={0}};
break;
@ -1088,7 +1082,7 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
case EE_VAR:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.scratch1_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s (%%%s),%%%s\n",operator,gen->ld.scratch1_wordsize,gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s (%%%s),%%%s\n",operator,gen->ld.scratch1_wordsize,gen->ld.acc_wordsize);
break;
}
@ -1158,13 +1152,13 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
case LADD:
case LSMINUS:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[1],gen->ld.acc_wordsize);
break;
case LSMUL:
case LSDIV:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.scratch1_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_wordsize);
break;
}
@ -1186,15 +1180,15 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
case LADD:
case LSMINUS:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_wordsize);
break;
case LSMUL:
case LSDIV:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.scratch1_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_wordsize);
break;
}
@ -1212,20 +1206,20 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
case LASSIGN:
opos+=sprintf(output_buffer+opos,"\t%s %s,%s\n",operator,operands[0],operands[1]);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.acc_wordsize);
break;
case LADD:
case LSMINUS:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_wordsize);
break;
case LSMUL:
case LSDIV:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.scratch1_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %%%s\n",operator,gen->ld.scratch1_wordsize);
break;
}
@ -1242,19 +1236,19 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
{
case LASSIGN:
opos+=sprintf(output_buffer+opos,"\t%s %%%s,%s\n",operator,gen->ld.acc_32,operands[1]);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %%%s,%s\n",operator,gen->ld.acc_wordsize,operands[1]);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.acc_wordsize);
break;
case LADD:
case LSMINUS:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",operator,operands[0],gen->ld.acc_wordsize);
break;
case LSMUL:
case LSDIV:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[1],gen->ld.acc_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[1],gen->ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s\n",operator,operands[0]);
break;
@ -1304,9 +1298,9 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
break;
case LSMINUS:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_32,operands[0],gen->ld.scratch1_32);
opos+=sprintf(output_buffer+opos,"\t%s %s,%s\n",gen->ld.mov_32,operands[1],operands[0]);
opos+=sprintf(output_buffer+opos,"\t%s %%%s,%s\n",gen->ld.sub_32,gen->ld.scratch1_32,operands[0]);
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",gen->ld.mov_wordsize,operands[0],gen->ld.scratch1_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s %s,%s\n",gen->ld.mov_wordsize,operands[1],operands[0]);
opos+=sprintf(output_buffer+opos,"\t%s %%%s,%s\n",gen->ld.sub_wordsize,gen->ld.scratch1_wordsize,operands[0]);
break;
case LSMUL:

7
gen.h
View File

@ -21,6 +21,8 @@ typedef struct LangDef
const char*add_32;
const char*add_wordsize;
const char*bp;
const char*cmp_32;
const char*cmp_wordsize;
const char*div_32;
const char*div_wordsize;
const char*lea_wordsize;
@ -37,6 +39,9 @@ typedef struct LangDef
const char*sp;
const char*sub_32;
const char*sub_wordsize;
const char*xor_32;
const char*xor_wordsize;
size_t wordsize;
}LangDef;
typedef struct Gen
@ -69,7 +74,7 @@ Gen gen_new(void);
Vec gen_i2r(const Vec*tokens);
bool gen_findret(const PNode*pn,bool found);
size_t gen_stacksize(const PNode*pn);
size_t gen_stacksize(const Gen*gen,const PNode*pn);
void gen(Gen*gen,PNode*pn,FILE*file);
void gen_code(Gen*gen,PNode*pn,FILE*file);
void gen_declare_function(Gen*gen,PNode*pn,FILE*file);

5
i386.c
View File

@ -11,6 +11,8 @@ LangDef gen_i386_langdef(void)
.add_32="addl",
.add_wordsize="addl",
.bp="ebp",
.cmp_32="cmpl",
.cmp_wordsize="cmpl",
.div_32="idivl",
.div_wordsize="idivl",
.lea_wordsize="leal",
@ -27,6 +29,9 @@ LangDef gen_i386_langdef(void)
.sp="esp",
.sub_32="subl",
.sub_wordsize="subl",
.wordsize=4,
.xor_32="xorl",
.xor_wordsize="xorl",
};
return ld;
}

9
main.c
View File

@ -204,6 +204,15 @@ int main(int argc,char**argv)
{
state_set_outfile(&state,(char*)*vec_at(&args,i,const char**),setoutfile,setoutfile_name,state.gen.buildarch);
// Set gen LangDef
switch(state.gen.buildarch)
{
case M_X86_64:state.gen.ld=(LangDef)gen_x86_64_langdef();break;
case M_I386:state.gen.ld=(LangDef)gen_i386_langdef();break;
case M_IR:case M_RUN:break;
default:err_log("Undefined generator language");break;
}
// Generate code based on buildarch
switch(state.gen.buildarch)
{

View File

@ -1,4 +1,4 @@
#*:13
#:13
# Create reference to an i32,
# then dereference it
fn main()

12
tests/x86_64/asm.lr Normal file
View File

@ -0,0 +1,12 @@
#:99
fn f()
{
asm "movq $44,%rax";
ret;
}
fn main()
{
let x=55;
ret x+f();
}

View File

@ -13,6 +13,8 @@ LangDef gen_x86_64_langdef(void)
.add_32="addl",
.add_wordsize="addq",
.bp="rbp",
.cmp_32="cmpl",
.cmp_wordsize="cmpq",
.div_32="idivl",
.div_wordsize="idivq",
.lea_wordsize="leaq",
@ -29,6 +31,9 @@ LangDef gen_x86_64_langdef(void)
.sp="rsp",
.sub_32="subl",
.sub_wordsize="subq",
.wordsize=8,
.xor_32="xorl",
.xor_wordsize="xorq",
};
return ld;
}