%{ /* vim: filetype=c */ #define CODE #include #include #include #include "tree.h" #include "code_gen.h" /* TODO (-a)+b */ /* TODO imul -> imulq, add -> addq */ /* TODO bugs - hopefully fixed: * func f(a,b,c,d) return ((a+1)+(b+1))+((c+1)+(d+1)); end; * func f(a,b,c,d) var b:=a; var c:=b; var d:=c; return a+b+c+d; end; * mul, add etc. with direct memory access */ /* TODO immediate values in assignments */ /* TODO assignment with immediate value/variable on RHS */ /* TODO immediate values in boolean expressions */ /* TODO optimize boolean expressions */ /* FIXME if_then label not inserted */ %} %start stat %term OP_Not=1 OP_Negation=2 OP_Addition=3 OP_Multiplication=4 OP_Disjunction=5 OP_Greater=6 OP_Equal=7 OP_ID=8 OP_Number=9 OP_Field=10 OP_Return=11 OP_Zero=12 OP_One=13 OP_Exprs=14 OP_Call=15 OP_Assign=16 OP_If=17 OP_Stats=18 OP_Empty=19 OP_Ifstats=20 OP_While=21 OP_CallNoParam=22 OP_Arg=23 %% stat: ret # 0 # stat: assign # 0 # stat: bexpr # 0 # stat: expr # 0 # assign: OP_Assign(OP_ID, expr) # 1 # if(bnode->kids[0]->param_index!=-1 && !call) { printf("\tmovq %%%s, %%%s /* x */\n", bnode->reg, get_param_reg(bnode->kids[0]->param_index)); } else if(bnode->kids[0]->param_index!=-1 && call) { printf("\tmovq %%%s, %i(%%rsp) /* y */\n", bnode->reg, 8*(variables-bnode->kids[0]->param_index)); } else { printf("\tmovq %%%s, %i(%%rsp) /* z */\n", bnode->reg, bnode->kids[0]->value); } assign: OP_Assign(OP_Field(expr,OP_ID), expr) # 1 # printf("\tmovq %%%s, %li(%%%s)\n", bnode->kids[1]->reg, 8*bnode->kids[0]->value, bnode->kids[0]->reg); ret: OP_Return(expr) # 1 # move(bnode->reg, "rax"); ret(); expr: OP_ID # 1 # if(bnode->param_index!=-1 && !call) { move(get_param_reg(bnode->param_index), bnode->reg); } else if(bnode->param_index!=-1 && call) { printf("\tmov %i(%%rsp), %%%s\n", 8*(variables-bnode->param_index), bnode->reg); } else { printf("\tmovq %i(%%rsp), %%%s\n", bnode->value, bnode->reg); } expr: imm # 1 # printf("\tmovq $%li, %%%s\n", bnode->value, bnode->reg); expr: call # 0 # expr: OP_Negation(expr) # 1 # printf("\tnegq %%%s\n", bnode->reg); expr: OP_Addition(expr,expr) # 1 # printf("\taddq %%%s, %%%s\n", bnode->kids[1]->reg, bnode->kids[0]->reg); expr: OP_Addition(imm,expr) # 1 # printf("\taddq $%li, %%%s\n", bnode->kids[0]->value, bnode->kids[1]->reg); move(bnode->kids[1]->reg, bnode->reg); expr: OP_Addition(expr,imm) # 1 # if(bnode->kids[0]->op==OP_ID) { move(bnode->kids[0]->reg, bnode->reg); printf("\taddq $%li, %%%s /* x2 */\n", bnode->kids[1]->value, bnode->reg); } else { printf("\taddq $%li, %%%s /* y2 */\n", bnode->kids[1]->value, bnode->kids[0]->reg); } expr: OP_Multiplication(expr,expr) # 1 # printf("\timulq %%%s, %%%s\n", bnode->kids[1]->reg, bnode->kids[0]->reg); expr: OP_Multiplication(imm,expr) # 1 # printf("\timulq $%li, %%%s\n", bnode->kids[0]->value, bnode->kids[1]->reg); move(bnode->kids[1]->reg, bnode->reg); expr: OP_Multiplication(expr,imm) # 1 # if(bnode->kids[0]->op==OP_ID) { move(bnode->kids[0]->reg, bnode->reg); printf("\timulq $%li, %%%s\n", bnode->kids[1]->value, bnode->reg); } else { printf("\timulq $%li, %%%s\n", bnode->kids[1]->value, bnode->kids[0]->reg); } expr: OP_Field(expr,OP_ID) # 2 # printf("\tmovq %li(%%%s), %%%s\n", 8*bnode->value, bnode->kids[0]->reg, bnode->reg); expr: OP_Field(imm,OP_ID) # 1 # printf("\tmovq %li, %%%s\n", bnode->kids[0]->value+bnode->value*8, bnode->reg); call: OP_Call(exprs) # 0 # prepare_call(bnode->name, bnode->reg); /* reg_return=bnode->reg; */ do_call(bnode->name, bnode->reg); call: OP_CallNoParam # 0 # # prepare_call(bnode->name, bnode->reg); /* reg_return=bnode->reg; */ /* prepare_call(bnode->name); */ do_call(bnode->name, bnode->reg); exprs: OP_Arg(expr) # 0 # /* reg_return=bnode->reg; function_name=bnode->name; */ /* prepare_call(bnode->name); */ exprs: OP_Exprs(exprs,exprs) # 0 # zero: OP_Negation(zero) # 0 # zero: OP_Zero # 0 # zero: OP_Multiplication(zexpr,zero) # 0 # zero: OP_Multiplication(zero,zexpr) # 0 # zexpr: zero # 0 # zexpr: imm # 0 # zexpr: OP_Negation(zexpr) # 0 # zexpr: OP_Addition(zexpr,zexpr) # 0 # zexpr: OP_Multiplication(zexpr,zexpr) # 0 # zexpr: OP_Field(zexpr,OP_ID) # 0 # zexpr: OP_ID # 0 # imm: zero # 0 # imm: OP_Negation(imm) # 0 # bnode->value=-bnode->kids[0]->value; imm: OP_Addition(imm,imm) # 0 # bnode->value=bnode->kids[0]->value+bnode->kids[1]->value; imm: OP_Multiplication(imm,imm) # 0 # bnode->value=bnode->kids[0]->value*bnode->kids[1]->value; imm: OP_Number # 0 # imm: OP_Zero # 0 # imm: OP_One # 0 # bexpr: OP_Disjunction(bexpr,bexpr) # 0 # bexpr: OP_Not(bexpr) # 0 # bexpr: OP_Greater(expr,expr) # 0 # bexpr: OP_Equal(expr,expr) # 0 # %%