self compile: for ../util/scf_string.c & ../util/test/scf_list_test.c ok. master
authoryu.dongliang <18588496441@163.com>
Thu, 3 Sep 2026 13:47:37 +0000 (21:47 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 3 Sep 2026 13:47:42 +0000 (21:47 +0800)
core/scf_operator_handler_3ac.c
examples/div.c [new file with mode: 0644]
native/x64/scf_x64.h
native/x64/scf_x64_inst.c
native/x64/scf_x64_inst_common.c
native/x64/scf_x64_inst_div.c
native/x64/scf_x64_opcode.c
parse/main.c
parse/scf_dfa_expr.c

index fdd1acd4466fdeee4a05512649c65e01dd86b224..98f86532fcdddef70cb2bdf84d7026ec8de4c7f7 100644 (file)
@@ -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 (file)
index 0000000..a9b17aa
--- /dev/null
@@ -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;
+}
index 42f4ec3a20148011af35ee8b76436078eb407cbe..015b3820dd6f2b1026493a2b290b02b97ef951cd 100644 (file)
@@ -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);
index c0c3b105a600a74fc4573fb013e82651d9d89e04..85135aae9d8c8e5ad077b5743a5a47b5e925c2e4 100644 (file)
@@ -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)
index 8740d2c4978b3376aac64e020a2bb9d83d044ff8..4fcb48a11183259cdeece2f270c0ac3f2038854e 100644 (file)
@@ -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);
index 9c55d3d31d0768316c35bf4e1f6846a4105a3e57..3134f210c0560c345b6c9a1ba6e12e2ecf34c35e 100644 (file)
@@ -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;
index f67b5d218ac466964fb65e2af6b30dcdfc6269d5..d373969bfdf1cdb552c4f6319ef98dcaacd1f4ea 100644 (file)
@@ -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}},
index 8374d53d12011113645e25b5aa0138cd6175e205..4c87a25e4ddaf7fda7e8122bde0e9ba808691f9c 100644 (file)
@@ -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;
index 83ef0815e0030e08ae964af08d072929f9c7c758..46bbc380b9baddddbe308c4990f87d4a4dafd5a2 100644 (file)
@@ -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();