Skip to content
Snippets Groups Projects
assembly_gen.c 23.8 KiB
Newer Older
#include <stdlib.h>
krf41037's avatar
krf41037 committed
#include <stdio.h>
#include <string.h>
Clemens Paumgarten's avatar
Clemens Paumgarten committed
#include <unistd.h>
krf41037's avatar
krf41037 committed

#include "mcc/tac.h"
#include "mcc/tac_print.h"
#include "mcc/symbol_table.h"
#include "mcc/assembly_gen.h"
#include "mcc/assembly.h"
krf41037's avatar
krf41037 committed

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);
FlorianKrull's avatar
FlorianKrull committed
        if(ao->temporary !=NULL){
            if (strcmp(ao->temporary, temp) == 0) {
                a_offset = ao;
                break;
            }
    }

    return a_offset;
}

FlorianKrull's avatar
FlorianKrull committed

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;
}

FlorianKrull's avatar
FlorianKrull committed
//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) {
FlorianKrull's avatar
FlorianKrull committed
	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");
FlorianKrull's avatar
FlorianKrull committed
    //TODO add correct stack size 
    fprintf(out, "\tsubl\t$64, %%esp\n");
FlorianKrull's avatar
FlorianKrull committed
    //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) {
FlorianKrull's avatar
FlorianKrull committed
    struct mcc_assembly_offset *ao = find_var(te -> result, asm_container);

    if (ao != NULL) {
FlorianKrull's avatar
FlorianKrull committed
        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);

FlorianKrull's avatar
FlorianKrull committed
    fprintf(out, "\tmovl\t$%s, %d(%%ebp)\n", te -> arg1, mcc_assembly_get_current_offset(asm_container));
FlorianKrull's avatar
FlorianKrull committed
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);
FlorianKrull's avatar
FlorianKrull committed
    if(strcmp("true",te->arg1) == 0){
        fprintf(out, "\tmovl $1,\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container));
FlorianKrull's avatar
FlorianKrull committed
    }else {
        fprintf(out, "\tmovl $0,\t%d(%%ebp)\n", mcc_assembly_get_current_offset(asm_container));
FlorianKrull's avatar
FlorianKrull committed
    }
   
}

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);
FlorianKrull's avatar
FlorianKrull committed
    fprintf(out, "\tmovl\t$.LC%d, %d(%%ebp)\n", asm_container->labelCounter++, mcc_assembly_get_current_offset(asm_container));
}

FlorianKrull's avatar
FlorianKrull committed
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);
FlorianKrull's avatar
FlorianKrull committed
    fprintf(out,"\tflds .LC%d\n", asm_container->labelCounter++);
    mcc_assembly_add_constant(asm_container,MCC_ASM_CONST_FLOAT,te->arg1);
FlorianKrull's avatar
FlorianKrull committed
    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");
}

FlorianKrull's avatar
FlorianKrull committed
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));
}
FlorianKrull's avatar
FlorianKrull committed

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)
{   
FlorianKrull's avatar
FlorianKrull committed
    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
FlorianKrull's avatar
FlorianKrull committed
    if(arg1_offset != NULL){
        fprintf(out, "\tmovl\t%d(%%ebp), %%edx\n",
		arg1_offset->offset);
    }
    

    //TODO offset from te->arg2 lookup
FlorianKrull's avatar
FlorianKrull committed
    if(arg2_offset != NULL){
        fprintf(out, "\tcmpl\t%d(%%ebp), %%edx\n",
		arg2_offset->offset);
    }
   
FlorianKrull's avatar
FlorianKrull committed
    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:
FlorianKrull's avatar
FlorianKrull committed
    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);
FlorianKrull's avatar
FlorianKrull committed
    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)
{   
FlorianKrull's avatar
FlorianKrull committed
    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
FlorianKrull's avatar
FlorianKrull committed
    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));
}


FlorianKrull's avatar
FlorianKrull committed
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);
}

FlorianKrull's avatar
FlorianKrull committed
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);
FlorianKrull's avatar
FlorianKrull committed
    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);

}

FlorianKrull's avatar
FlorianKrull committed
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));
        }
}

FlorianKrull's avatar
FlorianKrull committed

void mcc_asm_gen(FILE *out, struct mcc_tac *tac, struct mcc_asm_gen_container *asm_container) {
FlorianKrull's avatar
FlorianKrull committed
    
    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);
FlorianKrull's avatar
FlorianKrull committed
                break;
            case MCC_TAC_CALL:
                fprintf(out, "\tcall\t%s\n", entry->result);
FlorianKrull's avatar
FlorianKrull committed
                break;
            case MCC_TAC_LABEL :
                fprintf(out, ".%s:\n",entry->result);
FlorianKrull's avatar
FlorianKrull committed
                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:
FlorianKrull's avatar
FlorianKrull committed
            case MCC_TAC_INT_ASSIGNMENT:
                asm_gen_assignment_int(out, entry, asm_container);
                break;
FlorianKrull's avatar
FlorianKrull committed
            // case MCC_TAC_STRING_ASSIGNMENT:
            case MCC_TAC_STRING:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_assignment_string(out, entry, asm_container);
FlorianKrull's avatar
FlorianKrull committed
                break;
            case MCC_TAC_FLOAT:
FlorianKrull's avatar
FlorianKrull committed
            // case MCC_TAC_FLOAT_ASSIGNMENT:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_assignment_float(out, entry, asm_container);
FlorianKrull's avatar
FlorianKrull committed
                break;
            case MCC_TAC_BOOL:
FlorianKrull's avatar
FlorianKrull committed
            // case MCC_TAC_BOOL_ASSIGNMENT:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_assignment_bool(out, entry, asm_container);
FlorianKrull's avatar
FlorianKrull committed
                break;
FlorianKrull's avatar
FlorianKrull committed
            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;
FlorianKrull's avatar
FlorianKrull committed
            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:
FlorianKrull's avatar
FlorianKrull committed
            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:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_and(out, entry, asm_container);
                break;
            case MCC_TAC_OR:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_or(out, entry, asm_container);
                break;

            case MCC_TAC_MINUS_INT_UN:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_unary_minus(out, entry, asm_container);
                break;
            case MCC_TAC_MINUS_FLOAT_UN:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_unary_minus_float(out, entry, asm_container);
            // 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;
FlorianKrull's avatar
FlorianKrull committed
            
            //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;
FlorianKrull's avatar
FlorianKrull committed
            case MCC_TAC_ARR_DECL :
                // set stack offset size of pointer * elements
                break;
FlorianKrull's avatar
FlorianKrull committed
            
            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:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_identifier(out, entry , asm_container);
                break;

            case MCC_TAC_IDENTIFIER_FLOAT:
FlorianKrull's avatar
FlorianKrull committed
                asm_gen_identifier_float(out, entry , asm_container);
FlorianKrull's avatar
FlorianKrull committed
            //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:
FlorianKrull's avatar
FlorianKrull committed
                fprintf(out, "\t TAC_UNKNOWN \n");

    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);
FlorianKrull's avatar
FlorianKrull committed
    ac->labelCounter = 0;
    ac->constants_size = 0;
	ac->constant_count = 0;
	ac->constants = NULL;

    mcc_asm_gen(out, tac, ac);


    return 0;
}

FlorianKrull's avatar
FlorianKrull committed
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;
FlorianKrull's avatar
FlorianKrull committed
	gcc_arguments[6] = NULL;
FlorianKrull's avatar
FlorianKrull committed

    execvp("/usr/bin/gcc", gcc_arguments);
}