{
if (scf_type_is_var(node->type)) {
if (node->var->w) {
- printf("v_%d_%d/%s",
- node->var->w->line, node->var->w->pos, node->var->w->text->data);
+ printf("v_%d_%d/%s/%#lx",
+ node->var->w->line, node->var->w->pos, node->var->w->text->data, 0xffff & (uintptr_t)node->var);
} else {
printf("v_%#lx", 0xffff & (uintptr_t)node->var);
}
} else if (scf_type_is_operator(node->type)) {
if (node->result) {
if (node->result->w) {
- printf("v_%d_%d/%s",
- node->result->w->line, node->result->w->pos, node->result->w->text->data);
+ printf("v_%d_%d/%s/%#lx",
+ node->result->w->line, node->result->w->pos, node->result->w->text->data, 0xffff & (uintptr_t)node->result);
} else
printf("v/%#lx", 0xffff & (uintptr_t)node->result);
}
if (bb) {
#define SCF_BB_PRINT(h) \
do { \
- scf_list_t* l; \
- for (l = scf_list_head(&bb->h); l != scf_list_sentinel(&bb->h); \
- l = scf_list_next(l)) { \
- scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); \
+ scf_3ac_code_t* c; \
+ scf_list_t* l; \
+ for (l = scf_list_head(&bb->h); l != scf_list_sentinel(&bb->h); l = scf_list_next(l)) { \
+ c = scf_list_data(l, scf_3ac_code_t, list); \
scf_3ac_code_print(c, sentinel); \
} \
} while (0)
for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
bb = scf_list_data(l, scf_basic_block_t, list);
- printf("\033[33mbasic_block: %p, index: %d, dfo: %d, cmp_flag: %d, call_flag: %d, group: %d, loop: %d, dereference_flag: %d, ret_flag: %d\033[0m\n",
+ printf("\033[34mbasic_block: %p, index: %d, dfo: %d, cmp_flag: %d, call_flag: %d, group: %d, loop: %d, dereference_flag: %d, ret_flag: %d\033[0m\n",
bb, bb->index, bb->dfo, bb->cmp_flag, bb->call_flag, bb->group_flag, bb->loop_flag, bb->dereference_flag, bb->ret_flag);
scf_basic_block_print(bb, sentinel);
printf("next : %p, index: %d\n", bb2, bb2->index);
}
}
-#if 0
- if (bb->dominators_normal) {
- for (i = 0; i < bb->dominators_normal->size; i++)
- printf("dominator: %p\n", bb->dominators_normal->data[i]);
- }
-#endif
+
if (bb->dn_status_initeds) {
printf("inited: \n");
for (i = 0; i < bb->dn_status_initeds->size; i++) {
}
printf("\n");
}
-#if 1
+
if (bb->ds_malloced) {
printf("auto gc: \n");
for (i = 0; i < bb->ds_malloced->size; i++) {
}
printf("\n");
}
-#endif
+
if (bb->entry_dn_actives) {
for (i = 0; i < bb->entry_dn_actives->size; i++) {
dn = bb->entry_dn_actives->data[i];
scf_expr_t* scf_expr_alloc()
{
scf_expr_t* e = calloc(1, sizeof(scf_expr_t));
- if (!e) {
- scf_loge("expr alloc failed");
+ if (!e)
return NULL;
- }
e->nodes = calloc(1, sizeof(scf_node_t*));
if (!e->nodes) {
- scf_loge("expr nodes alloc failed");
-
free(e);
- e = NULL;
return NULL;
}
for (i = 0; i < e->nb_nodes; i++) {
node = scf_node_clone(e->nodes[i]);
-
if (!node)
return -ENOMEM;
}
}
-static int _scf_expr_node_add_node(scf_node_t** pparent, scf_node_t* child)
+static int __expr_node_add_node(scf_node_t** pparent, scf_node_t* child)
{
scf_node_t* parent = *pparent;
if (!parent) {
if (parent->op->nb_operands > parent->nb_nodes)
return scf_node_add_child(parent, child);
- else {
- assert(parent->nb_nodes >= 1);
- return _scf_expr_node_add_node(&(parent->nodes[parent->nb_nodes - 1]), child);
- }
+
+ assert(parent->nb_nodes >= 1);
+ return __expr_node_add_node(&(parent->nodes[parent->nb_nodes - 1]), child);
+
} else if (parent->priority < child->priority) {
assert(child->op);
assert(child->op->nb_operands > child->nb_nodes);
child->parent = parent->parent;
- if (scf_node_add_child(child, parent) < 0) {
- scf_loge("expr nodes alloc failed");
+ if (scf_node_add_child(child, parent) < 0)
return -1;
- }
+
*pparent = child;
return 0;
- } else {
- // parent->priority == child->priority
- assert(parent->op);
- assert(child->op);
+ }
- if (SCF_OP_ASSOCIATIVITY_LEFT == child->op->associativity) {
- if (child->op->nb_operands > 0)
- assert(child->op->nb_operands > child->nb_nodes);
-
- child->parent = parent->parent;
- scf_node_add_child(child, parent); // add parent to child's child node
- *pparent = child; // child is the new parent node
- return 0;
- } else {
- if (parent->op->nb_operands > parent->nb_nodes)
- return scf_node_add_child(parent, child);
- else {
- assert(parent->nb_nodes >= 1);
- return _scf_expr_node_add_node(&(parent->nodes[parent->nb_nodes - 1]), child);
- }
- }
+ // parent->priority == child->priority
+ assert(parent->op);
+ assert(child->op);
+
+ if (SCF_OP_ASSOCIATIVITY_LEFT == child->op->associativity) {
+ if (child->op->nb_operands > 0)
+ assert(child->op->nb_operands > child->nb_nodes);
+
+ child->parent = parent->parent;
+
+ scf_node_add_child(child, parent); // add parent to child's child node
+
+ *pparent = child; // child is the new parent node
+ return 0;
}
- scf_loge("\n");
- return -1;
+ if (parent->op->nb_operands > parent->nb_nodes)
+ return scf_node_add_child(parent, child);
+
+ assert(parent->nb_nodes >= 1);
+ return __expr_node_add_node(&(parent->nodes[parent->nb_nodes - 1]), child);
}
int scf_expr_add_node(scf_expr_t* e, scf_node_t* node)
assert(e);
assert(node);
- if (scf_type_is_var(node->type)) {
+ if (scf_type_is_var(node->type))
node->priority = -1;
- } else if (scf_type_is_operator(node->type)) {
+ else if (scf_type_is_operator(node->type)) {
node->op = scf_find_base_operator_by_type(node->type);
if (!node->op) {
return -1;
}
- if (_scf_expr_node_add_node(&(e->nodes[0]), node) < 0) {
- scf_loge("\n");
+ if (__expr_node_add_node(&(e->nodes[0]), node) < 0)
return -1;
- }
e->nodes[0]->parent = e;
e->nb_nodes = 1;
return 0;
}
+void scf_expr_simplify(scf_expr_t** pe)
+{
+ scf_expr_t** pp = pe;
+ scf_expr_t* e;
+
+ while (SCF_OP_EXPR == (*pp)->type) {
+ e = *pp;
+ pp = &(e->nodes[0]);
+ }
+
+ if (pp != pe) {
+ e = *pp;
+ *pp = NULL;
+
+ e->parent = (*pe)->parent;
+
+ scf_expr_free(*pe);
+ *pe = e;
+ }
+}
#include"scf_node.h"
-typedef scf_node_t scf_expr_t; // expr is a node
+typedef scf_node_t scf_expr_t; // expr is a node
-scf_expr_t* scf_expr_alloc();
-scf_expr_t* scf_expr_clone(scf_expr_t* e);
-void scf_expr_free(scf_expr_t* expr);
-int scf_expr_add_node(scf_expr_t* expr, scf_node_t* node);
+scf_expr_t* scf_expr_alloc();
+scf_expr_t* scf_expr_clone(scf_expr_t* e);
+void scf_expr_free (scf_expr_t* e);
-#endif
+int scf_expr_add_node(scf_expr_t* e, scf_node_t* node);
+void scf_expr_simplify(scf_expr_t** pe);
+#endif
return -EINVAL;
void* p = realloc(parent->nodes, sizeof(scf_node_t*) * (parent->nb_nodes + 1));
- if (!p) {
- scf_loge("realloc failed\n");
+ if (!p)
return -ENOMEM;
- }
parent->nodes = p;
parent->nodes[parent->nb_nodes++] = child;
return -1;
}
- scf_node_t* srcs[2] = {e, e2};
+ if (SCF_OP_CALL == e2->type)
+ cmp = scf_3ac_code_NN(SCF_OP_3AC_TEQ, NULL, 0, &e2, 1);
+ else {
+ scf_node_t* srcs[2] = {e, e2};
+
+ cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
+ }
+ scf_list_add_tail(d->_3ac_list_head, &cmp->list);
- cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
- scf_list_add_tail(d->_3ac_list_head, &cmp->list);
scf_list_add_tail(d->_3ac_list_head, &jnot->list);
scf_vector_add(up_branch_ops->_breaks, jnot);
if (!f->node.define_flag)
continue;
+ printf("\n");
scf_logi("------- %s() ------\n", f->node.w->text->data);
scf_basic_block_print_list(&f->basic_block_list_head);
if (scf_type_is_integer(dst->type)) {
- if (dst->size < src->size) {
- scf_logw("type cast %s -> %s discard bits\n",
- src->w->text->data, dst->w->text->data);
- }
-
+ if (dst->size < src->size)
+ scf_logw("type cast %s -> %s discard bits, file: %s, line: %d\n",
+ src->w->text->data, dst->w->text->data, src->w->file->data, src->w->line);
return 0;
}
}
dst_type = scf_variable_type_name(ast, dst);
src_type = scf_variable_type_name(ast, src);
- scf_loge("type cast '%s -> %s' with different type: from '%s' to '%s'\n",
+ scf_loge("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n",
src->w->text->data, dst->w->text->data,
- src_type->data, dst_type->data);
+ src_type->data, dst_type->data, src->w->file->data, src->w->line);
scf_string_free(dst_type);
scf_string_free(src_type);
&& 0 == v->nb_dimentions;
}
+static inline int scf_variable_string(scf_variable_t* v)
+{
+ return SCF_VAR_CHAR == v->type && 1 == v->nb_pointers + v->nb_dimentions;
+}
+
static inline int scf_variable_float(scf_variable_t* v)
{
return scf_type_is_float(v->type) && 0 == v->nb_pointers && 0 == v->nb_dimentions;
--- /dev/null
+int printf(const char* fmt, ...);
+int strcmp(const char* s1, const char* s2);
+
+int main()
+{
+ const char* s = "123";
+
+ switch (s) {
+ case "456":
+ printf("0\n");
+ case "123":
+ printf("1\n");
+ break;
+ default:
+ printf("default\n");
+ break;
+ };
+
+ return 0;
+}
local += 8;
}
- scf_logw("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n",
+ scf_logd("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n",
local, f->local_vars_size, f->callee_saved_size);
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&local, 4);
for (i = 0; i < local_vars->size; i++) {
scf_variable_t* v = local_vars->data[i];
assert(v->w);
+
scf_logd("v: %p, name: %s_%d_%d, size: %d, bp_offset: %d, arg_flag: %d\n",
v, v->w->text->data, v->w->line, v->w->pos,
scf_variable_size(v), v->bp_offset, v->arg_flag);
.select_inst = scf_x64_select_inst,
};
-
d->current_node = fd->parent_node;
- scf_logi("\033[31m for: %d, fd: %p, s->size: %d\033[0m\n", fd->_for->w->line, fd, s->size);
+ scf_logi("for: %d, fd: %p, s->size: %d\n", fd->_for->w->line, fd, s->size);
free(fd);
fd = NULL;
d->current_node = ifd->parent_node;
- scf_logi("\033[31m if: %d, ifd: %p, s->size: %d\033[0m\n", ifd->_if->w->line, ifd, s->size);
+ scf_logi("if: %d, ifd: %p, s->size: %d\n", ifd->_if->w->line, ifd, s->size);
free(ifd);
ifd = NULL;
scf_stack_t* s = d->module_datas[dfa_module_switch.index];
scf_node_t* _switch = scf_node_alloc(w, SCF_OP_SWITCH, NULL);
- if (!_switch) {
- scf_loge("node alloc failed\n");
- return SCF_DFA_ERROR;
- }
+ if (!_switch)
+ return -ENOMEM;
dfa_switch_data_t* sd = calloc(1, sizeof(dfa_switch_data_t));
- if (!sd) {
- scf_loge("module data alloc failed\n");
- return SCF_DFA_ERROR;
- }
+ if (!sd)
+ return -ENOMEM;
if (d->current_node)
scf_node_add_child(d->current_node, _switch);
d->current_node = sd->parent_node;
- scf_logi("\033[31m switch: %d, sd: %p, s->size: %d\033[0m\n", sd->_switch->w->line, sd, s->size);
+ scf_logi("switch: %d, sd: %p, s->size: %d\n", sd->_switch->w->line, sd, s->size);
free(sd);
sd = NULL;
d->current_node = wd->parent_node;
- scf_logi("\033[31m while: %d, wd: %p, s->size: %d\033[0m\n", wd->_while->w->line, wd, s->size);
+ scf_logi("while: %d, wd: %p, s->size: %d\n", wd->_while->w->line, wd, s->size);
free(wd);
wd = NULL;
return __scf_op_const_call(ast, (scf_function_t*)node, data);
if (0 == node->nb_nodes) {
+
+ if (scf_type_is_var(node->type) && node->var->w)
+ scf_logd("w: %s\n", node->var->w->text->data);
+
assert(scf_type_is_var(node->type)
|| SCF_LABEL == node->type
|| node->split_flag);
-
- if (scf_type_is_var(node->type) && node->var->w) {
- scf_logd("w: %s\n", node->var->w->text->data);
- }
return 0;
}
scf_handler_data_t* d = data;
scf_variable_t* r = NULL;
scf_expr_t* e = nodes[0];
+ scf_expr_t* e2;
+ scf_node_t* b = nodes[1];
+ scf_node_t* child;
assert(SCF_OP_EXPR == e->type);
if (_scf_expr_calculate_internal(ast, e, &r) < 0)
return -1;
- if (_scf_op_const_node(ast, nodes[1], d) < 0)
- return -1;
+ int i;
+ for (i = 0; i < b->nb_nodes; i++) {
+ child = b->nodes[i];
+
+ if (SCF_OP_CASE == child->type) {
+ assert(1 == child->nb_nodes);
+
+ e = child->nodes[0];
+
+ assert(SCF_OP_EXPR == e->type);
+
+ if (_scf_expr_calculate_internal(ast, e, &r) < 0)
+ return -1;
+
+ } else {
+ if (_scf_op_const_node(ast, child, d) < 0)
+ return -1;
+ }
+ }
return 0;
}
static int _scf_op_const_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
- assert(1 == nb_nodes);
-
- scf_handler_data_t* d = data;
- scf_variable_t* r = NULL;
- scf_expr_t* e = nodes[0];
-
- assert(SCF_OP_EXPR == e->type);
-
- if (_scf_expr_calculate_internal(ast, e, &r) < 0)
- return -1;
return 0;
}
{
assert(1 == nb_nodes);
- scf_handler_data_t* d = data;
-
- scf_node_t* n = nodes[0];
scf_node_t* parent = nodes[0]->parent;
+ scf_node_t* node;
- while (SCF_OP_EXPR == n->type)
- n = n->nodes[0];
+ scf_expr_simplify(&nodes[0]);
- n->parent->nodes[0] = NULL;
- scf_node_free(nodes[0]);
- nodes[0] = n;
- n->parent = parent;
+ node = nodes[0];
- int ret = _scf_expr_calculate_internal(ast, n, d);
+ int ret = _scf_expr_calculate_internal(ast, node, data);
if (ret < 0) {
scf_loge("\n");
return -1;
if (parent->result)
scf_variable_free(parent->result);
- scf_variable_t* v = _scf_operand_get(n);
-
+ scf_variable_t* v = _scf_operand_get(node);
if (v)
parent->result = scf_variable_ref(v);
else
ret = _scf_op_semantic_node(ast, node, d);
if (ret < 0) {
- scf_loge("\n");
ast->current_block = up;
return -1;
}
return 0;
}
-static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+static int __switch_for_string(scf_ast_t* ast, scf_node_t* parent, scf_node_t* child, scf_expr_t* e, scf_expr_t* e1, scf_handler_data_t* d)
{
- assert(2 == nb_nodes);
-
- scf_handler_data_t* d = data;
- scf_variable_t* r = NULL;
- scf_expr_t* e = nodes[0];
+ scf_function_t* f = NULL;
+ scf_expr_t* e2;
+ scf_expr_t* e3;
+ scf_expr_t* e4;
- assert(SCF_OP_EXPR == e->type);
+ int ret = scf_ast_find_function(&f, ast, "strcmp");
+ if (ret < 0)
+ return ret;
- if (_scf_expr_calculate(ast, e, &r) < 0) {
- scf_loge("\n");
+ if (!f) {
+ scf_loge("can't find function 'strcmp()' for compare const string, file: %s, line: %d\n",
+ parent->w->file->data, parent->w->line);
return -1;
}
- if (!r || !scf_variable_integer(r)) {
- scf_loge("\n");
- return -1;
+ e2 = scf_expr_clone(e);
+ if (!e1)
+ return -ENOMEM;
+
+ e3 = scf_expr_alloc();
+ if (!e3) {
+ scf_expr_free(e2);
+ return -ENOMEM;
}
- scf_variable_free(r);
- r = NULL;
- int ret = _scf_op_semantic_node(ast, nodes[1], d);
+ ret = scf_node_add_child(e3, e2);
if (ret < 0) {
- scf_loge("\n");
- return -1;
+ scf_expr_free(e2);
+ scf_expr_free(e3);
+ return ret;
}
+ e2 = NULL;
- return 0;
+ ret = scf_node_add_child(e3, e1);
+ if (ret < 0) {
+ scf_expr_free(e3);
+ return ret;
+ }
+ child->nodes[0] = NULL;
+
+ e4 = scf_expr_alloc();
+ if (!e4) {
+ scf_expr_free(e3);
+ return -ENOMEM;
+ }
+
+ ret = scf_node_add_child(e4, e3);
+ if (ret < 0) {
+ scf_expr_free(e3);
+ scf_expr_free(e4);
+ return ret;
+ }
+
+ child->nodes[0] = e4;
+ e4->parent = child;
+
+ d->pret = &e3->result;
+
+ return _semantic_add_call(ast, e3->nodes, e3->nb_nodes, d, f);
}
-static int _scf_op_semantic_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
- assert(1 == nb_nodes);
+ assert(2 == nb_nodes);
- scf_handler_data_t* d = data;
- scf_variable_t* r = NULL;
- scf_expr_t* e = nodes[0];
+ scf_handler_data_t* d = data;
+ scf_variable_t** pret = d->pret;
+ scf_variable_t* v0 = NULL;
+ scf_variable_t* v1 = NULL;
+ scf_block_t* tmp = ast->current_block;
+ scf_expr_t* e = nodes[0];
+ scf_node_t* b = nodes[1];
+ scf_node_t* parent = nodes[0]->parent;
+ scf_node_t* child;
+ scf_expr_t* e1;
- assert(SCF_OP_EXPR == e->type);
+ assert(SCF_OP_EXPR == e->type);
+ assert(SCF_OP_BLOCK == b->type);
- if (_scf_expr_calculate(ast, e, &r) < 0) {
- scf_loge("\n");
+ if (_scf_expr_calculate(ast, e, &v0) < 0)
return -1;
- }
- if (!r || !scf_variable_integer(r)) {
- scf_loge("\n");
+ if (!scf_variable_integer(v0) && !scf_variable_string(v0)) {
+ scf_loge("result of switch expr should be an integer or string, file: %s, line: %d\n", parent->w->file->data, parent->w->line);
+ scf_variable_free(v0);
return -1;
}
- scf_variable_free(r);
+ ast->current_block = (scf_block_t*)b;
+
+ int ret = -1;
+ int i;
+
+ for (i = 0; i < b->nb_nodes; i++) {
+ child = b->nodes[i];
+
+ if (SCF_OP_CASE == child->type) {
+ assert(1 == child->nb_nodes);
+
+ e1 = child->nodes[0];
+
+ assert(SCF_OP_EXPR == e1->type);
+
+ ret = _scf_expr_calculate(ast, e1, &v1);
+ if (ret < 0) {
+ scf_variable_free(v0);
+ return ret;
+ }
+
+ if (!scf_variable_const_integer(v1) && !scf_variable_const_string(v1)) {
+ ret = -1;
+ scf_loge("result of case expr should be const integer or const string, file: %s, line: %d\n", child->w->file->data, child->w->line);
+ goto error;
+ }
+
+ if (!scf_variable_type_like(v0, v1)) {
+
+ if (scf_type_cast_check(ast, v0, v1) < 0) {
+ ret = -1;
+ scf_loge("type of switch's expr is NOT same to the case's, file: %s, line: %d\n", child->w->file->data, child->w->line);
+ goto error;
+ }
+
+ ret = _semantic_add_type_cast(ast, &(e1->nodes[0]), v0, e1->nodes[0]);
+ if (ret < 0)
+ goto error;
+ }
+
+ if (scf_variable_const_string(v1)) {
+
+ ret = __switch_for_string(ast, parent, child, e, e1, d);
+ if (ret < 0)
+ goto error;
+ }
+
+ scf_variable_free(v1);
+ v1 = NULL;
+
+ } else {
+ ret = _scf_op_semantic_node(ast, child, d);
+ if (ret < 0) {
+ scf_variable_free(v0);
+ return -1;
+ }
+ }
+ }
+
+ ast->current_block = tmp;
+
+ scf_variable_free(v0);
+
+ d->pret = pret;
return 0;
+
+error:
+ scf_variable_free(v0);
+ scf_variable_free(v1);
+ d->pret = pret;
+ return ret;
+}
+
+static int _scf_op_semantic_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ scf_loge("\n");
+ return -1;
}
static int _scf_op_semantic_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
// change the current block
ast->current_block = (scf_block_t*)f;
- if (_scf_op_semantic_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) {
- scf_loge("\n");
+ if (_scf_op_semantic_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0)
return -1;
- }
ast->current_block = tmp;
return 0;
int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions)
{
scf_function_t* f;
-
int i;
+
for (i = 0; i < functions->size; i++) {
f = functions->data[i];
- scf_logi("i: %d, fname: %s, f->argv->size: %d, f->node.define_flag: %d, inline_flag: %d\n",
+ printf("%d, %s(), argv->size: %d, define_flag: %d, inline_flag: %d\n",
i, f->node.w->text->data, f->argv->size, f->node.define_flag, f->inline_flag);
if (!f->node.define_flag)