From eff5cafdf09f70ed0303e3b0f1c7fa5d6e3e841f Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Thu, 3 Sep 2026 21:47:37 +0800 Subject: [PATCH] self compile: for ../util/scf_string.c & ../util/test/scf_list_test.c ok. --- core/scf_operator_handler_3ac.c | 2 + examples/div.c | 25 ++++++++++ native/x64/scf_x64.h | 6 +-- native/x64/scf_x64_inst.c | 67 ++++++++++++++++++-------- native/x64/scf_x64_inst_common.c | 2 +- native/x64/scf_x64_inst_div.c | 82 ++++++++++++++++++-------------- native/x64/scf_x64_opcode.c | 8 ++-- parse/main.c | 4 ++ parse/scf_dfa_expr.c | 14 +++--- 9 files changed, 141 insertions(+), 69 deletions(-) create mode 100644 examples/div.c diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index fdd1acd..98f8653 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -1786,6 +1786,8 @@ static int _scf_op_address_of(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, 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); diff --git a/examples/div.c b/examples/div.c new file mode 100644 index 0000000..a9b17aa --- /dev/null +++ b/examples/div.c @@ -0,0 +1,25 @@ +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; +} diff --git a/native/x64/scf_x64.h b/native/x64/scf_x64.h index 42f4ec3..015b382 100644 --- a/native/x64/scf_x64.h +++ b/native/x64/scf_x64.h @@ -73,10 +73,10 @@ int x64_assign_dereference(scf_native_t* ctx, scf_3ac_code_t* c); 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); diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index c0c3b10..85135aa 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -1075,13 +1075,13 @@ static int _x64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_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; @@ -1199,11 +1199,7 @@ static int _div_mod(scf_native_t* ctx, scf_3ac_code_t* c, int mod_flag) 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) @@ -1234,10 +1230,15 @@ static int _x64_inst_mul_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) @@ -1258,16 +1259,44 @@ 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; } @@ -1502,7 +1531,7 @@ static int _div_mod_assign(scf_native_t* ctx, scf_3ac_code_t* c, int mod_flag) 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) diff --git a/native/x64/scf_x64_inst_common.c b/native/x64/scf_x64_inst_common.c index 8740d2c..4fcb48a 100644 --- a/native/x64/scf_x64_inst_common.c +++ b/native/x64/scf_x64_inst_common.c @@ -241,7 +241,7 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ 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); diff --git a/native/x64/scf_x64_inst_div.c b/native/x64/scf_x64_inst_div.c index 9c55d3d..3134f21 100644 --- a/native/x64/scf_x64_inst_div.c +++ b/native/x64/scf_x64_inst_div.c @@ -1,14 +1,15 @@ #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; @@ -23,31 +24,31 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c 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; @@ -61,18 +62,25 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c 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); @@ -81,16 +89,16 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c 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; @@ -99,7 +107,9 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c 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); @@ -115,15 +125,15 @@ int x64_inst_int_div(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c } 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; diff --git a/native/x64/scf_x64_opcode.c b/native/x64/scf_x64_opcode.c index f67b5d2..d373969 100644 --- a/native/x64/scf_x64_opcode.c +++ b/native/x64/scf_x64_opcode.c @@ -128,10 +128,10 @@ scf_x64_OpCode_t x64_OpCodes[] = { {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}}, diff --git a/parse/main.c b/parse/main.c index 8374d53..4c87a25 100644 --- a/parse/main.c +++ b/parse/main.c @@ -524,6 +524,10 @@ int main(int argc, char* argv[]) 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; diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 83ef081..46bbc38 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -138,16 +138,18 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) 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(); -- 2.25.1