scf_node_t* parent = nodes[0]->parent;
scf_node_t* child = nodes[0];
+ _scf_operand_get(parent)->tmp_flag = 1;
+
if (scf_type_is_var(child->type))
return _scf_3ac_code_2(d->_3ac_list_head, SCF_OP_ADDRESS_OF, parent, child);
--- /dev/null
+int printf(const char* fmt, ...);
+
+int div0(int64_t a, int64_t b)
+{
+ a = b / a;
+ return a;
+}
+
+int div1(int a, int b)
+{
+ a /= b;
+ return a;
+}
+
+int div2(int a, int b)
+{
+ int c = a / b;
+ return c;
+}
+
+int main(int argc, char* argv[])
+{
+ printf("b / a: %d\n", div1(1, 2));
+ return 0;
+}
int x64_assign_pointer (scf_native_t* ctx, scf_3ac_code_t* c);
int x64_assign_array_index(scf_native_t* ctx, scf_3ac_code_t* c);
-int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f);
-int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f, int mod_flag);
+int x64_inst_int_mul(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f);
+int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* c, scf_function_t* f, int mod_flag);
-int x64_inst_pointer(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag);
+int x64_inst_pointer (scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag);
int x64_inst_dereference(scf_native_t* ctx, scf_3ac_code_t* c);
int x64_inst_float_cast(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f);
scf_x64_OpCode_t* OpCode;
scf_instruction_t* inst;
- int ret = x64_select_reg(&rd, dst->dag_node, c, f, 0);
+ int ret = x64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
- ret = x64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f);
+ ret = x64_select_reg(&rd, dst->dag_node, c, f, 0);
if (ret < 0) {
scf_loge("\n");
return ret;
return _x64_inst_float_op3(SCF_X64_DIV, dst->dag_node, src0->dag_node, src1->dag_node, c, f);
}
- int ret = x64_inst_op2(SCF_X64_MOV, dst->dag_node, src0->dag_node, c, f);
- if (ret < 0)
- return ret;
-
- return x64_inst_int_div(dst->dag_node, src1->dag_node, c, f, mod_flag);
+ return x64_inst_int_div(dst->dag_node, src0->dag_node, src1->dag_node, c, f, mod_flag);
}
static int _x64_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c)
return _x64_inst_float_op3(SCF_X64_MUL, dst->dag_node, src0->dag_node, src1->dag_node, c, f);
}
- int ret = x64_inst_op2(SCF_X64_MOV, dst->dag_node, src0->dag_node, c, f);
- if (ret < 0)
- return ret;
- return x64_inst_int_mul(dst->dag_node, src1->dag_node, c, f);
+ if (dst->dag_node->var != src1->dag_node->var) {
+ int ret = x64_inst_op2(SCF_X64_MOV, dst->dag_node, src0->dag_node, c, f);
+ if (ret < 0)
+ return ret;
+
+ return x64_inst_int_mul(dst->dag_node, src1->dag_node, c, f);
+ }
+
+ return x64_inst_int_mul(dst->dag_node, src0->dag_node, c, f);
}
static int _x64_inst_op3(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type)
return _x64_inst_float_op3(OpCode_type, dst->dag_node, src0->dag_node, src1->dag_node, c, f);
}
- int ret = x64_inst_op2(SCF_X64_MOV, dst->dag_node, src0->dag_node, c, f);
- if (ret < 0) {
- scf_loge("\n");
- return ret;
+ scf_x64_OpCode_t* OpCode;
+ scf_instruction_t* inst = NULL;
+ scf_register_t* rd = NULL;
+ scf_variable_t* vd = dst->dag_node->var;
+ scf_variable_t* vs1 = src1->dag_node->var;
+ int ret;
+
+ if (vd != vs1) {
+ ret = x64_inst_op2(SCF_X64_MOV, dst->dag_node, src0->dag_node, c, f);
+ if (ret < 0)
+ return ret;
+
+ return x64_inst_op2(OpCode_type, dst->dag_node, src1->dag_node, c, f);
}
- ret = x64_inst_op2(OpCode_type, dst->dag_node, src1->dag_node, c, f);
- if (ret < 0) {
- scf_loge("\n");
+
+ ret = x64_inst_op2(OpCode_type, dst->dag_node, src0->dag_node, c, f);
+ if (ret < 0)
return ret;
+
+ if (SCF_X64_SUB == OpCode_type)
+ {
+ OpCode = x64_find_OpCode(SCF_X64_NEG, vd->size, vd->size, SCF_X64_E);
+ if (!OpCode)
+ return -EINVAL;
+
+ if (dst->dag_node->color > 0) {
+ X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 1);
+ inst = x64_make_inst_E(OpCode, rd);
+ X64_INST_ADD_CHECK(c, inst, NULL);
+ } else {
+ scf_rela_t* rela = NULL;
+
+ inst = x64_make_inst_M(&rela, OpCode, vd, NULL, c, f);
+ X64_INST_ADD_CHECK(c, inst, rela);
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, vd, NULL);
+ }
}
+
return ret;
}
return _x64_inst_float_op2(SCF_X64_DIV, dst->dag_node, src->dag_node, c, f);
}
- return x64_inst_int_div(dst->dag_node, src->dag_node, c, f, mod_flag);
+ return x64_inst_int_div(dst->dag_node, dst->dag_node, src->dag_node, c, f, mod_flag);
}
static int _x64_inst_div_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
if (src->color > 0) {
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
- if (SCF_X64_MOV == OpCode && src->color == dst->color)
+ if (SCF_X64_MOV == OpCode_type && src->color == dst->color)
return 0;
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_G2E);
#include"scf_x64.h"
-int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f, int mod_flag)
+int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src0, scf_dag_node_t* src1, scf_3ac_code_t* c, scf_function_t* f, int mod_flag)
{
assert(0 != dst->color);
- int size = x64_variable_size(src->var);
+ int size = x64_variable_size(src1->var);
int ret;
scf_instruction_t* inst = NULL;
- scf_register_t* rs = NULL;
+ scf_register_t* rs0 = NULL;
+ scf_register_t* rs1 = NULL;
scf_register_t* rd = NULL;
scf_register_t* rl = x64_find_register_type_id_bytes(0, SCF_X64_REG_AX, size);
scf_register_t* rh;
else
rh = x64_find_register_type_id_bytes(0, SCF_X64_REG_DX, size);
- int src_literal = src->var->const_literal_flag;
- intptr_t src_color = src->color;
+ int src_literal = src1->var->const_literal_flag;
+ intptr_t src_color = src1->color;
- if (0 == src->color) {
- src->var->const_literal_flag = 0;
- src->var->tmp_flag = 1;
- src->color = -1;
+ if (0 == src1->color) {
+ src1->var->const_literal_flag = 0;
+ src1->var->tmp_flag = 1;
+ src1->color = -1;
- X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
+ X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1);
}
- if (dst->color > 0) {
- X64_SELECT_REG_CHECK(&rd, dst, c, f, 1);
+ if (src0->color > 0) {
+ X64_SELECT_REG_CHECK(&rs0, src0, c, f, 1);
- if (rd->id != rl->id) {
+ if (rs0->id != rl->id) {
ret = x64_overflow_reg(rl, c, f);
if (ret < 0)
return ret;
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_G2E);
- inst = x64_make_inst_G2E(mov, rl, rd);
+ inst = x64_make_inst_G2E(mov, rl, rs0);
X64_INST_ADD_CHECK(c, inst, NULL);
}
- if (rd->id != rh->id) {
+ if (rs0->id != rh->id) {
ret = x64_overflow_reg(rh, c, f);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
- scf_rela_t* rela = NULL;
+ if (0 == src0->color) {
- mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, mov, rl, NULL, dst->var, c, f);
- X64_INST_ADD_CHECK(c, inst, rela);
- X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
+ ret = x64_load_const(rl, src0, c, f);
+ if (ret < 0)
+ return ret;
+ } else {
+ scf_rela_t* rela = NULL;
+
+ mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
+ inst = x64_make_inst_M2G(&rela, mov, rl, NULL, src0->var, c, f);
+ X64_INST_ADD_CHECK(c, inst, rela);
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, src0->var, NULL);
+ }
}
- if (scf_variable_signed(src->var)) {
- div = x64_find_OpCode(SCF_X64_IDIV, size, size, SCF_X64_E);
- cdq = x64_find_OpCode_by_type(SCF_X64_CDQ);
- inst = x64_make_inst(cdq, size << 1);
+ if (scf_variable_signed(src1->var)) {
+ div = x64_find_OpCode(SCF_X64_IDIV, size, size, SCF_X64_E);
+ cdq = x64_find_OpCode(SCF_X64_CDQ, size, size << 1, SCF_X64_G);
+ inst = x64_make_inst(cdq, size);
X64_INST_ADD_CHECK(c, inst, NULL);
} else {
div = x64_find_OpCode(SCF_X64_DIV, size, size, SCF_X64_E);
X64_INST_ADD_CHECK(c, inst, NULL);
}
- if (src->color > 0) {
- X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
- inst = x64_make_inst_E(div, rs);
+ if (src1->color > 0) {
+ X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1);
+ inst = x64_make_inst_E(div, rs1);
X64_INST_ADD_CHECK(c, inst, NULL);
} else {
scf_rela_t* rela = NULL;
- inst = x64_make_inst_M(&rela, div, src->var, NULL, c, f);
+ inst = x64_make_inst_M(&rela, div, src1->var, NULL, c, f);
X64_INST_ADD_CHECK(c, inst, rela);
- X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, src1->var, NULL);
}
scf_register_t* result;
else
result = rl;
- if (rd) {
+ if (dst->color > 0) {
+ X64_SELECT_REG_CHECK(&rd, dst, c, f, 0);
+
if (rd->id != result->id) {
mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_G2E);
inst = x64_make_inst_G2E(mov, rd, result);
}
if (0 == src_color) {
- src->var->tmp_flag = 0;
- src->var->const_literal_flag = src_literal;
+ src1->var->tmp_flag = 0;
+ src1->var->const_literal_flag = src_literal;
- if (src->color > 0) {
- assert(0 == scf_vector_del(rs->dag_nodes, src));
- src->loaded = 0;
+ if (src1->color > 0) {
+ assert(0 == scf_vector_del(rs1->dag_nodes, src1));
+ src1->loaded = 0;
}
- src->color = 0;
+ src1->color = 0;
}
return 0;
{SCF_X64_IDIV, "idiv", 2, {0xf7, 0x0, 0x0},1, 4,4, SCF_X64_E, 7,1, 2,{0,2}},
{SCF_X64_IDIV, "idiv", 2, {0xf7, 0x0, 0x0},1, 8,8, SCF_X64_E, 7,1, 2,{0,2}},
- {SCF_X64_CBW, "cwd", 1, {0x98, 0x0, 0x0},1, 1,2, SCF_X64_G, 0,0, 2,{0,2}},
- {SCF_X64_CWD, "cwd", 1, {0x98, 0x0, 0x0},1, 2,4, SCF_X64_G, 0,0, 2,{0,2}},
- {SCF_X64_CDQ, "cdq", 1, {0x98, 0x0, 0x0},1, 4,8, SCF_X64_G, 0,0, 2,{0,2}},
- {SCF_X64_CQO, "cqo", 1, {0x98, 0x0, 0x0},1, 8,16, SCF_X64_G, 0,0, 2,{0,2}},
+ {SCF_X64_CBW, "cbw", 1, {0x98, 0x0, 0x0},1, 1,2, SCF_X64_G, 0,0, 2,{0,2}},
+ {SCF_X64_CWD, "cwd", 1, {0x99, 0x0, 0x0},1, 2,4, SCF_X64_G, 0,0, 2,{0,2}},
+ {SCF_X64_CDQ, "cdq", 1, {0x99, 0x0, 0x0},1, 4,8, SCF_X64_G, 0,0, 2,{0,2}},
+ {SCF_X64_CQO, "cqo", 1, {0x99, 0x0, 0x0},1, 8,16, SCF_X64_G, 0,0, 2,{0,2}},
{SCF_X64_SAR, "sar", 2, {0xc0, 0x0, 0x0},1, 1,1, SCF_X64_I2E, 7,1, 0,{0,0}},
{SCF_X64_SAR, "sar", 2, {0xc1, 0x0, 0x0},1, 1,2, SCF_X64_I2E, 7,1, 0,{0,0}},
case SCF_C89:
ret = add_macro(macros, "__STDC__=1");
+ if (ret < 0)
+ goto error;
+
+ ret = add_macro(macros, "_XOPEN_SOURCE=700");
if (ret < 0)
goto error;
break;
return -ENOMEM;
var->const_literal_flag = 1;
- }
-
- scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
- node = scf_node_alloc(w, var->type, var);
+ node = scf_node_alloc(w, var->type, var);
+ scf_variable_free(var);
+ var = NULL;
+ } else {
+ node = scf_node_alloc(w, var->type, var);
+ }
- scf_variable_free(var);
- var = NULL;
if (!node)
return -ENOMEM;
+ scf_logd("\033[31m $$$ node->var: %p, node->var->refs: %d, member_flag: %d\033[0m\n\n",
+ node->var, node->var->refs, node->var->member_flag);
if (!d->expr) {
d->expr = scf_expr_alloc();