#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include "mcc/tac.h" #include "mcc/tac_print.h" #include "mcc/symbol_table.h" #include "mcc/assembly_gen.h" #include "mcc/assembly.h" struct mcc_assembly_offset *find_var(char *temp, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *a_offset = NULL; for (int i = 0; i < asm_container -> variable_offsets -> size; i++) { struct mcc_assembly_offset *ao = (struct mcc_assembly_offset *) asm_container -> variable_offsets -> arr[i]; // printf("%s %s\n", temp, ao -> temporary); if(ao->temporary !=NULL){ if (strcmp(ao->temporary, temp) == 0) { a_offset = ao; break; } } } return a_offset; } int mcc_tac_is_return_temporary(char *tac_item) { if (strlen(tac_item) < 8) { return 0; } char buffer[9]; memcpy(buffer, tac_item, 8); buffer[8] = '\0'; return strcmp(buffer, "$return_") == 0; } //TODO get vars_count of function to compute stack size // void mcc_get_function_size(struct mcc_tac *tac, int *n_local_vars, // int *n_statements, int *return_found) // { // for(int i = 0; i < tac->tac_entries->size; i++) { // struct mcc_tac_entry *entry = tac->tac_entries->arr[i]; // do{ // switch (entry->tac_op) { // (*n_statements)++; // case MCC_TAC_CALL: // (*n_local_vars)++; // break; // /* LITERALS */ // case MCC_TAC_BOOL_LITERAL: // case MCC_TAC_INT_LITERAL: // case MCC_TAC_FLOAT_LITERAL: // case MCC_TAC_STRING_LITERAL: // case MCC_TAC_VARIABLE_DECLARATION: // (*n_local_vars)++; // break; // /* ARRAYS */ // case MCC_TAC_ARR_DECL: // (*n_local_vars) += entry->arg2; // (*n_local_vars)++; // add array address // break; // default: // break; // } // } // while (entry->tac_op != MCC_TAC_FUNCTION_START); // } // } int mcc_compute_stack(int variable_size) { int stack_size = variable_size * 4; if (stack_size % 16 != 0) { stack_size += (16 - stack_size % 16); } return stack_size; } void asm_gen_function_start(FILE *out, char* function_name) { fprintf(out, ".global %s\n",function_name); fprintf(out, ".type %s, @function\n",function_name); fprintf(out, "%s:\n", function_name); fprintf(out, "\tpushl\t(%%ebp)\n"); fprintf(out, "\tmovl\t%%esp, %%ebp\n"); //TODO add correct stack size fprintf(out, "\tsubl\t$64, %%esp\n"); //set current offset to 0 } void asm_gen_function_end_no_return(FILE *out) { fprintf(out, "\tnop\n"); fprintf(out, "\tpopl\t%%ebp\n"); fprintf(out, "\tret\n"); } void asm_gen_function_end_with_return(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *ao = find_var(te -> result, asm_container); if (ao != NULL) { if(te->tac_op == MCC_TAC_FLOAT){ fprintf(out, "\tflds\t%d(%%ebp)\n", ao -> offset); }else{ fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", ao -> offset); } } else { fprintf(out, "\tnop\n"); } fprintf(out, "\tleave\n"); fprintf(out, "\tret\n"); } void asm_gen_assignment_int(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { mcc_assembly_add_offset_variable(asm_container, te); fprintf(out, "\tmovl\t$%s, %d(%%ebp)\n", te -> arg1, mcc_assembly_get_current_offset(asm_container)); } void asm_gen_assignment_bool(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { mcc_assembly_add_offset_variable(asm_container, te); if(strcmp("true",te->arg1) == 0){ fprintf(out, "\tmovl $1,\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); }else { fprintf(out, "\tmovl $0,\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } } void asm_gen_assignment_string(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { mcc_assembly_add_offset_variable(asm_container, te); te->arg1[strlen(te->arg1) - 2] = '\0'; // fprintf(out, "\t.LC%d:\n", asm_container->labelCounter); // fprintf(out, "\t .string \"%s\"\n", te->arg1 + 2); mcc_assembly_add_constant(asm_container,MCC_ASM_CONST_STRING,te->arg1 + 2); fprintf(out, "\tmovl\t$.LC%d, %d(%%ebp)\n", asm_container->labelCounter++, mcc_assembly_get_current_offset(asm_container)); } void asm_gen_assignment_float(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { mcc_assembly_add_offset_variable(asm_container, te); // fprintf(out, "\t.LC%d:\n", asm_container->labelCounter); // fprintf(out, "\t .long %s\n", te->arg1); fprintf(out,"\tflds .LC%d\n", asm_container->labelCounter++); mcc_assembly_add_constant(asm_container,MCC_ASM_CONST_FLOAT,te->arg1); fprintf(out, "\tfstps %d(%%ebp)\n",mcc_assembly_get_current_offset(asm_container)); } void asm_gen_param(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { fprintf(out, "\tpushl\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_param_array(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { fprintf(out, "\tleal\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); fprintf(out, "\tpushl\t%%eax\n"); } void asm_gen_binary_int_op(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); switch (te->tac_op) { case MCC_TAC_PLUS_INT: fprintf(out, "\taddl\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_MINUS_INT_BIN: fprintf(out, "\tsubl\t%d(%%ebp), %%eax\n",mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_MUL_INT: fprintf(out, "\timull\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_DIV_INT: fprintf(out, "\tcltd\n"); fprintf(out, "\tidivl\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); break; default: fprintf(out,"\tnop\n"); break; } mcc_assembly_add_offset_variable(asm_container, te); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_binary_float_op(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { fprintf(out, "\tflds\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); switch (te->tac_op) { case MCC_TAC_PLUS_FLOAT: fprintf(out, "\tfadds\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_MINUS_FLOAT_BIN: fprintf(out, "\tfsubs\t%d(%%ebp)\n",mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_MUL_FLOAT: fprintf(out, "\tfmuls\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); break; case MCC_TAC_DIV_FLOAT: fprintf(out, "\tfdivs\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); break; default: fprintf(out,"\tnop\n"); break; } mcc_assembly_add_offset_variable(asm_container, te); fprintf(out, "\tfstps\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_relation_int_op(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); struct mcc_assembly_offset *result_offset = find_var(te -> result, asm_container); //TODO offset from te->arg1 lookup if(arg1_offset != NULL){ fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n", arg1_offset->offset); } //TODO offset from te->arg2 lookup if(arg2_offset != NULL){ fprintf(out, "\tcmpl\t%d(%%ebp), %%edx\n", arg2_offset->offset); } switch (te->tac_op) { case MCC_TAC_EQ: case MCC_TAC_EQ_BOOL: fprintf(out, "\tsete\t%%al\n"); break; case MCC_TAC_GT: fprintf(out, "\tsetg\t%%al\n"); break; case MCC_TAC_GTEQ: fprintf(out, "\tsetge\t%%al\n"); break; case MCC_TAC_LT: fprintf(out, "\tsetl\t%%al\n"); break; case MCC_TAC_LTEQ: fprintf(out, "\tsetle\t%%al\n"); break; case MCC_TAC_NEQ: case MCC_TAC_NEQ_BOOL: fprintf(out, "\tsetne\t%%al\n"); break; default: fprintf(out,"\tnop\n"); break; } fprintf(out, "\tmovzbl\t%%al, %%edx\n"); mcc_assembly_add_offset_variable(asm_container, te); if(result_offset != NULL){ fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", result_offset->offset); } } void asm_gen_relation_float_op(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); //TODO offset from te->arg2 lookup if(arg2_offset != NULL){ fprintf(out, "\tflds\t%d(%%ebp)\n", arg2_offset->offset); } //TODO offset from te->arg1 lookup if(arg1_offset != NULL){ fprintf(out, "\tflds\t%d(%%ebp)\n", arg1_offset->offset); } fprintf(out, "\tfcomip\t%%st(1), %%st\n"); fprintf(out, "\tfstp\t%%st(0)\n"); switch (te->tac_op) { case MCC_TAC_EQ_FLOAT: fprintf(out, "\tsete\t%%al\n"); break; case MCC_TAC_GT_FLOAT: fprintf(out, "\tseta\t%%al\n"); break; case MCC_TAC_GTEQ_FLOAT: fprintf(out, "\tsetae\t%%al\n"); break; case MCC_TAC_LT_FLOAT: fprintf(out, "\tsetb\t%%al\n"); break; case MCC_TAC_LTEQ_FLOAT: fprintf(out, "\tsetbe\t%%al\n"); break; case MCC_TAC_NEQ_FLOAT: fprintf(out, "\tsetne\t%%al\n"); break; default: fprintf(out,"\tnop\n"); break; } fprintf(out, "\tmovzbl\t%%al, %%edx\n"); mcc_assembly_add_offset_variable(asm_container, te); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_param_pop(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); // increase parameter offset mcc_assembly_add_offset_variable(asm_container, te); } void asm_gen_param_pop_array(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { // increase parameter offset mcc_assembly_add_offset_variable(asm_container, te); } void asm_gen_load(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n", arg1_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%ecx\n", arg2_offset->offset); fprintf(out, "\tmovl\t0(%%ecx, %%edx, %d), %%eax\n", 4); } void asm_gen_load_float(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n", arg1_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%ecx\n", arg2_offset->offset); fprintf(out, "\tflds\t%d(%%ebp, %%edx, %d)\n", arg1_offset->offset, 8); } void asm_gen_store(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", arg1_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n", arg2_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%ecx\n", mcc_assembly_get_current_offset(asm_container)); fprintf(out, "\tmovl\t%%eax, 0(%%ecx, %%edx, %d)\n", 4); } void asm_gen_store_float(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); fprintf(out, "\tflds\t%d(%%ebp)\n", arg1_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n", arg2_offset->offset); fprintf(out, "\tmovl\t%d(%%ebp), %%ecx\n", mcc_assembly_get_current_offset(asm_container)); fprintf(out, "\tfstps\t0(%%ecx, %%edx, %d)\n", 8); } void asm_gen_not(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *result = find_var(te -> result, asm_container); fprintf(out, "\tcmpl\t$0, %d(%%ebp)\n", arg1_offset->offset); fprintf(out, "\tsete\t%%al\n"); fprintf(out, "\tmovzbl\t%%al, %%eax\n"); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", result->offset); } void asm_gen_unary_minus(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", arg1_offset->offset); fprintf(out, "\tnegl\t%%eax\n"); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_unary_minus_float(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); fprintf(out, "\tflds\t%d(%%ebp)\n", arg1_offset->offset); fprintf(out, "\tfchs\n"); fprintf(out, "\tfstps\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } void asm_gen_and(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); // struct mcc_assembly_offset *result = find_var(te -> result, asm_container); printf(out, "\tmovl\t%d(%%ebp), %%eax\n", arg1_offset->offset); fprintf(out, "\tand\t%d(%%ebp), %%eax\n", arg2_offset->offset); // fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", result->offset); } void asm_gen_or(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { struct mcc_assembly_offset *arg1_offset = find_var(te -> arg1, asm_container); struct mcc_assembly_offset *arg2_offset = find_var(te -> arg2, asm_container); struct mcc_assembly_offset *result = find_var(te -> result, asm_container); printf(out, "\tmovl\t%d(%%ebp), %%eax\n", arg1_offset->offset); fprintf(out, "\tor\t%d(%%ebp), %%eax\n", arg2_offset->offset); fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", result->offset); } void asm_gen_identifier(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { if (!mcc_tac_is_return_temporary(te->arg1)) { fprintf(out, "\tmovl\t%d(%%ebp), %%eax\n", mcc_assembly_get_current_offset(asm_container)); } if (!mcc_tac_is_return_temporary(te->result)) { fprintf(out, "\tmovl\t%%eax, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } } void asm_gen_identifier_float(FILE *out, struct mcc_tac_entry *te, struct mcc_asm_gen_container *asm_container) { if (!mcc_tac_is_return_temporary(te->arg1)) { fprintf(out, "\tflds\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } if (!mcc_tac_is_return_temporary(te->result)) { fprintf(out, "\tfstps\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); } } void mcc_asm_gen(FILE *out, struct mcc_tac *tac, struct mcc_asm_gen_container *asm_container) { for(int i = 0; i < tac->tac_entries->size; i++) { struct mcc_tac_entry *entry = tac->tac_entries->arr[i]; switch (entry -> tac_op) { case MCC_TAC_FUNCTION_START: asm_container -> variable_offsets = mcc_create_dynamic_array(20); asm_container->labelCounter = 0; asm_gen_function_start(out, entry -> arg2); break; case MCC_TAC_FUNCTION_END: asm_gen_function_end_no_return(out); break; case MCC_TAC_CALL: fprintf(out, "\tcall\t%s\n", entry->result); break; case MCC_TAC_LABEL : fprintf(out, ".%s:\n",entry->result); break; case MCC_TAC_JMP : fprintf(out, "\tjmp\t.%s\n", entry->result); break; case MCC_TAC_JMP_FALSE : fprintf(out, "\tcmpl\t$0, %d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container)); fprintf(out, "\tje\t.%s\n", entry->result); break; case MCC_TAC_RETURN: asm_gen_function_end_with_return(out, entry, asm_container); break; case MCC_TAC_INT: case MCC_TAC_INT_ASSIGNMENT: asm_gen_assignment_int(out, entry, asm_container); break; // case MCC_TAC_STRING_ASSIGNMENT: case MCC_TAC_STRING: asm_gen_assignment_string(out, entry, asm_container); break; case MCC_TAC_FLOAT: // case MCC_TAC_FLOAT_ASSIGNMENT: asm_gen_assignment_float(out, entry, asm_container); break; case MCC_TAC_BOOL: // case MCC_TAC_BOOL_ASSIGNMENT: asm_gen_assignment_bool(out, entry, asm_container); break; case MCC_TAC_PLUS_INT: case MCC_TAC_MINUS_INT_BIN: case MCC_TAC_MUL_INT: case MCC_TAC_DIV_INT: asm_gen_binary_int_op(out, entry, asm_container); break; case MCC_TAC_PLUS_FLOAT: case MCC_TAC_MINUS_FLOAT_BIN: case MCC_TAC_MUL_FLOAT: case MCC_TAC_DIV_FLOAT: asm_gen_binary_float_op(out, entry, asm_container); break; case MCC_TAC_EQ: case MCC_TAC_GT: case MCC_TAC_GTEQ: case MCC_TAC_LT: case MCC_TAC_LTEQ: case MCC_TAC_NEQ: case MCC_TAC_EQ_BOOL: case MCC_TAC_NEQ_BOOL: asm_gen_relation_int_op(out, entry, asm_container); break; case MCC_TAC_EQ_FLOAT: case MCC_TAC_GT_FLOAT: case MCC_TAC_GTEQ_FLOAT: case MCC_TAC_LT_FLOAT: case MCC_TAC_LTEQ_FLOAT: case MCC_TAC_NEQ_FLOAT: asm_gen_relation_float_op(out, entry, asm_container); break; case MCC_TAC_NOT_BOOL: fprintf(out, "\t TAC_NOT_BOOL arg1 : %s\n",entry->arg1); break; case MCC_TAC_NOT: asm_gen_not(out, entry, asm_container); break; case MCC_TAC_AND: asm_gen_and(out, entry, asm_container); break; case MCC_TAC_OR: asm_gen_or(out, entry, asm_container); break; case MCC_TAC_MINUS_INT_UN: asm_gen_unary_minus(out, entry, asm_container); break; case MCC_TAC_MINUS_FLOAT_UN: asm_gen_unary_minus_float(out, entry, asm_container); break; // push case MCC_TAC_PARAM_BOOL: case MCC_TAC_PARAM_INT: case MCC_TAC_PARAM_FLOAT: case MCC_TAC_PARAM_STRING: asm_gen_param(out,entry,asm_container); break; case MCC_TAC_PARAM_BOOL_ARR: case MCC_TAC_PARAM_INT_ARR: case MCC_TAC_PARAM_FLOAT_ARR: case MCC_TAC_PARAM_STRING_ARR: asm_gen_param_array(out,entry, asm_container); break; //pop case MCC_TAC_PARAM_POP_BOOL: case MCC_TAC_PARAM_POP_INT: case MCC_TAC_PARAM_POP_FLOAT: case MCC_TAC_PARAM_POP_STRING: asm_gen_param_pop(out, entry, asm_container); break; case MCC_TAC_PARAM_POP_BOOL_ARR: case MCC_TAC_PARAM_POP_INT_ARR: case MCC_TAC_PARAM_POP_FLOAT_ARR: case MCC_TAC_PARAM_POP_STRING_ARR: asm_gen_param_pop_array(out, entry, asm_container); break; case MCC_TAC_ARR_DECL : // set stack offset size of pointer * elements break; case MCC_TAC_VARIABLE_DECLARATION: mcc_assembly_add_offset_variable(asm_container, entry); break; case MCC_TAC_INT_LITERAL: case MCC_TAC_BOOL_LITERAL: case MCC_TAC_STRING_LITERAL: case MCC_TAC_FLOAT_LITERAL: break; case MCC_TAC_VARIABLE_ASSIGNMENT: break; case MCC_TAC_IDENTIFIER_INT: case MCC_TAC_IDENTIFIER_BOOL: case MCC_TAC_IDENTIFIER_STRING: asm_gen_identifier(out, entry , asm_container); break; case MCC_TAC_IDENTIFIER_FLOAT: asm_gen_identifier_float(out, entry , asm_container); break; //load case MCC_TAC_LOAD_BOOL: case MCC_TAC_LOAD_INT: case MCC_TAC_LOAD_STRING: asm_gen_load(out, entry, asm_container); break; case MCC_TAC_LOAD_FLOAT: asm_gen_load_float(out, entry, asm_container); break; //store case MCC_TAC_STORE_BOOL: case MCC_TAC_STORE_INT: case MCC_TAC_STORE_STRING: asm_gen_store(out, entry, asm_container); break; case MCC_TAC_STORE_FLOAT: asm_gen_store_float(out, entry, asm_container); break; case MCC_TAC_UNKNOWN: fprintf(out, "\t TAC_UNKNOWN \n"); break; } } for(int i = 0; i < asm_container->constant_count; i++){ fprintf(out, ".LC%d:\n", i); struct mcc_asm_constant *temp_const = asm_container->constants[i]; if(temp_const->const_type == MCC_ASM_CONST_FLOAT){ fprintf(out, "\t.float\t%s\n", temp_const->const_value); }else{ fprintf(out, "\t .string \"%s\"\n", temp_const->const_value); } } } int mcc_asm_gen_creator(FILE *out, struct mcc_tac *tac, struct mcc_symbol_table *st) { struct mcc_asm_gen_container *ac = malloc(sizeof(*ac)); ac -> variable_offsets = mcc_create_dynamic_array(20); ac->labelCounter = 0; ac->constants_size = 0; ac->constant_count = 0; ac->constants = NULL; mcc_asm_gen(out, tac, ac); return 0; } void mcc_invoke_gcc(char *file_name, char *output) { char *gcc_arguments[6]; gcc_arguments[0] = "gcc"; gcc_arguments[1] = "-m32"; gcc_arguments[2] = "../src/mc_builtins.c"; gcc_arguments[3] = file_name; gcc_arguments[4] = "-o"; gcc_arguments[5] = output; gcc_arguments[6] = NULL; execvp("/usr/bin/gcc", gcc_arguments); }