From 36680f5c8d9f0b499466cbf429dcb97941cbe117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind?= Date: Thu, 31 Mar 2022 23:12:12 +0200 Subject: [PATCH] Finished two of the generator parts - string table -global vars beginnings of function --- exercises/05/vslc/src/generator.c | 56 ++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/exercises/05/vslc/src/generator.c b/exercises/05/vslc/src/generator.c index 6896772..9b12a26 100644 --- a/exercises/05/vslc/src/generator.c +++ b/exercises/05/vslc/src/generator.c @@ -1,5 +1,8 @@ #include +#define ASM(opcode, args...) puts("\t"#opcode"\t"#args) +#define LABEL(label) printf("_%s:\n", (char*)label) + /**Generate table of strings in a rodata section. */ void generate_stringtable ( void ); /**Declare global variables in a bss section */ @@ -20,6 +23,8 @@ static const char *record[6] = { "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9" }; +static uint64_t fetch_symbols(tlhash_t* symbol_table, symbol_t*** symbol_list); + void generate_program ( void ) { @@ -30,12 +35,21 @@ generate_program ( void ) */ // TODO: Implement - // - Generate string table - // - Declare global variables // - Generate code for all functions // - Generate main (function already implemented) by assigning either the // function named main or the first function of the source file if no // main exists. + generate_stringtable(); + generate_global_variables(); + + symbol_t **global_list; + uint64_t no_globals = fetch_symbols(global_names, &global_list); + + for (uint64_t g = 0; g < no_globals; g++) + { + if (global_list[g]->type == SYM_FUNCTION) + generate_function(global_list[g]); + } } void @@ -44,24 +58,48 @@ generate_stringtable ( void ) /* These can be used to emit numbers, strings and a run-time * error msg. from main */ + puts("# DATA SECTION"); puts(".data"); puts(".intout:\t.asciz \"\%ld \""); puts(".strout:\t.asciz \"\%s \""); puts(".errout:\t.asciz \"Wrong number of arguments\""); - // TODO: Implement the rest + for (uint64_t s = 0; s < stringc; s++) + { + printf(".STR%03ld:\t.asciz %s\n", s, string_list[s]); + } + putchar('\n'); } void generate_global_variables ( void ) { - // TODO: Create a .bss section and declare global variables + symbol_t **global_list; + uint64_t no_globals = fetch_symbols(global_names, &global_list); + + puts("# GLOBAL VARIABLES"); + puts(".bss"); + puts(".align 8"); + + for (uint64_t g = 0; g < no_globals; g++) { + if (global_list[g]->type == SYM_GLOBAL_VAR) + printf(".%s:\n", global_list[g]->name); + } + 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; + + LABEL(function->name); + ASM(pushq, %rbp); + ASM(movq, %rsp, %rbp); + + putchar('\n'); } void @@ -122,3 +160,13 @@ generate_main ( symbol_t *first ) puts ( "\tmovq %rax, %rdi" ); puts ( "\tcall exit" ); } + +static uint64_t +fetch_symbols(tlhash_t* symbol_table, symbol_t*** symbol_list) +{ + uint64_t no_symbols = tlhash_size(symbol_table); + *symbol_list = malloc(no_symbols * sizeof(symbol_t)); + tlhash_values(symbol_table, (void **)*symbol_list ); + + return no_symbols; +}