aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib.s3
-rw-r--r--mips.c41
-rw-r--r--semantics.c12
-rw-r--r--semantics.h3
-rw-r--r--ssa.c174
-rw-r--r--ssa.h15
6 files changed, 210 insertions, 38 deletions
diff --git a/lib.s b/lib.s
index 72b138c..3efbd17 100644
--- a/lib.s
+++ b/lib.s
@@ -82,7 +82,8 @@ __L14:
bnez $10, __L13
__L15:
# len_5 = 4 - len_4
- subu $11, $2, 4
+ li $2, 4
+ subu $11, $2, $11
# goto __L17
j __L17
__L16:
diff --git a/mips.c b/mips.c
index 6dce7f5..efb51ba 100644
--- a/mips.c
+++ b/mips.c
@@ -10,6 +10,7 @@ int reg_v1 = 3;
int memcpy_cnt;
static int save_pos[32];
static int used_reg[32];
+static CType_t func;
void mips_prologue(void) {
CVList_t v;
@@ -60,7 +61,7 @@ void mips_prologue(void) {
}
printf("\t.align 2\n");
prev += align_shift(prev);
- for (s = cstrs; s; s = s->next)
+ for (s = cstrs->next; s != cstrs; s = s->next)
{
int len = 1;
char *p = s->str;
@@ -190,7 +191,7 @@ void mips_space_alloc(void) {
CBlock_t p;
COList_t d;
CVar_t v;
- for (d = defs; d; d = d->next)
+ for (d = func_ir->defs; d; d = d->next)
{
COpr_t opr = d->opr;
assert(opr->par == opr);
@@ -207,7 +208,7 @@ void mips_space_alloc(void) {
tmp_size += calc_size(opr->type);
}
}
- for (p = entry; p; p = p->next)
+ for (p = func_ir->entry; p; p = p->next)
{
CInst_t i, ih = p->insts;
for (i = ih->next; i != ih; i = i->next)
@@ -264,7 +265,7 @@ void mips_space_alloc(void) {
}
prev += save_size;
/* adjust offset for spilled temporaries */
- for (d = defs; d; d = d->next)
+ for (d = func_ir->defs; d; d = d->next)
{
COpr_t opr = d->opr;
assert(opr->par == opr);
@@ -273,7 +274,7 @@ void mips_space_alloc(void) {
}
prev += tmp_size;
prev += align_shift(prev);
- for (p = entry; p; p = p->next)
+ for (p = func_ir->entry; p; p = p->next)
{
CInst_t i, ih = p->insts;
for (i = ih->next; i != ih; i = i->next)
@@ -316,7 +317,9 @@ void mips_func_end(void) {
void mips_generate(void) {
CBlock_t p;
- CType_t rt = func->rec.func.ret;
+ CType_t rt;
+ func = func_ir->func;
+ rt = func->rec.func.ret;
/* int arg_cnt = 0; */
mips_space_alloc();
if (strcmp(func->name, "main"))
@@ -324,9 +327,9 @@ void mips_generate(void) {
else
printf("main:\n");
mips_func_begin();
- for (p = entry; p; p = p->next)
+ for (p = func_ir->entry; p; p = p->next)
{
- if (p->ref) printf("_L%d:\n", p->id + gbbase);
+ if (p->ref) printf("_L%d:\n", p->id + func_ir->gbbase);
CInst_t i, ih = p->insts;
const char *bop;
for (i = ih->next; i != ih; i = i->next)
@@ -520,16 +523,24 @@ void mips_generate(void) {
int j;
memset(used_reg, 0, sizeof used_reg);
/* NOTE: bad hack */
- if (i->src1->kind == IMMF && !strcmp(i->src1->info.str, "__print_string"))
+ if (i->src1->kind == IMMF)
{
- printf( "\tlw $a0, 0($sp)\n"
- "\tli $2, 4\n"
- "\tsyscall\n");
- break;
+ char *fname = i->src1->info.str;
+ int flag = 0;
+ if (!strcmp(fname, "__print_int")) flag = 1;
+ else if (!strcmp(fname, "__print_char")) flag = 11;
+ else if (!strcmp(fname, "__print_string")) flag = 4;
+ if (flag)
+ {
+ printf( "\tlw $a0, 0($sp)\n"
+ "\tli $2, %d\n"
+ "\tsyscall\n", flag);
+ break;
+ }
}
if (rt->type == CSTRUCT || rt->type == CUNION)
used_reg[30] = 1; /* save $fp */
- for (p = defs; p; p = p->next)
+ for (p = func_ir->defs; p; p = p->next)
{
COpr_t opr = p->opr;
if (opr->reg != -1 &&
@@ -556,7 +567,7 @@ void mips_generate(void) {
for (j = 0; j < 32; j++)
if (used_reg[j])
printf("\tlw $%d, %d($sp) # load reg\n", j, save_pos[j]);
- for (p = defs; p; p = p->next)
+ for (p = func_ir->defs; p; p = p->next)
{
COpr_t opr = p->opr;
if (opr->reg != -1 &&
diff --git a/semantics.c b/semantics.c
index a431e25..30088ca 100644
--- a/semantics.c
+++ b/semantics.c
@@ -63,7 +63,6 @@ static CType_t builtin_memcpy;
static CType_t builtin_print_int;
static CType_t builtin_print_char;
static CType_t builtin_print_string;
-static int scnt = 0;
CTList_t funcs;
CVList_t gvars;
@@ -1253,9 +1252,10 @@ ExpType semantics_exp(CNode *p, CScope_t scope) {
CSList_t cstr = NEW(CSList);
cstr->str = p->rec.strval;
- cstr->next = cstrs;
- cstr->id = scnt++;
- cstrs = cstr;
+ (cstr->prev = cstrs->prev)->next = cstr;
+ (cstr->next = cstrs)->prev = cstr;
+ cstr->id = cstr->prev->id + 1;
+ /* cstrs = cstr; */
type->rec.ref = basic_type_char;
res.type = type;
@@ -1885,7 +1885,9 @@ void semantics_check(CNode *p) {
cscope_push_type(scope, builtin_print_char, NS_ID);
cscope_push_type(scope, builtin_print_string, NS_ID);
/* const string counter */
- scnt = 0;
+ cstrs = NEW(CSList);
+ cstrs->id = -1;
+ cstrs->prev = cstrs->next = cstrs;
/* check all definitions and declarations */
for (p = p->chd; p; p = p->next)
{
diff --git a/semantics.h b/semantics.h
index b77cf2e..a7712b6 100644
--- a/semantics.h
+++ b/semantics.h
@@ -33,7 +33,7 @@ struct CSList {
char *str;
int id;
int start;
- CSList_t next;
+ CSList_t prev, next;
};
typedef struct CBList *CBList_t;
@@ -203,6 +203,7 @@ void def_exit(void);
int calc_size(CType_t type);
int align_shift(int x);
+extern int scnt;
extern CTList_t funcs;
extern CVList_t gvars;
extern CSList_t cstrs;
diff --git a/ssa.c b/ssa.c
index b0ea04b..f92d4f3 100644
--- a/ssa.c
+++ b/ssa.c
@@ -14,16 +14,18 @@ static COList_t raw_defs; /* defintion of all vars and tmps */
static int bcnt; /* block counter */
static int tcnt; /* temporary counter */
+static int gbbase;
+static CBlock_t entry;
+static COList_t defs; /* all defintions that have actual effects */
+
/* for code generation */
-int gbbase;
-CBlock_t entry;
-CType_t func;
-COList_t defs; /* all defintions that have actual effects */
+CFuncIR_t func_ir;
COpr_t copr_create(void) {
COpr_t opr = NEW(COpr);
opr->type = NULL;
opr->cval = NULL;
+ opr->range = NULL;
opr->same = opr;
opr->dep = 0;
opr->mod = 0;
@@ -322,17 +324,27 @@ void ssa_func_print(CBlock_t p) {
void ssa_func(CType_t);
void ssa_generate(void) {
CTList_t f;
- mips_prologue();
+ CFuncIR_t cf, cf_list = NULL;
for (f = funcs; f; f = f->next)
{
- func = f->type;
- fprintf(stderr, "%s:\n", func->name);
- ssa_func(func);
+ cf = NEW(CFuncIR);
+ ssa_func(cf->func = f->type);
+ cf->gbbase = gbbase;
+ cf->defs = defs;
+ cf->entry = entry;
+ cf->next = cf_list;
+ cf_list = cf;
+ fprintf(stderr, "%s:\n", cf->func->name);
ssa_func_print(entry);
- mips_generate();
gbbase += bcnt;
bcnt = 0;
}
+ mips_prologue();
+ for (cf = cf_list; cf; cf = cf->next)
+ {
+ func_ir = cf;
+ mips_generate();
+ }
}
#define POINTER_CONV(inst) \
@@ -1597,7 +1609,6 @@ void renaming_dfs(CBlock_t blk) {
COList_t n = NEW(COList), n2;
dest->sub = var->cnt++;
dest->def = ih->next; /* the first inst */
- dest->range = NULL;
n->opr = dest;
n->next = var->stack;
var->stack = n;
@@ -1635,7 +1646,6 @@ void renaming_dfs(CBlock_t blk) {
COList_t n = NEW(COList), n2;
dest->sub = var->cnt++;
dest->def = i;
- dest->range = NULL;
n->opr = dest;
n->next = var->stack;
var->stack = n;
@@ -2311,6 +2321,37 @@ void strength_reduction(void) {
} \
} while (0)
+#define PRINT_BARE_STRING \
+ do { \
+ if (bp != buff) \
+ { \
+ CInst_t print = cinst_create(); \
+ print->op = CALL; \
+ print->dest = copr_create(); \
+ print->dest->kind = TMP; \
+ print->dest->info.var = ctmp_create(); \
+ print->dest->type = i->dest->type; \
+ print->src1 = copr_create(); \
+ print->src1->kind = IMMF; \
+ CSList_t cstr = NEW(CSList); \
+ *bp = '\0'; \
+ print->src1->kind = IMMF; \
+ cstr->str = strdup(buff); \
+ (cstr->prev = cstrs->prev)->next = cstr; \
+ (cstr->next = cstrs)->prev = cstr; \
+ cstr->id = cstr->prev->id + 1; \
+ inst = cinst_create(); \
+ inst->op = PUSH; \
+ inst->src1 = copr_create(); \
+ inst->src1->kind = IMMS; \
+ inst->src1->info.cstr = cstr; \
+ cblock_append(ibuff, inst); \
+ print->src1->info.str = "__print_string"; \
+ cblock_append(ibuff, print); \
+ bp = buff; \
+ } \
+ } while (0)
+
int i;
int call_cnt = 0;
for (i = bcnt - 1; i >= 0; i--)
@@ -2365,12 +2406,122 @@ void strength_reduction(void) {
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";
}
+ */
+ if (i->src1->kind == IMMF &&
+ !strcmp(i->src1->info.str, "printf"))
+ {
+ static char buff[1024];
+ char *bp = buff, *sp;
+ CInst_t push = i, inst, phead, np;
+ CBlock_t ibuff;
+ CSList_t fmt;
+ /* move to the first push */
+ while (call_cnt--) push = push->prev;
+ if (push->src1->kind != IMMS) break; /* not a const pattern */
+ ibuff = cblock_create(0);
+ fmt = push->src1->info.cstr;
+ push->prev->next = i->next;
+ i->next->prev = push->prev;
+ phead = push->prev;
+ np = push->next;
+ free(push);
+ push = np;
+ for (sp = fmt->str; *sp != '\0'; sp++)
+ {
+ if (*sp == '%')
+ {
+ CInst_t print = cinst_create();
+ print->op = CALL;
+ print->dest = copr_create();
+ print->dest->kind = TMP;
+ print->dest->info.var = ctmp_create();
+ print->dest->type = i->dest->type;
+ print->src1 = copr_create();
+ print->src1->kind = IMMF;
+
+
+ PRINT_BARE_STRING;
+ switch (*(++sp))
+ {
+ case 'd':
+ {
+ if (push != i)
+ {
+ np = push->next;
+ cblock_append(ibuff, push);
+ push = np;
+ }
+ print->src1->info.str = "__print_int";
+ cblock_append(ibuff, print);
+ }
+ break;
+ case 'c':
+ {
+ if (push != i)
+ {
+ np = push->next;
+ cblock_append(ibuff, push);
+ push = np;
+ }
+ print->src1->info.str = "__print_char";
+ cblock_append(ibuff, print);
+ }
+ break;
+ case 's':
+ {
+
+ if (push != i)
+ {
+ np = push->next;
+ cblock_append(ibuff, push);
+ push = np;
+ }
+ print->src1->info.str = "__print_string";
+ cblock_append(ibuff, print);
+ }
+ break;
+ default:
+ {
+ CSList_t cstr = NEW(CSList);
+ cstr->str = strdup(sp - 1);
+ (cstr->prev = cstrs->prev)->next = cstr;
+ (cstr->next = cstrs)->prev = cstr;
+ cstr->id = cstr->prev->id + 1;
+ inst = cinst_create();
+ inst->op = PUSH;
+ inst->src1 = copr_create();
+ inst->src1->kind = IMMS;
+ inst->src1->info.cstr = cstr;
+ cblock_append(ibuff, inst);
+ for (; push != i; push = np)
+ {
+ np = push->next;
+ cblock_append(ibuff, push);
+ }
+ print->src1->info.str = "printf";
+ cblock_append(ibuff, print);
+ sp = fmt->str + strlen(fmt->str) - 1;
+ }
+ break;
+ }
+ }
+ else *bp++ = *sp;
+ }
+ PRINT_BARE_STRING;
+ fmt->prev->next = fmt->next;
+ fmt->next->prev = fmt->prev;
+ free(fmt);
+ (i->next->prev = ibuff->insts->prev)->next = i->next;
+ (phead->next = ibuff->insts->next)->prev = phead;
+ free(ibuff);
+ }
call_cnt = 0;
break;
default: ;
@@ -2516,7 +2667,6 @@ void subexp_elimination_(CBlock_t b, CExpMap_t cem) {
(t->prev = i)->next = t;
t->dest->def = t;
t->dest->type = i->dest->type;
- t->dest->range = NULL;
cexpmap_insert(cem, t);
}
else
diff --git a/ssa.h b/ssa.h
index 0507a5c..a85e5c7 100644
--- a/ssa.h
+++ b/ssa.h
@@ -158,15 +158,22 @@ CInst_t cexpmap_lookup(CExpMap_t cem, CInst_t exp);
void cexpmap_clear(CExpMap_t cem);
void cexpmap_destroy(CExpMap_t cem);
+typedef struct CFuncIR CFuncIR;
+typedef CFuncIR *CFuncIR_t;
+struct CFuncIR {
+ int gbbase;
+ CBlock_t entry;
+ COList_t defs;
+ CType_t func;
+ CFuncIR_t next;
+};
+
void ssa_generate(void);
COpr_t cinterv_repr(COpr_t opr);
void cinst_print(FILE *stream, CInst_t inst);
int overlap_with_beg(COpr_t i, int beg);
-extern int gbbase;
-extern CBlock_t entry;
-extern COList_t defs;
-extern CType_t func;
+extern CFuncIR_t func_ir;
extern const int avail_regs[];
extern const int MAX_AVAIL_REGS;