diff options
-rw-r--r-- | mips.c | 35 | ||||
-rw-r--r-- | ssa.c | 100 |
2 files changed, 85 insertions, 50 deletions
@@ -14,13 +14,16 @@ static int used_reg[32]; void mips_prologue(void) { CVList_t v; CSList_t s; + int prev = 0; 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; + prev += align_shift(prev); + var->start = prev; + prev += calc_size(var->type); if (var->initr) { CNode *initr = var->initr->chd; @@ -65,6 +68,24 @@ void mips_prologue(void) { printf(".text\n"); } +#define IN_IMM(x) (-0x8000 <= (x) && (x) < 0x8000) + +void mips_global_addr(int reg, CVar_t var) { + int offset = var->start - 0x8000; + if (IN_IMM(offset)) + printf("\taddiu $%d, $gp, %d\n", reg, offset); + else + printf("\tla $%d, _%s\n", reg, var->name); +} + +void mips_global(const char *l, int reg, CVar_t var) { + int offset = var->start - 0x8000; + if (IN_IMM(offset)) + printf("\t%s $%d, %d($gp)\n", l, reg, offset); + else + printf("\t%s $%d, _%s\n", l, reg, var->name); +} + void mips_load(int reg, COpr_t opr) { CVar_t var = opr->spill->info.var; CType_t type = opr->type; @@ -74,7 +95,7 @@ void mips_load(int reg, COpr_t opr) { type->type == CARR)) { if (var->loc > 0) - printf("\tla $%d, _%s\n", reg, var->name); + mips_global_addr(reg, var); else printf("\taddiu $%d, $sp, %d\n", reg, var->start); } @@ -82,7 +103,7 @@ void mips_load(int reg, COpr_t opr) { { const char *l = type->type == CCHAR ? "lb" : "lw"; if (var->loc > 0) - printf("\t%s $%d, _%s\n", l, reg, var->name); + mips_global(l, reg, var); else printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name); } @@ -93,7 +114,7 @@ void mips_store(int reg, COpr_t opr) { CType_t type = opr->type; const char *l = type->type == CCHAR ? "sb" : "sw"; if (var->loc > 0) - printf("\t%s $%d, _%s\n", l, reg, var->name); + mips_global(l, reg, var); else if (opr->reg == -1) printf("\t%s $%d, %d($sp)\t#%s\n", l, reg, var->start, var->name); } @@ -270,8 +291,6 @@ void mips_func_end(void) { printf("\tjr $31\n"); } -#define IN_IMM(x) (-0x8000 <= (x) && (x) < 0x8000) - void mips_generate(void) { CBlock_t p; CType_t rt = func->rec.func.ret; @@ -356,7 +375,7 @@ void mips_generate(void) { else { rt = mips_to_reg(i->src2, reg_v1); - printf("\t%s$%d, $%d, _L%d\n", b, rs, rt, i->dest->info.imm); + printf("\t%s $%d, $%d, _L%d\n", b, rs, rt, i->dest->info.imm); } } break; @@ -581,7 +600,7 @@ void mips_generate(void) { { CVar_t var = i->src1->spill->info.var; if (var->loc > 0) - printf("\tla $%d, _%s\n", rd, var->name); + mips_global_addr(rd, var); else printf("\taddiu $%d, $sp, %d\n", rd, var->start); if (i->dest->reg == -1 || i->dest->kind == VAR) @@ -1972,7 +1972,10 @@ int copr_comp(const void *a, const void *b) { return (*(COpr_t *)a)->range->l - (*(COpr_t *)b)->range->l; } -const int avail_regs[] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25}; +const int avail_regs[] = {8, 9, 10, 11, + 12, 13, /*14, 15, */ + 16, 17, 24, 25}; + const int MAX_AVAIL_REGS = sizeof(avail_regs) / sizeof(avail_regs[0]); void register_alloc(void) { @@ -2274,6 +2277,7 @@ void strength_reduction(void) { } while (0) int i; + int call_cnt = 0; for (i = bcnt - 1; i >= 0; i--) { CBlock_t b = blks[vis[i]]; @@ -2304,7 +2308,18 @@ void strength_reduction(void) { } } break; - + case PUSH: + call_cnt++; + break; + case CALL: + if (i->src1->kind == IMMF && + call_cnt == 1 && + !strcmp(i->src1->info.str, "printf")) + { + i->src1->info.str = "__print_string"; + } + call_cnt = 0; + break; default: ; } } @@ -2401,52 +2416,53 @@ void copr_shortcut(COpr_t *opr) { *opr = t->same; } -void subexp_elimination(void) { - int i; - CExpMap_t cem = cexpmap_create(); - for (i = bcnt - 1; i >= 0; i--) +void subexp_elimination_(CBlock_t b, CExpMap_t cem) { + CInst_t i, ih = b->insts; + CEdge *e; + for (i = ih->next; i != ih; i = i->next) { - CBlock_t b = blks[vis[i]]; - CInst_t i, ih = b->insts; - for (i = ih->next; i != ih; i = i->next) + CInst_t t; + if (i->op == MOVE) { - CInst_t t; - if (i->op == MOVE) - { - i->dest->same = i->src1->same; - continue; - } - else if (i->op == CALL) - { - /* cexpmap_clear(cem); */ - continue; - } - copr_shortcut(&i->src1); - copr_shortcut(&i->src2); - t = cexpmap_lookup(cem, i); - if (t) - { - i->op = MOVE; - i->src1 = t->dest; - i->src2 = NULL; - i->dest->same = i->src1; - } - else + i->dest->same = i->src1->same; + continue; + } + else if (i->op == CALL) + { + /* cexpmap_clear(cem); */ + continue; + } + copr_shortcut(&i->src1); + copr_shortcut(&i->src2); + t = cexpmap_lookup(cem, i); + if (t) + { + i->op = MOVE; + i->src1 = t->dest; + i->src2 = NULL; + i->dest->same = i->src1; + } + else + { + switch (i->op) { - switch (i->op) - { - case MUL: case DIV: case MOD: case ADD: case SUB: - case SHL: case SHR: case AND: case XOR: case OR: case NOR: - case EQ: case NE: case LT: case GT: case LE: case GE: - case NEG: - cexpmap_insert(cem, i); - break; - default: ; - } + case MUL: case DIV: case MOD: case ADD: case SUB: + case SHL: case SHR: case AND: case XOR: case OR: case NOR: + case EQ: case NE: case LT: case GT: case LE: case GE: + case NEG: + cexpmap_insert(cem, i); + break; + default: ; } } - cexpmap_clear(cem); } + for (e = dtree.head[b->id]; e; e = e->next) + subexp_elimination_(e->to, cem); +} + +void subexp_elimination(void) { + CExpMap_t cem = cexpmap_create(); + subexp_elimination_(entry, cem); cexpmap_destroy(cem); } |