void emitstmt(void* stmt){ Syntax *st = (Syntax*) stmt; if(st->type == IF_STATEMENT){ int label = labelconditionid++; char c[10]; emit_condition(st->if_statement->condition,label); emitblock(st->if_statement->then); sprintf(c,".LC%d",label); emit_label(c); }else if(st->type == WHILE_SYNTAX){ int labelcondition,labelblock; labelcondition = labelconditionid++; labelblock = labelconditionid++; char c[10]; emit_instr_format("jmp",".LC%d",labelcondition);//to check condition sprintf(c,".LC%d",labelblock); emit_label(c); emitblock(st->while_statement->body); sprintf(c,".LC%d",labelcondition); emit_label(c); emit_condition(st->while_statement->condition,labelblock); }else if(st->type == PRINT_STATEMENT){ emit_instr_format("leaq","%s(%%rip), %%rcx",st->printstmt->tag); emit_ins("call","printf"); }else if(st->type == PRINTDEC_STATEMENT){ emit_expression(st->printexp->exp); emit_ins("movq","%%rax, %%rdx"); emit_ins("leaq",".DEC(%%rip), %%rcx");//.DEC print dec format emit_ins("call","printf"); }else if(st->type == PRINTHEX_STATEMENT){ emit_expression(st->printexp->exp); emit_ins("movq","%%rax, %%rdx"); emit_ins("leaq",".HEX(%%rip), %%rcx");//.HEX print hex format emit_ins("call","printf"); }else if(st->type == ASSIGNMENT){ int tempoffset = findOffsetVar(st->assignment->var_name);//not found is -1 if(tempoffset == -1){ OffsetVarmap* temp = (OffsetVarmap*)malloc(sizeof(OffsetVarmap)); temp->varname = st->assignment->var_name; temp->offset = offset; tempoffset = offset; //printf("offset %d \n",offset); offset = offset+8; list_push(tablevar,temp); } emit_expression(st->assignment->expression); emit_instr_format("movq","%%rax, -%d(%%rbp)",tempoffset);//result to variable. }else if(st->type == VARIABLE){ OffsetVarmap *temp = (OffsetVarmap*)malloc(sizeof(OffsetVarmap)); temp->varname = st->variable->var_name; temp->offset = offset; offset = offset+8; list_push(tablevar,temp); }else{ fprintf(fp,"statement error"); } }
void emit_condition(Syntax* condition,int label){ if(condition->type == BINARY_OPERATOR){ BinaryExpression *binary_syntax = condition->binary_expression; char l[20]; char r[20];//digit no exceed 20 digit. if(binary_syntax->left->type == VARIABLE){ int os = findOffsetVar(binary_syntax->left->variable->var_name); if(os == -1) printf("%s not initialize",binary_syntax->left->variable->var_name); sprintf(l,"-%d(%%rbp)",os); }else if(binary_syntax->left->type == IMMEDIATE){ sprintf(l,"$%d",binary_syntax->left->immediate->value); }else{ printf("condition accept only variable or immediate : left operand"); exit(0); } emit_instr_format("movq","%s, %%rax",l); if(binary_syntax->right->type == VARIABLE){ int os = findOffsetVar(binary_syntax->right->variable->var_name); if(os == -1) printf("%s not initialize",binary_syntax->right->variable->var_name); sprintf(r,"-%d(%%rbp)",os); }else if(binary_syntax->right->type == IMMEDIATE){ sprintf(r,"$%d",binary_syntax->right->immediate->value); }else{ printf("condition accept only variable or immediate : right operand"); exit(0); } emit_instr_format("movq","%s, %%r8",r); if(binary_syntax->binary_type == LESS_THAN){// l = arg1 r= arg2 emit_instr_format("cmpq","%%r8, %%rax"); //cmpq arg2, arg1 gas syntax. emit_instr_format("jl",".LC%d",label); }else if(binary_syntax->binary_type == LESS_THAN_OR_EQUAL){ emit_instr_format("cmpq","%%r8, %%rax"); emit_instr_format("jle",".LC%d",label); }else if(binary_syntax->binary_type == EQUAL){ emit_instr_format("cmpq","%%rax, %%r8"); emit_instr_format("je",".LC%d",label); }else if(binary_syntax->binary_type == NOT_EQ){ emit_instr_format("cmpq","%%rax ,%%r8"); emit_instr_format("jne",".LC%d",label); }else{ printf("unknown condition"); } }else printf("invalid condition"); }
void emit_expression(Syntax *exp){ if (exp->type == UNARY_OPERATOR) { UnaryExpression *unary_syntax = exp->unary_expression; emit_expression(unary_syntax->expression); if (unary_syntax->unary_type == BITWISE_NEGATION) { emit_ins("notq", "%%rax"); } else { emit_ins("testq", "$0xFFFFFFFF, %%rax"); emit_ins("setz", "%%al"); } } else if (exp->type == IMMEDIATE) { //may be fix 64 bit emit_instr_format("movq", "$%d, %%rax", exp->immediate->value); } else if (exp->type == VARIABLE) { int tempoffset = findOffsetVar(exp->variable->var_name); emit_instr_format("movq", "-%d(%%rbp), %%rax",tempoffset); } else if (exp->type == BINARY_OPERATOR) { BinaryExpression *binary_syntax = exp->binary_expression; char l[20]; char r[20];//digit no exceed 20 digit. if(binary_syntax->left->type == VARIABLE){ int os = findOffsetVar(binary_syntax->left->variable->var_name); if(os == -1) printf("%s not initialize",binary_syntax->left->variable->var_name); sprintf(l,"-%d(%%rbp)",os); }else if(binary_syntax->left->type == IMMEDIATE){ sprintf(l,"$%d",binary_syntax->left->immediate->value); }else{ emit_expression(binary_syntax->left); } if(binary_syntax->right->type == VARIABLE){ int os = findOffsetVar(binary_syntax->right->variable->var_name); if(os == -1) printf("%s not initialize",binary_syntax->right->variable->var_name); sprintf(r,"-%d(%%rbp)",os); }else if(binary_syntax->right->type == IMMEDIATE){ sprintf(r,"$%d",binary_syntax->right->immediate->value); }else{ emit_expression(binary_syntax->right); } /* int stack_offset = ctx->stack_offset; ctx->stack_offset -= WORD_SIZE; emit_instr(out, "sub", "$4, %esp"); write_syntax(out, binary_syntax->left, ctx); emit_instr_format(out, "mov", "%%eax, %d(%%ebp)", stack_offset); write_syntax(out, binary_syntax->right, ctx); */ emit_instr_format("movq", "%%rax ,%%r8");//bug emit_instr_format("movq","%s ,%%rax",l); if (binary_syntax->binary_type == MULTIPLICATION) { emit_instr_format("imulq", "%s ,%%rax",r); } else if (binary_syntax->binary_type == ADDITION) { emit_instr_format("addq", "%s ,%%rax",r); } else if (binary_syntax->binary_type == SUBTRACTION) { emit_instr_format("movq", "%s, %%r10", r); emit_ins("subq", "%%r10, %%rax"); //emit_instr_format("movq", "%s, %%rax", r); } else if (binary_syntax->binary_type == DIVIDE) { emit_ins("cltd",NULL); emit_instr_format("idivl","%s",r); } else if (binary_syntax->binary_type == MODULO){ emit_ins("cltd",NULL); emit_instr_format("idivl","%s",r); emit_ins("movq","%rdx, %rax"); } else{ printf("expression error"); } } }
void write_syntax(FILE *out, Syntax *syntax){ printf("write_syntax\n"); if(syntax->type == IMMEDIATE){ printf("case gen immediate\n"); emit_instr_format(out, "mov", "$%d, %%eax", syntax->immediate->value); } else if (syntax->type == VARIABLE) { printf("case gen var\n"); emit_instr_format(out, "mov", "-%d(%%ebp), %%eax", 4*(syntax->variable->var_index+1)); } else if (syntax->type == BINARY_OPERATOR){ printf("case gen binary\n"); BinaryExpression *binary_syntax = syntax->binary_expression; //reserve space for temporary write_syntax(out, binary_syntax->left); emit_instr(out, "sub", "$4, %esp"); emit_instr(out, "mov", "%eax, 0(%esp)"); write_syntax(out, binary_syntax->right); if(binary_syntax->binary_type == MULTIPLICATION){ emit_instr(out, "mull", "0(%esp)"); //emit_instr(out, "mull", "%ebx"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == DIVISION) { //edx:eax / 0(%esp) emit_instr(out, "mov", "$0, %edx"); emit_instr(out, "xchg", "0(%esp), %eax"); emit_instr(out, "divl", "0(%esp)"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == MOD) { emit_instr(out, "mov", "$0, %edx"); emit_instr(out, "xchg", "0(%esp), %eax"); emit_instr(out, "divl", "0(%esp)"); emit_instr(out, "mov", "%edx, %eax"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == ADDITION){ emit_instr(out, "add", "0(%esp), %eax"); //emit_instr(out, "add", "%ebx, %eax"); //TODO: check if this instruction redundant emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == SUBTRACTION) { emit_instr(out, "sub", "%eax, 0(%esp)"); emit_instr(out, "mov", "0(%esp), %eax"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == COMPARISION) { emit_instr(out, "xor", "0(%esp), %eax"); emit_instr(out, "add", "$4, %esp"); } } else if (syntax->type == ASSIGNMENT) { printf("case gen assignment\n"); write_syntax(out, syntax->assignment->expression); emit_instr_format(out, "mov", "%%eax, -%d(%%ebp)", 4*(syntax->assignment->var_index+1)); } else if (syntax->type == SHOW_STATEMENT){ printf("case get SHOW statement"); if(syntax->show_statement->decOrHex == 'd'){ emit_instr_format(out, "pushl", "-%d(%%ebp)", 4*(syntax->show_statement->var->variable->var_index+1)); emit_instr(out, "pushl", "$.LC0"); emit_instr(out, "call", "_printf"); } else if (syntax->show_statement->decOrHex == 'h') { emit_instr_format(out, "pushl", "-%d(%%ebp)", 4*(syntax->show_statement->var->variable->var_index+1)); emit_instr(out, "pushl", "$.LC1"); emit_instr(out, "call", "_printf"); } } else if (syntax->type == IF_STATEMENT){ char *label; printf("case if statement kaa"); write_syntax(out, syntax->if_statement->condition); emit_instr(out, "test", "%eax, %eax"); label = gen_label("LC"); emit_instr_format(out, "jne", "%s", label); write_syntax(out, syntax->if_statement->then); emit_label(out, label); //emit_instr(out, "call", "_printf"); } else if (syntax->type == FOR_STATEMENT) { char *start_label; char *end_label; if(syntax->for_statement->startNum->type == IMMEDIATE){ emit_instr_format(out, "mov", "$%d, %%edi", syntax->for_statement->startNum->immediate->value); } else if (syntax->for_statement->startNum->type == VARIABLE) { emit_instr_format(out, "mov", "-%d(%%ebp), %%edi", 4*(syntax->for_statement->startNum->variable->var_index+1)); } if(syntax->for_statement->stopNum->type == IMMEDIATE){ emit_instr_format(out, "mov", "$%d, %%esi", syntax->for_statement->stopNum->immediate->value); } else if (syntax->for_statement->stopNum->type == VARIABLE) { emit_instr_format(out, "mov", "-%d(%%ebp), %%esi", 4*(syntax->for_statement->stopNum->variable->var_index+1)); } start_label = gen_label("LC"); end_label = gen_label("LC"); emit_label(out, start_label); emit_instr(out, "cmp", "%edi, %esi"); //confuse which jump condition to use. emit_instr_format(out, "jg", "%s", end_label); write_syntax(out, syntax->for_statement->expression); emit_instr(out, "inc", "%esi"); emit_instr_format(out, "jmp", "%s", start_label); emit_label(out, end_label); } else if (syntax->type == INPUT) { //printf("gen INPUT\n"); List *lines = syntax->input->lines; int i; for (i = list_length(lines)-1; i >= 0; i--) { //printf("*"); write_syntax(out, list_get(lines, i)); } } else if(syntax->type = MINUS){ printf("gen minus\n"); write_syntax(out,syntax->minus->expression); emit_instr(out, "xor", "%ebx, %ebx"); emit_instr(out, "sub", "%eax, %ebx"); emit_instr(out, "mov", "%ebx, %eax"); } else { printf("last case\n"); } /*else if(syntax->type = MINUS){ write_syntax(out,syntax->expression); emit_instr(out, "sub", "0(%esp), %eax"); }*/ }