fully merge separate buildarch expression evaluators

This commit is contained in:
corey 2024-01-20 07:33:28 -06:00
parent 0f2cc784eb
commit 0cb0988182
6 changed files with 410 additions and 952 deletions

418
gen.c
View File

@ -662,15 +662,9 @@ Vec gen_i2r(const Vec*tokens)
// Convert to infix, then evaluate
void gen_eval(Gen*gen,const PNode*pn,FILE*file)
{
if(gen->buildarch==M_I386)
{
gen_i386_eval(gen,pn,file);
return;
}
Vec rpn_stack={0};
Vec stack=vec_new(sizeof(eval_elem));
LangDef ld=gen_x86_64_langdef();
LangDef ld=(gen->buildarch==M_X86_64)?(gen_x86_64_langdef()):(gen_i386_langdef());
rpn_stack=gen_i2r(&pn->tokens);
if(gen->showrpn)vec_print_tokens(&rpn_stack);
@ -758,7 +752,7 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,elem[k].val.name);
}
gen_x86_64_evalop((PNode*)pn,elem,nops,vec_at(&rpn_stack,i,Tok*),file,&stack);
gen_evalop(gen,(PNode*)pn,elem,nops,vec_at(&rpn_stack,i,Tok*),file,&stack);
}
break;
@ -770,7 +764,7 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
// Empty remaining variables/integers on the stack
if(stack.size>0)
{
/* gen_x86_64_evalop((PNode*)pn,&elem,nops,vec_at(&rpn_stack,0,Tok*),file,&stack); */
/* gen_evalop((PNode*)pn,&elem,nops,vec_at(&rpn_stack,0,Tok*),file,&stack); */
eval_elem e=*vec_at(&stack,stack.size-1,eval_elem*);
int32_t value=0;
/* size_t var_stackloc=0; */
@ -813,3 +807,409 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
vec_free(&rpn_stack);
vec_free(&stack);
}
// Evaluate one operation
void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file,Vec*stack)
{
uint32_t integers[2]={elem[0].val.i32,elem[1].val.i32};
uint32_t res=0;
LangDef ld=(gen->buildarch==M_X86_64)?gen_x86_64_langdef():gen_i386_langdef();
// TODO: refactor this function to be smarter,
// removing special cases and pendantic-ness
// Create strings of operands, operators
/* { */
/* char operator[1024]; */
/* char operands[2][1024]; */
/* */
/* // Create operand eval_elems */
/* for(size_t i=0;i<nops;++i) */
/* { */
/* if(elem[i].type==EE_VAR) */
/* sprint(operands[i],"v::%s",elem[i].val.name); */
/* else if(elem[i].type==EE_FUNC) */
/* sprint(operands[i],"f::%s",elem[i].val.name); */
/* else if(elem[i].type==EE_I32) */
/* sprint(operands[i],"%d",elem[i].val.i32); */
/* else */
/* sprint(operands[i],"%%eax"); */
/* } */
/* */
/* if(nops>1&&elem[0].type==EE_I32&&elem[1].type==EE_I32) */
/* printf("[[[%d+%d=%d]]]\n",elem[1].val.i32,elem[0].val.i32,elem[1].val.i32+elem[0].val.i32); */
/* */
/* // Convert operator name to instruction name */
/* if(strcmp("+",curtok->str.buffer)==0) */
/* sprint(operator,"addl"); */
/* else if(strcmp("-",curtok->str.buffer)==0) */
/* sprint(operator,"subl"); */
/* else if(strcmp("*",curtok->str.buffer)==0) */
/* sprint(operator,"imull"); */
/* else if(strcmp("/",curtok->str.buffer)==0) */
/* sprint(operator,"idivl"); */
/* else if(strcmp("=",curtok->str.buffer)==0) */
/* sprint(operator,"movl"); */
/* */
/* // Print output */
/* if(nops>1) */
/* printf("%s %s, %s\n",operator,operands[0],operands[1]); */
/* else */
/* printf("%s %s\n",operator,operands[0]); */
/* } */
// UNARY OPS
if(nops==1)
{
switch(curtok->str.buffer[0])
{
case '!':
if(elem[0].type==EE_VAR)
{
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp); */
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
else if(elem[0].type==EE_I32)
{
fprintf(file,"\tmovl $%d,%%eax\n",integers[0]);
fprintf(file,"\tcmpl $0,%%eax\n");
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
else if(elem[0].type==EE_ACC)
{
fprintf(file,"\tcmpl $0,%%eax\n");
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
//fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
break;
}
}
// INT OP INT
else if(elem[0].type==EE_I32&&elem[1].type==EE_I32)
{
switch(curtok->str.buffer[0])
{
case '+':res=integers[1]+integers[0];break;
case '-':res=integers[1]-integers[0];break;
case '*':res=integers[1]*integers[0];break;
case '/':res=integers[1]/integers[0];break;
}
eval_elem tmpelem={.type=EE_I32,.val.i32=res};
vec_push(stack,&tmpelem);
}
// INT OP ACC
else if(
(elem[0].type==EE_ACC && elem[1].type==EE_I32) ||
(elem[0].type==EE_I32 && elem[1].type==EE_ACC)
)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
if(elem[0].type==EE_I32)
{
eval_elem etmp=elem[0];
elem[0]=elem[1];
elem[1]=etmp;
}
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\timull %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\tidiv %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// INT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_I32)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\timull %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\tidivl %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP INT
else if(elem[0].type==EE_I32 && elem[1].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,ld.scratch1);
fprintf(file,"\timul %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,ld.scratch1);
fprintf(file,"\tidivl %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
// I32 OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_I32)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to accumulator",vec_at(&pn->tokens,0,Tok*)->line,tmpelem.val.name);
/* vec_push(stack,&tmpelem); */
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull $%d\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl $%d\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
}
}
// ACC OP IDENT
else if(elem[1].type==EE_VAR && elem[0].type==EE_ACC)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
}

1
gen.h
View File

@ -64,6 +64,7 @@ void gen_declare_variable(Gen*gen,PNode*pn,FILE*file);
void gen_epilog(Gen*gen,const PNode*pn,FILE*file);
void gen_eval(Gen*gen,const PNode*pn,FILE*file);
void gen_eval_analyze(const PNode*pn);
void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file,Vec*stack);
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);

521
i386.c
View File

@ -3,17 +3,6 @@
#include"i386.h"
#include"state.h"
const char*const gen_i386_registers_abi_wordsize[4]={"edi","esi","edx","ecx"};
const char*const gen_i386_registers_abi_32[4]={"edi","esi","edx","ecx"};
const char*const gen_i386_mov_wordsize="movl";
const char*const gen_i386_mov_32="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";
const char*const gen_i386_sp="esp";
const char*const gen_i386_bp="ebp";
const char*const gen_i386_scratch1="ecx";
LangDef gen_i386_langdef(void)
{
LangDef ld={
@ -30,513 +19,3 @@ LangDef gen_i386_langdef(void)
};
return ld;
}
// Convert to infix, then evaluate
void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file)
{
Vec rpn_stack={0};
Vec stack=vec_new(sizeof(eval_elem));
LangDef ld=gen_i386_langdef();
rpn_stack=gen_i2r(&pn->tokens);
if(gen->showrpn)vec_print_tokens(&rpn_stack);
/* gen_eval_analyze(pn); */
// Evaluate RPN
if(rpn_stack.buffer&&rpn_stack.size>0)
{
for(size_t i=0;i<rpn_stack.size;++i)
{
switch(vec_at(&rpn_stack,i,const Tok*)->type)
{
case LKEYWORD:
{
if(strcmp("true",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
{
eval_elem e={.type=EE_I32,.val.i32=1};
vec_push(&stack,&e);
}
else if(strcmp("false",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
{
eval_elem e={.type=EE_I32,.val.i32=0};
vec_push(&stack,&e);
}
}
break;
case LIDENTIFIER:
{
eval_elem e={.type=EE_IDENT,.val.name=vec_at(&rpn_stack,i,const Tok*)->str.buffer};
vec_push(&stack,&e);
}
break;
case LINTEGER:
case LFLOAT:
{
int32_t d=atoi(vec_at(&rpn_stack,i,const Tok*)->str.buffer);
eval_elem e={.type=EE_I32,.val.i32=d};
vec_push(&stack,&e);
}
break;
case LOPERATOR:
// Get operands
if(stack.size>1)
{
eval_elem elem[2]={{0}};
int32_t integers[2]={0};
int32_t res=0;
size_t var_stackloc[2]={0};
// Get top two stack elements (variables, integers, etc.)
for(size_t k=0;k<2;++k)
{
elem[k]=*vec_at(&stack,stack.size-1,eval_elem*);
vec_pop(&stack);
if(elem[k].type==EE_IDENT)
{
bool found=false;
// Identify functions
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
{
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,elem[k].val.name)==0)
{
elem[k].type=EE_FUNC;
fprintf(file,"\tcall %s\n",elem[k].val.name);
{
eval_elem e={.type=EE_ACC,.val.i32=0};
vec_push(&stack,&e);
--k;
}
found=true;
break;
}
}
// Identify variables
if(!found)
{
for(size_t j=0;j<gen->stackptr->vars.size;++j)
{
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,elem[k].val.name)==0)
{
elem[k].type=EE_VAR;
var_stackloc[k]=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
found=true;
break;
}
}
if(!found)
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,elem[k].val.name);
}
}
else if(elem[k].type==EE_I32)
integers[k]=elem[k].val.i32;
}
// Debugging output
/* if(elem[1].type==EE_VAR) */
/* printf("'%s' ",elem[1].val.name); */
/* else if(elem[1].type==EE_I32) */
/* printf("%d ",elem[1].val.i32); */
/* else */
/* printf("acc "); */
/* printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer); */
/* if(elem[0].type==EE_VAR) */
/* printf("'%s' ",elem[0].val.name); */
/* else if(e1.type==EE_I32) */
/* printf("%d ",e1.val.i32); */
/* else */
/* printf("acc "); */
/* puts(""); */
// INT OP INT
if(elem[0].type==EE_I32&&elem[1].type==EE_I32)
{
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
{
case '+':res=integers[1]+integers[0];break;
case '-':res=integers[1]-integers[0];break;
case '*':res=integers[1]*integers[0];break;
case '/':res=integers[1]/integers[0];break;
}
eval_elem e={.type=EE_I32,.val.i32=res};
vec_push(&stack,&e);
}
// INT OP ACC
else if(
(elem[0].type==EE_ACC && elem[1].type==EE_I32) ||
(elem[0].type==EE_I32 && elem[1].type==EE_ACC)
)
{
eval_elem e={.type=EE_ACC,.val={0}};
if(elem[0].type==EE_I32)
{
eval_elem etmp=elem[0];
elem[0]=elem[1];
elem[1]=etmp;
}
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(&stack,&e);
break;
case '-':
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 $%d,%%ecx\n",elem[1].val.i32);
fprintf(file,"\timull %%ecx\n");
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%ecx\n",elem[1].val.i32);
fprintf(file,"\tidiv %%ecx\n");
vec_push(&stack,&e);
break;
}
}
// INT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_I32)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.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(%%%s),%%eax\n",var_stackloc[0],ld.bp);
fprintf(file,"\tmovl $%d,%%ecx\n",elem[1].val.i32);
fprintf(file,"\timull %%ecx\n");
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
fprintf(file,"\tmovl $%d,%%ecx\n",elem[1].val.i32);
fprintf(file,"\tidivl %%ecx\n");
vec_push(&stack,&e);
break;
}
}
// IDENT OP INT
else if(elem[0].type==EE_I32 && elem[1].type==EE_VAR)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,var_stackloc[1],ld.bp);
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.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(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\tmovl $%d,%%ecx\n",elem[0].val.i32);
fprintf(file,"\timul %%ecx\n");
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\tmovl $%d,%%ecx\n",elem[0].val.i32);
fprintf(file,"\tidivl %%ecx\n");
vec_push(&stack,&e);
break;
}
}
// IDENT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_VAR)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
}
}
// IDENT OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_VAR)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],ld.bp);
vec_push(&stack,&e);
break;
}
}
// I32 OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_I32)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to accumulator",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
/* vec_push(&stack,&e); */
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull $%d\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl $%d\n",elem[0].val.i32);
vec_push(&stack,&e);
break;
}
}
// ACC OP IDENT
else if(elem[1].type==EE_VAR && elem[0].type==EE_ACC)
{
eval_elem e={.type=EE_ACC,.val={0}};
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[1],ld.bp);
vec_push(&stack,&e);
break;
}
}
}
break;
}
}
}
// Empty remaining variables/integers on the stack
if(stack.size>0)
{
eval_elem e=*vec_at(&stack,stack.size-1,eval_elem*);
int32_t value=0;
size_t var_stackloc=0;
if(e.type==EE_I32)
{
value=e.val.i32;
fprintf(file,"\tmovl $%d,%%eax\n",value);
}
else if(e.type==EE_IDENT)
{
bool found=false;
// Identify functions
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
{
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,e.val.name)==0)
{
e.type=EE_FUNC;
fprintf(file,"\tcall %s\n",e.val.name);
found=true;
break;
}
}
// Identify variables
if(!found)
{
for(size_t j=0;j<gen->stackptr->vars.size;++j)
{
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,e.val.name)==0)
{
e.type=EE_VAR;
var_stackloc=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc,ld.bp);
found=true;
break;
}
}
if(!found)
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
}
}
}
vec_free(&rpn_stack);
vec_free(&stack);
}

13
i386.h
View File

@ -4,19 +4,6 @@
#include"mem.h"
#include"pnode.h"
struct Gen;
struct LangDef;
extern const char*const gen_i386_registers_abi_wordsize[4];
extern const char*const gen_i386_registers_abi_32[4];
extern const char*const gen_i386_mov_wordsize;
extern const char*const gen_i386_mov_32;
extern const char*const gen_i386_push_wordsize;
extern const char*const gen_i386_sub_wordsize;
extern const char*const gen_i386_pop_wordsize;
extern const char*const gen_i386_sp;
extern const char*const gen_i386_bp;
extern const char*const gen_i386_scratch1;
struct LangDef gen_i386_langdef(void);
void gen_i386_eval(struct Gen*gen,const PNode*pn,FILE*file);

406
x86_64.c
View File

@ -21,409 +21,3 @@ LangDef gen_x86_64_langdef(void)
};
return ld;
}
// Evaluate one operation
void gen_x86_64_evalop(PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file,Vec*stack)
{
uint32_t integers[2]={elem[0].val.i32,elem[1].val.i32};
uint32_t res=0;
LangDef ld=gen_x86_64_langdef();
// TODO: refactor this function to be smarter,
// removing special cases and pendantic-ness
// Create strings of operands, operators
/* { */
/* char operator[1024]; */
/* char operands[2][1024]; */
/* */
/* // Create operand eval_elems */
/* for(size_t i=0;i<nops;++i) */
/* { */
/* if(elem[i].type==EE_VAR) */
/* sprint(operands[i],"v::%s",elem[i].val.name); */
/* else if(elem[i].type==EE_FUNC) */
/* sprint(operands[i],"f::%s",elem[i].val.name); */
/* else if(elem[i].type==EE_I32) */
/* sprint(operands[i],"%d",elem[i].val.i32); */
/* else */
/* sprint(operands[i],"%%eax"); */
/* } */
/* */
/* if(nops>1&&elem[0].type==EE_I32&&elem[1].type==EE_I32) */
/* printf("[[[%d+%d=%d]]]\n",elem[1].val.i32,elem[0].val.i32,elem[1].val.i32+elem[0].val.i32); */
/* */
/* // Convert operator name to instruction name */
/* if(strcmp("+",curtok->str.buffer)==0) */
/* sprint(operator,"addl"); */
/* else if(strcmp("-",curtok->str.buffer)==0) */
/* sprint(operator,"subl"); */
/* else if(strcmp("*",curtok->str.buffer)==0) */
/* sprint(operator,"imull"); */
/* else if(strcmp("/",curtok->str.buffer)==0) */
/* sprint(operator,"idivl"); */
/* else if(strcmp("=",curtok->str.buffer)==0) */
/* sprint(operator,"movl"); */
/* */
/* // Print output */
/* if(nops>1) */
/* printf("%s %s, %s\n",operator,operands[0],operands[1]); */
/* else */
/* printf("%s %s\n",operator,operands[0]); */
/* } */
// UNARY OPS
if(nops==1)
{
switch(curtok->str.buffer[0])
{
case '!':
if(elem[0].type==EE_VAR)
{
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp); */
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
else if(elem[0].type==EE_I32)
{
fprintf(file,"\tmovl $%d,%%eax\n",integers[0]);
fprintf(file,"\tcmpl $0,%%eax\n");
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
else if(elem[0].type==EE_ACC)
{
fprintf(file,"\tcmpl $0,%%eax\n");
fprintf(file,"\tsete %%al\n");
fprintf(file,"\tmovzbl %%al,%%eax\n");
//fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
eval_elem tmpelem={.type=EE_ACC,.val={0}};
vec_push(stack,&tmpelem);
}
break;
}
}
// INT OP INT
else if(elem[0].type==EE_I32&&elem[1].type==EE_I32)
{
switch(curtok->str.buffer[0])
{
case '+':res=integers[1]+integers[0];break;
case '-':res=integers[1]-integers[0];break;
case '*':res=integers[1]*integers[0];break;
case '/':res=integers[1]/integers[0];break;
}
eval_elem tmpelem={.type=EE_I32,.val.i32=res};
vec_push(stack,&tmpelem);
}
// INT OP ACC
else if(
(elem[0].type==EE_ACC && elem[1].type==EE_I32) ||
(elem[0].type==EE_I32 && elem[1].type==EE_ACC)
)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
if(elem[0].type==EE_I32)
{
eval_elem etmp=elem[0];
elem[0]=elem[1];
elem[1]=etmp;
}
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\timull %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\tidiv %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// INT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_I32)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\timull %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,ld.scratch1);
fprintf(file,"\tidivl %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP INT
else if(elem[0].type==EE_I32 && elem[1].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,ld.scratch1);
fprintf(file,"\timul %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,ld.scratch1);
fprintf(file,"\tidivl %%%s\n",ld.scratch1);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP IDENT
else if(elem[0].type==EE_VAR && elem[1].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
// IDENT OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_VAR)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
// I32 OP ACC
else if(elem[1].type==EE_ACC && elem[0].type==EE_I32)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
err_log("%u: cannot assign to accumulator",vec_at(&pn->tokens,0,Tok*)->line,tmpelem.val.name);
/* vec_push(stack,&tmpelem); */
break;
case '+':
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull $%d\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl $%d\n",elem[0].val.i32);
vec_push(stack,&tmpelem);
break;
}
}
// ACC OP IDENT
else if(elem[1].type==EE_VAR && elem[0].type==EE_ACC)
{
eval_elem tmpelem={.type=EE_ACC,.val={0}};
switch(curtok->str.buffer[0])
{
case '=':
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '+':
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '-':
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '*':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\timull -%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
case '/':
fprintf(file,"\txorl %%edx,%%edx\n");
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[1].vstackloc,ld.bp);
vec_push(stack,&tmpelem);
break;
}
}
}

View File

@ -5,9 +5,6 @@
#include"pnode.h"
#include"gen.h"
struct Gen;
struct eval_elem;
struct LangDef;
struct LangDef gen_x86_64_langdef(void);
void gen_x86_64_evalop(PNode*pn,struct eval_elem*elem,size_t nops,Tok*curtok,FILE*file,Vec*stack);