aboutsummaryrefslogblamecommitdiff
path: root/mips.c
blob: 0da5d4aae5fc8522fdbb3260a2b2d331183057dc (plain) (tree)
1
2
3
4

                   

                   















                                    
































                                                                                          











                                             
                             




















                                                                              
                             























                                                                          
                                                      


















                                                
                                    






                                                         
                                                 



















                                                
                                          







                                               
                                           












































                                                                  







                                                             





                                             






                                                 





                         



                                         








                                                      

                                   



































                                                                            
                                                     

                                                               





                                                              



















                                                                                         
                                                     
                                                               
                                      
                               




                                                              

















                                                                                         
                                                                            





                                                  
                                                                          














































































                                                                                              


                                                          





































                                                                    
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "ast.h"
#include "ssa.h"
#include "mips.h"

int reg_v0 = 2;
int reg_v1 = 3;

void mips_prologue() {
    CVList_t v;
    CSList_t s;
    printf(".data 0x10000000\n");
    for (v = gvars; v; v = v->next)
    {
        CVar_t var = v->var;
        printf("\t.align 2\n");
        printf("_%s:\n", var->name);
        var->start = -1;
        if (var->initr)
        {
            CNode *initr = var->initr->chd;
            assert(var->initr->rec.subtype == INITR_NORM);
            switch (initr->ext.type->type)
            {
                case CINT:
                    printf("\t.word %d\n", initr->ext.const_val);
                    break;
                case CCHAR:
                    printf("\t.byte %d\n", initr->ext.const_val);
                    break;
                case CPTR:
                    {
                        CType_t ref = initr->ext.type->rec.ref;
                        printf("\t.word ");
                        switch (ref->type)
                        {
                            case CFUNC:
                                printf("%s\n", initr->rec.strval);
                                break;
                            case CCHAR:
                                printf("_str_%d\n", ((CSList_t)initr->ext.const_val)->id);
                                break;
                            default: assert(0);
                        }
                    }
                    break;
                default: assert(0);
            }
        }
        else
            printf("\t.space %d\n", calc_size(var->type));
    }
    for (s = cstrs; s; s = s->next)
    {
        printf("_str_%d:\n", s->id);
        printf("\t.asciiz \"%s\"\n", s->str);
    }
    /* pre-calc done */
    printf(".text\n");
}

void mips_load(int reg, COpr_t opr) {
    CVar_t var = cinterv_repr(opr)->info.var;
    CType_t type = opr->type;
    if (type->type == CSTRUCT ||
        type->type == CUNION ||
        type->type == CARR)
    {
        if (var->global)
            printf("\tla $%d, _%s\n", reg, var->name);
        else
            printf("\taddi $%d, $sp, %d\n", reg, var->start);
    }
    else
    {
        const char *l = type->type == CCHAR ? "lb" : "lw";
        if (var->global)
            printf("\t%s $%d, _%s\n", l, reg, var->name);
        else
            printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name);
    }
}

void mips_store(int reg, COpr_t opr) {
    CVar_t var = cinterv_repr(opr)->info.var;
    CType_t type = opr->type;
    const char *l = type->type == CCHAR ? "sb" : "sw";
    /* TODO: struct */
    if (var->global)
        printf("\t%s $%d, _%s\n", l, reg, var->name);
    else
        printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name);
}

int mips_to_reg(COpr_t opr, int reg0) {
    if (opr->kind == IMM)
    {
        printf("\tli $%d, %d\n", reg0, opr->info.imm);
        return reg0;
    }
    else if (opr->kind == IMMS)
    {
        printf("\tla $%d, _str_%d\n", reg0, opr->info.cstr->id);
        return reg0;
    }
    else if (opr->kind == IMMF<