aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mips.c35
-rw-r--r--ssa.c100
2 files changed, 85 insertions, 50 deletions
diff --git a/mips.c b/mips.c
index 9605377..a9c0efb 100644
--- a/mips.c
+++ b/mips.c
@@ -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)
diff --git a/ssa.c b/ssa.c
index 80f9021..8ae8afe 100644
--- a/ssa.c
+++ b/ssa.c
@@ -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);
}