From 8c7c3602ac1fc2e1b382b442d3161a7151d2cec9 Mon Sep 17 00:00:00 2001 From: Teddy Date: Sun, 27 Apr 2014 04:32:02 +0800 Subject: ... --- ssa.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 171 insertions(+), 30 deletions(-) (limited to 'ssa.c') diff --git a/ssa.c b/ssa.c index 7f7f958..39133f7 100644 --- a/ssa.c +++ b/ssa.c @@ -1,5 +1,6 @@ #include #include +#include #include "ast.h" #include "ssa.h" #define NEW(type) ((type *)malloc(sizeof(type))) @@ -37,6 +38,12 @@ int cblock_isempty(CBlock_t cblk) { return cblk->insts->prev == cblk->insts; } +CVar_t ctmp_create(CType_t type) { + static char buff[MAX_NAMELEN]; + sprintf(buff, "t%d", tcnt++); + return cvar_create(strdup(buff), type, NULL); +} + void cfg_clear() { int i; for (i = 0; i < MAX_BLOCK; i++) @@ -85,17 +92,47 @@ void cinst_print(CInst_t inst) { fprintf(stderr, ") goto _L"); copr_print(&inst->dest); break; + case BNEZ: + fprintf(stderr, "if ("); + copr_print(&inst->src1); + fprintf(stderr, ") goto _L"); + copr_print(&inst->dest); + break; case GOTO: fprintf(stderr, "goto _L"); copr_print(&inst->dest); break; - case ADD: + case ARR: copr_print(&inst->dest); fprintf(stderr, " = "); copr_print(&inst->src1); - fprintf(stderr, " + "); + fprintf(stderr, "["); copr_print(&inst->src2); + fprintf(stderr, "]"); break; + default: + { + const char *op; + switch (inst->op) + { + case MUL: op = "*"; break; + case DIV: op = "/"; break; + case MOD: op = "%"; break; + case ADD: op = "+"; break; + case SUB: op = "-"; break; + case SHL: op = "<<"; break; + case SHR: op = ">>"; break; + case AND: op = "&"; break; + case XOR: op = "^"; break; + case OR: op = "|"; break; + default: ; + } + copr_print(&inst->dest); + fprintf(stderr, " = "); + copr_print(&inst->src1); + fprintf(stderr, " %s ", op); + copr_print(&inst->src2); + } } fprintf(stderr, "\n"); } @@ -141,6 +178,7 @@ COpr ssa_exp(CNode *p, CBlock_t cur) { res.kind = VAR; res.info.var = p->ext.var; break; + default: if (p->ext.is_const) { @@ -149,37 +187,138 @@ COpr ssa_exp(CNode *p, CBlock_t cur) { } else { + int op = p->rec.subtype; + int rec = 1, auto_dest = 1; COpr lhs = ssa_exp(p->chd, cur), rhs; if (p->chd->next) rhs = ssa_exp(p->chd->next, cur); - switch (p->rec.subtype) + + inst->src1 = lhs; + inst->src2 = rhs; + switch (op) + { + case OPT_OR: inst->op = LOR; break; + case OPT_AND: inst->op = LAND; break; + case OPT_SHL: inst->op = SHL; break; + case OPT_SHR: inst->op = SHR; break; + case '|': inst->op = OR; break; + case '^': inst->op = XOR; break; + case OPT_EQ: inst->op = EQ; break; + case OPT_NE: inst->op = NE; break; + case '<': inst->op = LT; break; + case '>': inst->op = GT; break; + case OPT_LE: inst->op = LE; break; + case OPT_GE: inst->op = GE; break; + case '/': inst->op = DIV; break; + case '%': inst->op = MOD; break; + case '&': + if (p->chd->next) + inst->op = AND; + else + { + rec = 0; + res.kind = IMM; + res.info.imm = 0; + /* TODO: be filled in with correct address */ + } + break; + case '*': + if (p->chd->next) + inst->op = MUL; + else + { + inst->op = ARR; + inst->src1 = lhs; + inst->src2.kind = IMM; + inst->src2.info.imm = 0; + } + break; + case '+': + if (p->chd->next) + inst->op = ADD; + else res = lhs; + break; + case '-': + if (p->chd->next) + inst->op = SUB; + else + { + inst->op = NEG; + inst->src1 = lhs; + } + break; + case '~': + inst->op = NOR; + inst->src1 = lhs; + inst->src2.kind = IMM; + inst->src2.info.imm = 0; + break; + case '!': + inst->op = SEQ; + inst->src1 = lhs; + inst->src2.kind = IMM; + inst->src2.info.imm = 0; + break; + case OPT_INC: + auto_dest = 0; + inst->op = ADD; + inst->dest = lhs; + inst->src1 = lhs; + inst->src2.kind = IMM; + inst->src2.info.imm = 1; + break; + case OPT_DEC: + auto_dest = 0; + inst->op = SUB; + inst->dest = lhs; + inst->src1 = lhs; + inst->src2.kind = IMM; + inst->src2.info.imm = 1; + break; + default: + auto_dest = 0; + if (op == '=') + { + if (rhs.kind == VAR) + { + inst->op = MOVE; + inst->dest = lhs; + inst->src1 = rhs; + cblock_append(cur, inst); + } + else + { + inst = cblock_getback(cur); + inst->dest = lhs; + } + res = inst->dest; + break; + } + inst->dest = lhs; + switch (op) + { + case ASS_MUL: inst->op = MUL; break; + case ASS_DIV: inst->op = DIV; break; + case ASS_MOD: inst->op = MOD; break; + case ASS_ADD: inst->op = ADD; break; + case ASS_SUB: inst->op = SUB; break; + case ASS_SHL: inst->op = SHL; break; + case ASS_SHR: inst->op = SHR; break; + case ASS_AND: inst->op = AND; break; + case ASS_XOR: inst->op = XOR; break; + case ASS_OR: inst->op = OR; break; + } + } + if (rec) { - case '=' : - inst->op = MOVE; - inst->dest = lhs; - inst->src1 = rhs; - break; - case ASS_ADD: - inst->op = ADD; - inst->dest = lhs; - inst->src1 = lhs; - inst->src2 = rhs; - break; - /* - case ASS_MUL: - case ASS_DIV: - case ASS_MOD: - case ASS_ADD: - case ASS_SUB: - case ASS_SHL: - case ASS_SHR: - case ASS_AND: - case ASS_XOR: - case ASS_OR: - */ + if (auto_dest) + { + inst->dest.kind = TMP; + inst->dest.info.var = ctmp_create(p->ext.type); + } + cblock_append(cur, inst); + res = inst->dest; } - cblock_append(cur, inst); - res = inst->dest; } } return res; @@ -208,7 +347,7 @@ CBlock_t ssa_while(CNode *p, CBlock_t cur) { cond_blk->ref = 1; cblock_append(cur, j_inst); - if_inst->op = BEQZ; + if_inst->op = BNEZ; if_inst->src1 = cblock_getback(cond_blk)->dest; if_inst->dest.kind = IMM; if_inst->dest.info.imm = loop_blk->id; @@ -221,6 +360,8 @@ CBlock_t ssa_while(CNode *p, CBlock_t cur) { DBLINK(cur, loop_blk); DBLINK(cond_blk, next_blk); + + return next_blk; } CBlock_t ssa_for(CNode *p, CBlock_t cur) { @@ -249,7 +390,7 @@ CBlock_t ssa_for(CNode *p, CBlock_t cur) { cond_blk->ref = 1; cblock_append(cur, j_inst); - if_inst->op = BEQZ; + if_inst->op = BNEZ; if_inst->src1 = cblock_getback(cond_blk)->dest; if_inst->dest.kind = IMM; if_inst->dest.info.imm = loop_blk->id; -- cgit v1.2.3