diff options
author | Teddy <[email protected]> | 2014-04-27 04:32:02 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2014-04-27 04:32:02 +0800 |
commit | 8c7c3602ac1fc2e1b382b442d3161a7151d2cec9 (patch) | |
tree | 6cc5ce659bcd4dd1a58c97445afe1c3e2833fed5 | |
parent | fbafb96963beae48ca095839ffb17b82f9901e5f (diff) |
...
-rw-r--r-- | const.h | 1 | ||||
-rw-r--r-- | semantics.c | 6 | ||||
-rw-r--r-- | ssa.c | 201 | ||||
-rw-r--r-- | ssa.h | 4 |
4 files changed, 178 insertions, 34 deletions
@@ -28,6 +28,7 @@ enum { #define MAX_DEBUG_PRINT_LVL 1024 #define MAX_TABLE_SIZE 1021 #define MAX_ERROR_BUFF 1024 +#define MAX_NAMELEN 1024 #define INT_SIZE 4 #define CHAR_SIZE 1 #define PTR_SIZE 4 diff --git a/semantics.c b/semantics.c index 5a6419c..c29ae04 100644 --- a/semantics.c +++ b/semantics.c @@ -1174,8 +1174,8 @@ ExpType semantics_exp(CNode *p, CScope_t scope) { POINTER_CONV(res.type, p); p->ext.var = cvar_create(p->ext.type->name, res.type, NULL); } - p->ext.is_const = res.type->type == CARR || - res.type->type == CFUNC; + p->ext.is_const = 0; /* res.type->type == CARR || + res.type->type == CFUNC; */ } break; case INT: @@ -1197,7 +1197,7 @@ ExpType semantics_exp(CNode *p, CScope_t scope) { res.type = type; res.lval = 0; p->ext.is_const = 1; - p->ext.const_val = (long int)p->rec.strval; + /* TODO: to be filled with address */ } break; case EXP: @@ -1,5 +1,6 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #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; @@ -20,8 +20,10 @@ struct CInst { enum { MOVE, BEQZ, /* conditional jump */ + BNEZ, GOTO, /* unconditional jump */ - ADD + ARR, /* displacement */ + MUL, DIV, MOD, ADD, SUB, SHL, SHR, AND, XOR, OR, LOR, LAND, NEG, NOR, SEQ, EQ, NE, LT, GT, LE, GE } op; COpr dest, src1, src2; CInst_t next, prev; |