gen: partial migration of eval functions

This commit is contained in:
corey 2024-01-18 13:19:27 -06:00
parent 3ea76d4685
commit 0d8ff486db
3 changed files with 411 additions and 420 deletions

438
gen.c
View File

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

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

View File

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