gen: partial migration of eval functions
This commit is contained in:
parent
3ea76d4685
commit
0d8ff486db
438
gen.c
438
gen.c
@ -207,10 +207,11 @@ void gen_declare_variable(Gen*gen,PNode*pn,FILE*file)
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
gen->stackptr->stacksize+=4;
|
||||
const Tok*vartok=vec_at(&pn->tokens,0,const Tok*);
|
||||
Var var={
|
||||
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
|
||||
.name=vartok->str.buffer,
|
||||
.is_arg=false,
|
||||
/* .type=I32, */
|
||||
.type=I32,
|
||||
/* .location=STACK, */
|
||||
/* .regnum=0, */
|
||||
.stackloc=gen->stackptr->stacksize,
|
||||
@ -680,21 +681,21 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
if(strcmp("true",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=1};
|
||||
vec_push(&stack,&e);
|
||||
eval_elem tmpelem={.type=EI32,.val.i32=1};
|
||||
vec_push(&stack,&tmpelem);
|
||||
}
|
||||
else if(strcmp("false",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
eval_elem tmpelem={.type=EI32,.val.i32=0};
|
||||
vec_push(&stack,&tmpelem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LIDENTIFIER:
|
||||
{
|
||||
eval_elem e={.type=EIDENT,.val.name=vec_at(&rpn_stack,i,const Tok*)->str.buffer};
|
||||
vec_push(&stack,&e);
|
||||
eval_elem tmpelem={.type=EIDENT,.val.name=vec_at(&rpn_stack,i,const Tok*)->str.buffer};
|
||||
vec_push(&stack,&tmpelem);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -702,8 +703,8 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
case LFLOAT:
|
||||
{
|
||||
int32_t d=atoi(vec_at(&rpn_stack,i,const Tok*)->str.buffer);
|
||||
eval_elem e={.type=EI32,.val.i32=d};
|
||||
vec_push(&stack,&e);
|
||||
eval_elem tmpelem={.type=EI32,.val.i32=d};
|
||||
vec_push(&stack,&tmpelem);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -714,12 +715,9 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
|
||||
eval_elem elem[2]={{0}};
|
||||
int32_t integers[2]={0};
|
||||
int32_t res=0;
|
||||
/* size_t var_stackloc[2]={0}; */
|
||||
/* int32_t integers[2]={0}; */
|
||||
size_t nops=2; // 2 unless unary operator
|
||||
|
||||
//if(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0]=='!')
|
||||
if(strcmp("!",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
nops=1;
|
||||
|
||||
@ -742,8 +740,8 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
elem[k].type=EFUNC;
|
||||
fprintf(file,"\tcall %s\n",elem[k].val.name);
|
||||
{
|
||||
eval_elem e={.type=EACC,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
eval_elem tmpelem={.type=EACC,.val.i32=0};
|
||||
vec_push(&stack,&tmpelem);
|
||||
--k;
|
||||
}
|
||||
found=true;
|
||||
@ -771,411 +769,10 @@ 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);
|
||||
}
|
||||
}
|
||||
else if(elem[k].type==EI32)
|
||||
integers[k]=elem[k].val.i32;
|
||||
/* else if(elem[k].type==EI32) */
|
||||
/* integers[k]=elem[k].val.i32; */
|
||||
}
|
||||
|
||||
/* // Debugging output */
|
||||
/* if(elem[1].type==EVAR) */
|
||||
/* printf("'%s' ",elem[1].val.name); */
|
||||
/* else if(elem[1].type==EI32) */
|
||||
/* printf("%d ",elem[1].val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer); */
|
||||
/* if(elem[0].type==EVAR) */
|
||||
/* printf("'%s' ",elem[0].val.name); */
|
||||
/* else if(elem[0].type==EI32) */
|
||||
/* printf("%d ",elem[0].val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* puts(""); */
|
||||
|
||||
// ----------------------------------------------------------
|
||||
/* // Extra debugging output */
|
||||
/* if(elem[1].type==EVAR) */
|
||||
/* { */
|
||||
/* printf("'%s'(%u) ",elem[1].val.name,elem[1].vtype); */
|
||||
/* } */
|
||||
/* else if(elem[1].type==EI32) */
|
||||
/* { */
|
||||
/* printf("%d ",elem[1].val.i32); */
|
||||
/* } */
|
||||
/* else */
|
||||
/* { */
|
||||
/* printf("acc "); */
|
||||
/* } */
|
||||
/* */
|
||||
/* printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer); */
|
||||
/* if(elem[0].type==EVAR) */
|
||||
/* { */
|
||||
/* printf("'%s'(%u) ",elem[0].val.name,elem[0].vtype); */
|
||||
/* } */
|
||||
/* else if(elem[0].type==EI32) */
|
||||
/* { */
|
||||
/* printf("%d ",elem[0].val.i32); */
|
||||
/* } */
|
||||
/* else */
|
||||
/* { */
|
||||
/* printf("acc "); */
|
||||
/* } */
|
||||
/* puts(""); */
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// UNARY OPS
|
||||
if(nops==1)
|
||||
{
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
|
||||
{
|
||||
case '!':
|
||||
if(elem[0].type==EVAR)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp); */
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EI32)
|
||||
{
|
||||
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 e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EACC)
|
||||
{
|
||||
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,gen_x86_64_bp);
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP INT
|
||||
else if(elem[0].type==EI32&&elem[1].type==EI32)
|
||||
{
|
||||
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=EI32,.val.i32=res};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
|
||||
// INT OP ACC
|
||||
else if(
|
||||
(elem[0].type==EACC && elem[1].type==EI32) ||
|
||||
(elem[0].type==EI32 && elem[1].type==EACC)
|
||||
)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
if(elem[0].type==EI32)
|
||||
{
|
||||
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,%%%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,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidiv %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.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",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,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(%%%s),%%eax\n",elem[0].vstackloc,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(%%%s),%%eax\n",elem[0].vstackloc,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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP INT
|
||||
else if(elem[0].type==EI32 && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,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(%%%s),%%eax\n",elem[1].vstackloc,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(%%%s),%%eax\n",elem[1].vstackloc,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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IDENT OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EVAR)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// I32 OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.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==EVAR && elem[0].type==EACC)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gen_x86_64_evalop((PNode*)pn,elem,nops,vec_at(&rpn_stack,i,Tok*),file,&stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1187,6 +784,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); */
|
||||
eval_elem e=*vec_at(&stack,stack.size-1,eval_elem*);
|
||||
int32_t value=0;
|
||||
/* size_t var_stackloc=0; */
|
||||
|
390
x86_64.c
390
x86_64.c
@ -14,3 +14,393 @@ const char*const gen_x86_64_pop_wordsize="popq";
|
||||
const char*const gen_x86_64_sp="rsp";
|
||||
const char*const gen_x86_64_bp="rbp";
|
||||
const char*const gen_x86_64_scratch1="r8d";
|
||||
|
||||
// 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;
|
||||
|
||||
// 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 operator eval_elems */
|
||||
/* sprint(operator,"%s",curtok->str.buffer); */
|
||||
/* */
|
||||
/* // Create operand eval_elems */
|
||||
/* for(size_t i=0;i<nops;++i) */
|
||||
/* { */
|
||||
/* if(elem[i].type==EVAR) */
|
||||
/* sprint(operands[i],"%s",elem[i].val.name); */
|
||||
/* else if(elem[i].type==EI32) */
|
||||
/* sprint(operands[i],"%d",elem[i].val.i32); */
|
||||
/* else */
|
||||
/* sprint(operands[i],"acc"); */
|
||||
/* } */
|
||||
/* */
|
||||
/* // Print output */
|
||||
/* if(nops>1) */
|
||||
/* printf("%s %s %s\n",operands[1],operator,operands[0]); */
|
||||
/* else */
|
||||
/* printf("%s %s\n",operator,operands[0]); */
|
||||
/* } */
|
||||
|
||||
// UNARY OPS
|
||||
if(nops==1)
|
||||
{
|
||||
switch(curtok->str.buffer[0])
|
||||
{
|
||||
case '!':
|
||||
if(elem[0].type==EVAR)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp); */
|
||||
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
vec_push(stack,&tmpelem);
|
||||
}
|
||||
else if(elem[0].type==EI32)
|
||||
{
|
||||
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=EACC,.val={0}};
|
||||
vec_push(stack,&tmpelem);
|
||||
}
|
||||
else if(elem[0].type==EACC)
|
||||
{
|
||||
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,gen_x86_64_bp);
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
vec_push(stack,&tmpelem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP INT
|
||||
else if(elem[0].type==EI32&&elem[1].type==EI32)
|
||||
{
|
||||
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=EI32,.val.i32=res};
|
||||
vec_push(stack,&tmpelem);
|
||||
}
|
||||
|
||||
// INT OP ACC
|
||||
else if(
|
||||
(elem[0].type==EACC && elem[1].type==EI32) ||
|
||||
(elem[0].type==EI32 && elem[1].type==EACC)
|
||||
)
|
||||
{
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
|
||||
if(elem[0].type==EI32)
|
||||
{
|
||||
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,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\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,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EI32)
|
||||
{
|
||||
eval_elem tmpelem={.type=EACC,.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,gen_x86_64_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,gen_x86_64_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,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,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,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,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP INT
|
||||
else if(elem[0].type==EI32 && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
|
||||
switch(curtok->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,elem[1].vstackloc,gen_x86_64_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,gen_x86_64_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,gen_x86_64_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,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,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,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,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
|
||||
switch(curtok->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IDENT OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EVAR)
|
||||
{
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
|
||||
switch(curtok->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// I32 OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EI32)
|
||||
{
|
||||
eval_elem tmpelem={.type=EACC,.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==EVAR && elem[0].type==EACC)
|
||||
{
|
||||
eval_elem tmpelem={.type=EACC,.val={0}};
|
||||
|
||||
switch(curtok->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(stack,&tmpelem);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
3
x86_64.h
3
x86_64.h
@ -3,8 +3,10 @@
|
||||
#include<stdio.h>
|
||||
#include"mem.h"
|
||||
#include"pnode.h"
|
||||
#include"gen.h"
|
||||
|
||||
struct Gen;
|
||||
struct eval_elem;
|
||||
|
||||
extern const char*const gen_x86_64_registers_abi_wordsize[6];
|
||||
extern const char*const gen_x86_64_registers_abi_32[6];
|
||||
@ -16,3 +18,4 @@ extern const char*const gen_x86_64_pop_wordsize;
|
||||
extern const char*const gen_x86_64_sp;
|
||||
extern const char*const gen_x86_64_bp;
|
||||
extern const char*const gen_x86_64_scratch1;
|
||||
void gen_x86_64_evalop(PNode*pn,struct eval_elem*elem,size_t nops,Tok*curtok,FILE*file,Vec*stack);
|
||||
|
Loading…
Reference in New Issue
Block a user