}
if (c->srcs) {
-
+
for (i = 0; i < c->srcs->size; i++) {
src = c->srcs->data[i];
static int _3ac_find_basic_block_start(scf_list_t* h)
{
- int start = 0;
- scf_list_t* l;
+ scf_3ac_operand_t* dst;
+ scf_3ac_code_t* c;
+ scf_3ac_code_t* c2;
+ scf_variable_t* v;
+ scf_list_t* l;
+ scf_list_t* l2;
- for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
+ int start = 0;
- scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list);
+ for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
- scf_list_t* l2 = NULL;
- scf_3ac_code_t* c2 = NULL;
+ c = scf_list_data(l, scf_3ac_code_t, list);
if (!start) {
c->basic_block_start = 1;
start = 1;
}
-#if 0
- if (scf_type_is_assign_dereference(c->op->type)) {
-
- l2 = scf_list_next(&c->list);
- if (l2 != scf_list_sentinel(h)) {
- c2 = scf_list_data(l2, scf_3ac_code_t, list);
- c2->basic_block_start = 1;
- }
-
- c->basic_block_start = 1;
- continue;
- }
- if (SCF_OP_DEREFERENCE == c->op->type) {
- c->basic_block_start = 1;
- continue;
- }
-#endif
+#if 1
+ if (SCF_OP_ASSIGN == c->op->type) {
+ dst = c->dsts->data[0];
+ v = _scf_operand_get(dst->node);
-#if 0
- if (SCF_OP_CALL == c->op->type) {
+ if (v->nb_pointers > 0) {
+ l2 = scf_list_next(&c->list);
- l2 = scf_list_next(&c->list);
- if (l2 != scf_list_sentinel(h)) {
- c2 = scf_list_data(l2, scf_3ac_code_t, list);
- c2->basic_block_start = 1;
+ if (l2 != scf_list_sentinel(h)) {
+ c2 = scf_list_data(l2, scf_3ac_code_t, list);
+ c2->basic_block_start = 1;
+ }
+ continue;
}
-
-// c->basic_block_start = 1;
- continue;
}
#endif
|| SCF_OP_3AC_TEQ == c->op->type) {
for (l2 = scf_list_next(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_next(l2)) {
-
c2 = scf_list_data(l2, scf_3ac_code_t, list);
if (scf_type_is_setcc(c2->op->type))
if (scf_type_is_jmp(c->op->type)) {
- scf_3ac_operand_t* dst0 = c->dsts->data[0];
-
- assert(dst0->code);
+ dst = c->dsts->data[0];
+ assert(dst->code);
// filter 1st expr of logic op, such as '&&', '||'
- if (SCF_OP_3AC_TEQ == dst0->code->op->type) {
+ if (SCF_OP_3AC_TEQ == dst->code->op->type) {
int ret = _3ac_filter_dst_teq(h, c);
if (ret < 0)
}
for (l2 = scf_list_prev(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_prev(l2)) {
-
c2 = scf_list_data(l2, scf_3ac_code_t, list);
if (scf_type_is_setcc(c2->op->type))
}
#if 1
for (l = scf_list_head(h); l != scf_list_sentinel(h); ) {
-
- scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list);
-
- scf_list_t* l2 = NULL;
- scf_3ac_code_t* c2 = NULL;
- scf_3ac_operand_t* dst0 = NULL;
+ c = scf_list_data(l, scf_3ac_code_t, list);
if (SCF_OP_3AC_NOP == c->op->type) {
assert(!c->jmp_dst_flag);
assert(!c->jmp_dst_flag);
for (l2 = scf_list_next(&c->list); l2 != scf_list_sentinel(h); ) {
-
c2 = scf_list_data(l2, scf_3ac_code_t, list);
if (c2->jmp_dst_flag)
c2 = NULL;
}
- l = scf_list_next(l);
- dst0 = c->dsts->data[0];
+ l = scf_list_next(l);
+ dst = c->dsts->data[0];
- if (l == &dst0->code->list) {
+ if (l == &dst->code->list) {
scf_list_del(&c->list);
scf_3ac_code_free(c);
c = NULL;
}
SCF_OP_CMP(eq, ==, SCF_OP_EQ)
-SCF_OP_CMP(gt, >, SCF_OP_GT)
-SCF_OP_CMP(lt, <, SCF_OP_LT)
+SCF_OP_CMP(ne, !=, SCF_OP_NE)
+SCF_OP_CMP(gt, >, SCF_OP_GT)
+SCF_OP_CMP(ge, >=, SCF_OP_GE)
+SCF_OP_CMP(lt, <, SCF_OP_LT)
+SCF_OP_CMP(le, <=, SCF_OP_LE)
scf_dag_operator_t dag_operators[] =
{
{SCF_OP_BIT_OR, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_or},
{SCF_OP_EQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_eq},
+ {SCF_OP_NE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ne},
{SCF_OP_GT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_gt},
+ {SCF_OP_GE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ge},
{SCF_OP_LT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_lt},
+ {SCF_OP_LE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_le},
{SCF_OP_VLA_ALLOC, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_vla_alloc},
{SCF_OP_RETURN, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_return},
&scf_optimizer_pointer_aliases,
&scf_optimizer_loads_saves,
- &scf_optimizer_auto_gc_find, // global optimizer
+ &scf_optimizer_basic_block,
+ &scf_optimizer_const_teq,
+ &scf_optimizer_auto_gc_find, // global optimizer
&scf_optimizer_dominators,
-
&scf_optimizer_auto_gc,
- &scf_optimizer_basic_block,
- &scf_optimizer_const_teq,
-
&scf_optimizer_active_vars,
&scf_optimizer_loads_saves,
if (v->tmp_flag)
return 0;
- scf_loge("pointer '%s' is not inited, tmp_flag: %d, local_flag: %d, file: %s, line: %d\n",
- v->w->text->data, v->tmp_flag, v->local_flag, v->w->file->data, v->w->line);
+ if (SCF_OP_ADDRESS_OF != dn->type) {
+ scf_loge("pointer '%s_%d_%d' is not inited, tmp_flag: %d, local_flag: %d, file: %s, line: %d\n",
+ v->w->text->data, v->w->line, v->w->pos, v->tmp_flag, v->local_flag, v->w->file->data, v->w->line);
+ }
return SCF_POINTER_NOT_INIT;
}
default:
if (dn_alias->var && dn_alias->var->w) {
v = dn_alias->var;
- scf_loge("type: %d, v_%d_%d/%s\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data);
+ scf_loge("type: %d, v_%d_%d/%s/%#lx\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn_alias->var);
} else
scf_loge("type: %d, v_%#lx\n", dn_alias->type, 0xffff & (uintptr_t)dn_alias->var);
return -1;
if (ret < 0)
return ret;
+ scf_3ac_operand_t* src = c->srcs->data[0];
+ scf_dag_node_t* dn = src->dag_node;
+
+ int is_float = scf_variable_float(dn->var);
+
+ switch (setcc_type)
+ {
+ case SCF_X64_SETG:
+ if (is_float)
+ setcc_type = SCF_X64_SETA;
+ break;
+
+ case SCF_X64_SETGE:
+ if (is_float)
+ setcc_type = SCF_X64_SETAE;
+ break;
+
+ case SCF_X64_SETL:
+ if (is_float)
+ setcc_type = SCF_X64_SETB;
+ break;
+
+ case SCF_X64_SETLE:
+ if (is_float)
+ setcc_type = SCF_X64_SETBE;
+ break;
+ default:
+ break;
+ };
+
return x64_inst_set(ctx, c, setcc_type);
}
-
{SCF_X64_SETL, "setl", 3, {0x0f, 0x9c, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
{SCF_X64_SETLE, "setle", 3, {0x0f, 0x9e, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
+ {SCF_X64_SETA, "seta", 3, {0x0f, 0x97, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
+ {SCF_X64_SETAE, "setae", 3, {0x0f, 0x93, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
+
+ {SCF_X64_SETB, "setb", 3, {0x0f, 0x92, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
+ {SCF_X64_SETBE, "setbe", 3, {0x0f, 0x96, 0x0},2, 1,1, SCF_X64_E, 0,0, 0,{0,0}},
+
{SCF_X64_ADDSS, "addss", 4, {0xf3, 0x0f, 0x58},3, 4,4, SCF_X64_E2G, 0,0, 0,{0,0}},
{SCF_X64_ADDSD, "addsd", 8, {0xf2, 0x0f, 0x58},3, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}},
int x64_find_OpCodes(scf_vector_t* results, const int type, const int OpBytes, const int RegBytes, const int EG);
#endif
-
if (x64_inst_data_is_reg(&inst->dst)) {
scf_register_t* r0 = inst->dst.base;
- scf_register_t* r1 = std->src.base;
+ scf_register_t* r1;
if (SCF_X64_CALL == std->OpCode->type) {
return 1;
} else {
+ r1 = std->src.base;
if (x64_inst_data_is_reg(&std->src)) {
if (X64_COLOR_CONFLICT(r0->color, r1->color))
return 1;
}
- if (std->src.base == inst->dst.base
- || std->src.index == inst->dst.base
- || std->dst.index == inst->dst.base
- || std->dst.base == inst->dst.base)
+ if (r1 && X64_COLOR_CONFLICT(r1->color, r0->color))
+ return 1;
+
+ r1 = std->src.index;
+ if (r1 && X64_COLOR_CONFLICT(r1->color, r0->color))
+ return 1;
+
+ r1 = std->dst.index;
+ if (r1 && X64_COLOR_CONFLICT(r1->color, r0->color))
+ return 1;
+
+ r1 = std->dst.base;
+ if (r1 && X64_COLOR_CONFLICT(r1->color, r0->color))
return 1;
}
assert(0 == scf_vector_del(c->instructions, inst));
assert(0 == scf_vector_del(tmp_insts, inst));
-// scf_logd("del: \n");
-// scf_instruction_print(inst);
-
free(inst);
inst = NULL;
}
X64_RCG_SET(setlt)
X64_RCG_SET(setle)
-static int _x64_rcg_eq_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
-}
-
-static int _x64_rcg_ne_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
-}
-
-static int _x64_rcg_gt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
-}
-
-static int _x64_rcg_lt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
-{
- scf_3ac_operand_t* dst = c->dsts->data[0];
-
- int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL);
- if (ret < 0)
- return ret;
-
- return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL);
+#define X64_RCG_CMP(op) \
+static int _x64_rcg_##op##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
+{ \
+ scf_3ac_operand_t* dst = c->dsts->data[0]; \
+ \
+ int ret = _x64_rcg_make2(c, dst->dag_node, NULL, NULL); \
+ if (ret < 0) \
+ return ret; \
+ return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); \
}
+X64_RCG_CMP(eq)
+X64_RCG_CMP(ne)
+X64_RCG_CMP(gt)
+X64_RCG_CMP(ge)
+X64_RCG_CMP(lt)
+X64_RCG_CMP(le)
static int _x64_rcg_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
[SCF_OP_EQ ] = _x64_rcg_eq_handler,
[SCF_OP_NE ] = _x64_rcg_ne_handler,
[SCF_OP_GT ] = _x64_rcg_gt_handler,
+ [SCF_OP_GE ] = _x64_rcg_ge_handler,
[SCF_OP_LT ] = _x64_rcg_lt_handler,
+ [SCF_OP_LE ] = _x64_rcg_le_handler,
[SCF_OP_ASSIGN ] = _x64_rcg_assign_handler,
[SCF_OP_ADD_ASSIGN ] = _x64_rcg_add_assign_handler,
SCF_X64_SETL,
SCF_X64_SETLE,
+ SCF_X64_SETA,
+ SCF_X64_SETAE,
+
+ SCF_X64_SETB,
+ SCF_X64_SETBE,
+
SCF_X64_ADDSS,
SCF_X64_ADDSD,
SCF_X64_MULSS,
SCF_X64_MULSD,
- // 41
SCF_X64_DIVSS,
SCF_X64_DIVSD,
SCF_X64_UCOMISS,
SCF_X64_UCOMISD,
- // 47
SCF_X64_CVTSI2SD,
SCF_X64_CVTSI2SS,
NULL,
};
-static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data);
+static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag);
void scf_dfa_del_hook_by_name(scf_dfa_hook_t** pp, const char* name)
{
scf_logd("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
+ int pre_hook_flag = 0;
+
scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_PRE]), w);
if (hook) {
// if pre hook is set, deliver the word to the proper hook node.
if (hook->node != child)
continue;
+ pre_hook_flag = 1;
scf_logi("\033[32mpre hook: %s\033[0m\n", hook->node->name);
continue;
}
- int ret = _scf_dfa_node_parse_word(dfa, child, words, data);
+ int ret = _scf_dfa_node_parse_word(dfa, child, words, data, pre_hook_flag);
if (SCF_DFA_OK == ret)
return SCF_DFA_OK;
return SCF_DFA_NEXT_SYNTAX;
}
-static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data)
+static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag)
{
int ret = SCF_DFA_NEXT_WORD;
scf_lex_word_t* w = words->data[words->size - 1];
printf("\n");
#endif
- scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_POST]), w);
- if (hook) {
- scf_dfa_node_t* hook_node = hook->node;
+ if (!pre_hook_flag) {
+ scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_POST]), w);
+ if (hook) {
+ scf_dfa_node_t* hook_node = hook->node;
- scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_POST]), hook->next);
- hook = NULL;
+ scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_POST]), hook->next);
+ hook = NULL;
- scf_logi("\033[32m post hook: %s->action()\033[0m\n", hook_node->name);
+ scf_logi("\033[32m post hook: %s->action()\033[0m\n", hook_node->name);
- if (hook_node != node && hook_node->action) {
+ if (hook_node != node && hook_node->action) {
- ret = hook_node->action(dfa, words, data);
+ ret = hook_node->action(dfa, words, data);
- if (SCF_DFA_SWITCH_TO == ret) {
- scf_logi("\033[32m post hook: switch to %s->%s\033[0m\n", node->name, hook_node->name);
+ if (SCF_DFA_SWITCH_TO == ret) {
+ scf_logi("\033[32m post hook: switch to %s->%s\033[0m\n", node->name, hook_node->name);
- node = hook_node;
- ret = SCF_DFA_NEXT_WORD;
+ node = hook_node;
+ ret = SCF_DFA_NEXT_WORD;
+ }
}
}
}
if (SCF_DFA_OK == ret) {
-
scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
while (*pp) {
static int _scf_op_semantic_eq(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
-#define CMPEQ_CHECK_FLOAT() \
- do { \
- assert(2 == nb_nodes); \
- scf_variable_t* v0 = _scf_operand_get(nodes[0]); \
- scf_variable_t* v1 = _scf_operand_get(nodes[1]); \
- \
- if (scf_variable_float(v0) || scf_variable_float(v1)) { \
- scf_loge("float type can't cmp equal\n"); \
- return -EINVAL; \
- } \
- } while (0)
-
- CMPEQ_CHECK_FLOAT();
-
return _scf_op_semantic_cmp(ast, nodes, nb_nodes, data);
}
static int _scf_op_semantic_ne(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
- CMPEQ_CHECK_FLOAT();
-
return _scf_op_semantic_cmp(ast, nodes, nb_nodes, data);
}
static int _scf_op_semantic_ge(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
- CMPEQ_CHECK_FLOAT();
-
return _scf_op_semantic_cmp(ast, nodes, nb_nodes, data);
}
static int _scf_op_semantic_le(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
- CMPEQ_CHECK_FLOAT();
-
return _scf_op_semantic_cmp(ast, nodes, nb_nodes, data);
}