From 3d68d7227c1757c8382755ec34fa998771a9778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind?= Date: Sat, 2 Apr 2022 20:14:57 +0200 Subject: [PATCH] started function body --- exercises/05/vslc/src/generator.c | 152 +++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 3 deletions(-) diff --git a/exercises/05/vslc/src/generator.c b/exercises/05/vslc/src/generator.c index 9b12a26..27d5f3e 100644 --- a/exercises/05/vslc/src/generator.c +++ b/exercises/05/vslc/src/generator.c @@ -23,6 +23,12 @@ static const char *record[6] = { "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9" }; +// Helper funcs for generating different nodes +static void generate_print(node_t* node); +static void generate_var_ident(node_t *node); +static void solve_expressions(node_t *node); + +// Helper func for fetching all symbols in a table static uint64_t fetch_symbols(tlhash_t* symbol_table, symbol_t*** symbol_list); void @@ -87,25 +93,165 @@ generate_global_variables ( void ) } putchar('\n'); free(global_list); + } void generate_function ( symbol_t *function ) { // TODO: Generate code for declaring and entering function, then generate its body - node_t *func_root = function->node; + printf("# func %s(nparams: %ld)\n", function->name, function->nparms); + puts(".text"); + printf(".global _%s\n", function->name); LABEL(function->name); ASM(pushq, %rbp); ASM(movq, %rsp, %rbp); + // Push params to stack + for (int arg = 0; arg < MIN(6,function->nparms); arg++) + printf("\tpushq\t%s\n", record[arg] ); + + // How many local variables are inside function + uint64_t no_locals = function->locals->size - function->nparms; + + // 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); + + // Make room for the local vars + while(no_locals--) + ASM(pushq, $0); + + // Now the stack ptr should be 16 byte aligned. + + generate_node(function->node); + putchar('\n'); } + void -generate_node ( node_t *node ) +generate_node ( node_t *node) { // TODO: Generate code corresponding to node + + switch (node->type) + { + case ASSIGNMENT_STATEMENT: + break; + case ADD_STATEMENT: + break; + case SUBTRACT_STATEMENT: + break; + case MULTIPLY_STATEMENT: + break; + case DIVIDE_STATEMENT: + break; + case PRINT_STATEMENT: + generate_print(node); + break; + case RETURN_STATEMENT: + ASM(movq, %rbp, %rsp); + ASM(popq, %rbp); + ASM(ret); + break; + case NULL_STATEMENT: + break; + + case IF_STATEMENT: + case WHILE_STATEMENT: + /* DO NOTHING YET */ + break; + + default: + for (int c = 0; c < node->n_children; c++) + generate_node(node->children[c]); + break; + } +} + + +void +generate_print(node_t* node) +{ + for (uint64_t p = 0; p < node->n_children; p++) + { + node_t *curr_print = node->children[p]; + + // Push rdi and rsi to stack incase there are data in them + //ASM(pushq, %rdi); + //ASM(pushq, %rsi); + switch (curr_print->type) + { + case EXPRESSION: + ASM(movq, $.intout, %rdi); + // Since this is a stack machine, rax allways + // contain the result of expression + ASM(movq, %rax, %rsi); + break; + + case STRING_DATA: + ASM(movq, $.strout, %rdi); + printf("\tmovq\t$.STR%03ld, %%rsi\n", *(uint64_t*)curr_print->data); + break; + + case IDENTIFIER_DATA: + ASM(movq, $.intout, %rdi); + // Need to find the sequence number of var + printf("\tmovq\t"); + generate_var_ident(curr_print); + printf(", %%rsi\n"); + break; + default: + break; + } + ASM(call, printf); + + + // Adds a newline + ASM(movq, $'\n', %rdi); + ASM(call, putchar); + + //ASM(popq, %rsi); + //ASM(popq, %rdi); + + + } +} + +void +generate_var_ident(node_t *node) +{ + symbol_t *ident_sym = node->entry; + switch (ident_sym->type) + { + case SYM_GLOBAL_VAR: + printf("$.%s", ident_sym->name); + break; + + case SYM_PARAMETER: + // If it is a paramter is one of the first 6, seacrch below bp + if (ident_sym->seq < 6) + printf("%ld(%%rbp)", -8 * (ident_sym->seq + 1)); + else + // This requires that the parameters on + // stack is in reversed order + printf("%ld(%%rbp)", 8 * (ident_sym->seq - 6 + 1 )); + break; + + case SYM_LOCAL_VAR: + printf("%ld(%%rbp)", -8 * (ident_sym->seq + 1)); + break; + } +} + + +void +solve_expressions(node_t *node) +{ + } /**Generates the main function with argument parsing and calling of our @@ -146,7 +292,7 @@ generate_main ( symbol_t *first ) printf ( "\tloop PARSE_ARGV\n" ); /* Now the arguments are in order on stack */ - for ( int arg=0; argnparms); arg++ ) + for (int arg = 0; arg < MIN(6,first->nparms); arg++) printf ( "\tpopq\t%s\n", record[arg] ); printf ( "SKIP_ARGS:\n" );