diff --git a/exercises/06/vslc/src/generator.c b/exercises/06/vslc/src/generator.c index 63d121e..e53d8db 100644 --- a/exercises/06/vslc/src/generator.c +++ b/exercises/06/vslc/src/generator.c @@ -1,11 +1,17 @@ #include -#define ASM(opcode, args...) puts("\t"#opcode"\t"#args) -#define LABEL(label) printf("_%s:\n", (char*)label) +#define ASM(opcode, args...) puts("\t"#opcode"\t"#args) +#define LABEL(label) printf("_%s:\n", (char*)label) +#define COMMENT(format, args...) printf("# "format"\n", ##args) + +#define PUSH(param) printf("\tpushq\t%s\t\t\t\t# Scope depth: %ld\n", #param, ++scope_depth) +#define POP(param) printf("\tpopq\t%s\t\t\t\t# Scope depth: %ld\n", #param, --scope_depth) #define NO_REG_RECORD 6 #define NO_CALLE_SAVED_REG 10 +uint64_t scope_depth = 0; + /**Generate table of strings in a rodata section. */ void generate_stringtable ( void ); /**Declare global variables in a bss section */ @@ -145,7 +151,7 @@ generate_stringtable ( void ) * error msg. from main */ puts("# DATA SECTION"); - puts(".data"); + puts(".section .data"); puts(".intout:\t.asciz \"\%ld \""); puts(".strout:\t.asciz \"\%s \""); puts(".errout:\t.asciz \"Wrong number of arguments\""); @@ -182,15 +188,16 @@ generate_function ( symbol_t *function ) // TODO: Generate code for declaring and entering function, then generate its body printf("# func %s(nparams: %ld)\n", function->name, function->nparms); - puts(".text"); + puts(".section .text"); printf(".global _%s\n", function->name); LABEL(function->name); - ASM(pushq, %rbp); + //ASM(pushq, %rbp); + PUSH(%rbp); ASM(movq, %rsp, %rbp); // Push params to stack for (int arg = 0; arg < MIN(NO_REG_RECORD,function->nparms); arg++) - printf("\tpushq\t%s\n", record[arg] ); + printf("\tpushq\t%s\t\t\t\t# Scope depth: %ld\n", record[arg], ++scope_depth); // How many local variables are inside function uint64_t no_locals = function->locals->size - function->nparms; @@ -198,11 +205,13 @@ generate_function ( symbol_t *function ) // IF the stack alignment is not 16 bytes, // add one now as all local var also is 0 if ((MIN(6,function->nparms) + no_locals) % 2) - ASM(pushq, $0); + PUSH($0); + //ASM(pushq, $0); // Make room for the local vars while(no_locals--) - ASM(pushq, $0); + PUSH($0); + //ASM(pushq, $0); // Now the stack ptr should be 16 byte aligned. @@ -224,7 +233,8 @@ generate_node ( node_t *node) { case ASSIGNMENT_STATEMENT: solve_expressions(node->children[1]); - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); writeback_variable(node->children[0], "%rax"); break; @@ -311,7 +321,8 @@ generate_print(node_t* node) { case EXPRESSION: solve_expressions(curr_print); - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); ASM(movq, $.intout, %rdi); ASM(movq, %rax, %rsi); break; @@ -328,14 +339,19 @@ generate_print(node_t* node) default: break; } + PUSH(%rax); + ASM(movq, $0, %rax); + COMMENT("Actual print. Stack size: %ld", scope_depth); ASM(call, printf); + POP(%rax); + } // Adds a newline + PUSH(%rax); + ASM(movq, $0, %rax); ASM(movq, $'\n', %rdi); ASM(call, putchar); - - //ASM(popq, %rsi); - //ASM(popq, %rdi); + POP(%rax); } @@ -407,17 +423,20 @@ solve_expressions(node_t *node) { case IDENTIFIER_DATA: fetch_variable(node, "%rax"); - ASM(pushq, %rax); + PUSH(%rax); + //ASM(pushq, %rax); break; case NUMBER_DATA: printf("\tmovq\t$%ld,%%rax\n",*(int64_t*)node->data); - ASM(pushq, %rax); + PUSH(%rax); + //ASM(pushq, %rax); break; } break; case 1: solve_expressions(node->children[0]); - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); switch (*(char*)node->data) { @@ -428,7 +447,8 @@ solve_expressions(node_t *node) ASM(notq, %rax); break; } - ASM(pushq, %rax); + //ASM(pushq, %rax); + PUSH(%rax); break; case 2: @@ -440,9 +460,11 @@ solve_expressions(node_t *node) // Put rhs in %r10 - ASM(popq, %r10); + //ASM(popq, %r10); + POP(%r10); // put lhs in %rax - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); switch (*(char*)node->data) { @@ -460,7 +482,8 @@ solve_expressions(node_t *node) } // Push result to stack. - ASM(pushq, %rax); + //ASM(pushq, %rax); + PUSH(%rax); break; } } @@ -490,22 +513,26 @@ generate_function_call(node_t *node) for (int arg = arg_list->n_children - 1; arg >= NO_REG_RECORD; arg--) { if (arg_list->children[arg]->type == NUMBER_DATA) - printf("\tpushq\t$%ld\n", - *(int64_t*)arg_list->children[arg]->data + printf("\tpushq\t$%ld\t\t\t\t# Scope depth: %ld\n", + *(int64_t*)arg_list->children[arg]->data, + ++scope_depth ); else { printf("\tpushq\t"); generate_var_ident(arg_list->children[arg]); + printf("\t\t\t\t# Scope depth: %ld", ++scope_depth); putchar('\n'); } } if (arg_list->n_children % 2) - ASM(pushq, $0); + PUSH($0); + //ASM(pushq, $0); } printf("\tcall\t_%s\n", (char*)node->children[0]->data); - ASM(pushq, %rax); + PUSH(%rax); + //ASM(pushq, %rax); printf("# End of function call\n"); /* @@ -527,7 +554,8 @@ void generate_function_return(node_t *node) { solve_expressions(node->children[0]); - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); ASM(leave); ASM(ret); } @@ -540,7 +568,8 @@ solve_statements(node_t *node, char *operator) solve_expressions(node); - ASM(popq, %rax); + //ASM(popq, %rax); + POP(%rax); writeback_variable(node->children[0], "%rax"); }