fix: x64 call argv register may be overlapped, sometimes like below:
authoryu.dongliang <18588496441@163.com>
Wed, 21 Jun 2023 17:11:31 +0000 (01:11 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 21 Jun 2023 17:11:40 +0000 (01:11 +0800)
int main()
{
int a[4] = {0, 1, 2, 3};
sort(a, 0, 3);
return 0;
}

native/x64/scf_x64_inst.c
native/x64/scf_x64_reg.c
native/x64/scf_x64_reg.h
parse/Makefile

index 52fd1a1eda2b8c75ebc449f6e06bed0800c46818..3cb5e451ae45b052b9c2c534e427d9c8913ea2c1 100644 (file)
@@ -104,76 +104,6 @@ static int _x64_inst_call_stack_size(scf_3ac_code_t* c)
        return stack_size;
 }
 
-static int _x64_load_const_arg(scf_register_t* rabi, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
-{
-       scf_instruction_t*  inst;
-       scf_x64_OpCode_t*   lea;
-       scf_x64_OpCode_t*   mov;
-       scf_variable_t*     v;
-
-       v = dn->var;
-
-       int size     = x64_variable_size(v);
-       int is_float = scf_variable_float(v);
-
-       if (SCF_FUNCTION_PTR == v->type) {
-
-               if (v->func_ptr) {
-                       assert(v->const_literal_flag);
-
-                       v->global_flag = 1;
-                       v->local_flag  = 0;
-                       v->tmp_flag    = 0;
-
-                       scf_rela_t* rela = NULL;
-
-                       lea  = x64_find_OpCode(SCF_X64_LEA,  size, size, SCF_X64_E2G);
-                       inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
-                       X64_INST_ADD_CHECK(c->instructions, inst);
-                       X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
-
-               } else {
-                       scf_x64_OpCode_t* xor;
-
-                       xor  = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
-                       inst = x64_make_inst_G2E(xor, rabi, rabi);
-                       X64_INST_ADD_CHECK(c->instructions, inst);
-               }
-
-       } else if (scf_variable_const_string(v)) {
-
-               scf_rela_t* rela = NULL;
-
-               v->global_flag = 1;
-               v->local_flag  = 0;
-               v->tmp_flag    = 0;
-
-               lea  = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
-
-               inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
-               X64_INST_ADD_CHECK(c->instructions, inst);
-               X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
-
-       } else if (v->nb_dimentions > 0) {
-               assert(v->const_literal_flag);
-
-               scf_rela_t* rela = NULL;
-
-               lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
-
-               inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
-               X64_INST_ADD_CHECK(c->instructions, inst);
-               X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
-
-       } else {
-               mov  = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
-               inst = x64_make_inst_I2G(mov, rabi, (uint8_t*)&v->data, size);
-               X64_INST_ADD_CHECK(c->instructions, inst);
-       }
-
-       return 0;
-}
-
 static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
 {
        scf_register_t* rsp  = x64_find_register("rsp");
@@ -189,9 +119,9 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
        for (i = c->srcs->size - 1; i >= 1; i--) {
                scf_3ac_operand_t*  src   = c->srcs->data[i];
                scf_variable_t*     v     = src->dag_node->var;
-               scf_register_t* rd    = src->rabi;
-               scf_register_t* rabi  = src->dag_node->rabi2;
-               scf_register_t* rs    = NULL;
+               scf_register_t*     rd    = src->rabi;
+               scf_register_t*     rabi  = src->dag_node->rabi2;
+               scf_register_t*     rs    = NULL;
 
                int size     = x64_variable_size(v);
                int is_float = scf_variable_float(v);
@@ -227,15 +157,12 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
                                if (ret < 0)
                                        return ret;
 
-                               ret = _x64_load_const_arg(rabi, src->dag_node, c, f);
+                               ret = x64_load_const(rabi, src->dag_node, c, f);
                                if (ret < 0)
                                        return ret;
 
                                rabi = x64_find_register_color_bytes(rabi->color, 8);
                                rs   = rabi;
-                       } else {
-                               if (src->dag_node->color < 0)
-                                       src->dag_node->color = rabi->color;
                        }
                } else {
                        nb_floats++;
@@ -250,13 +177,14 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
                                movx = x64_find_OpCode(SCF_X64_CVTSS2SD, 4, 8, SCF_X64_E2G);
                        } else
                                mov  = x64_find_OpCode(SCF_X64_MOVSD, size, size, SCF_X64_G2E);
-
-                       if (src->dag_node->color < 0)
-                               src->dag_node->color = rabi->color;
                }
 
+
                if (!rs) {
-                       assert(src->dag_node->color > 0);
+                       if (!src->dag_node->loaded)
+                               src->dag_node->color = x64_find_register_color_bytes(rabi->color, size)->color;
+                       else
+                               scf_logd("src->dag_node->color: %#lx\n", src->dag_node->color);
 
                        if (rd && X64_COLOR_CONFLICT(rd->color, src->dag_node->color)) {
 
index 5f893f735384636a1de0eb2ef0e1d978e1c0d50b..0339d3fb6ce0f4bbc30be9165f6750480e2d7e13 100644 (file)
@@ -849,31 +849,55 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
        return NULL;
 }
 
-static int _x64_load_reg_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
+int x64_load_const(scf_register_t* rabi, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
 {
-       scf_instruction_t* inst;
-       scf_x64_OpCode_t*  lea;
-       scf_x64_OpCode_t*  mov;
+       scf_instruction_t*  inst;
+       scf_x64_OpCode_t*   lea;
+       scf_x64_OpCode_t*   mov;
+       scf_variable_t*     v;
 
-       scf_variable_t*    v = dn->var;
+       v = dn->var;
 
-       int size = x64_variable_size(v);
+       int size     = x64_variable_size(v);
+       int is_float = scf_variable_float(v);
 
        if (SCF_FUNCTION_PTR == v->type) {
 
-               assert(v->func_ptr);
-               assert(v->const_literal_flag);
+               if (v->func_ptr) {
+                       assert(v->const_literal_flag);
+
+                       v->global_flag = 1;
+                       v->local_flag  = 0;
+                       v->tmp_flag    = 0;
+
+                       scf_rela_t* rela = NULL;
+
+                       lea  = x64_find_OpCode(SCF_X64_LEA,  size, size, SCF_X64_E2G);
+                       inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
+                       X64_INST_ADD_CHECK(c->instructions, inst);
+                       X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
+
+               } else {
+                       scf_x64_OpCode_t* xor;
+
+                       xor  = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
+                       inst = x64_make_inst_G2E(xor, rabi, rabi);
+                       X64_INST_ADD_CHECK(c->instructions, inst);
+               }
+
+       } else if (scf_variable_const_string(v)) {
+
+               scf_rela_t* rela = NULL;
 
                v->global_flag = 1;
                v->local_flag  = 0;
                v->tmp_flag    = 0;
 
-               scf_rela_t* rela = NULL;
+               lea  = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
 
-               lea  = x64_find_OpCode(SCF_X64_LEA,  size, size, SCF_X64_E2G);
-               inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+               inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
                X64_INST_ADD_CHECK(c->instructions, inst);
-               X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
+               X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
 
        } else if (v->nb_dimentions > 0) {
                assert(v->const_literal_flag);
@@ -882,13 +906,13 @@ static int _x64_load_reg_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_co
 
                lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
 
-               inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
+               inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
                X64_INST_ADD_CHECK(c->instructions, inst);
                X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
 
        } else {
                mov  = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
-               inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size);
+               inst = x64_make_inst_I2G(mov, rabi, (uint8_t*)&v->data, size);
                X64_INST_ADD_CHECK(c->instructions, inst);
        }
 
@@ -911,7 +935,7 @@ int x64_load_reg(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_f
 
                if (scf_variable_const(dn->var)) {
 
-                       int ret = _x64_load_reg_const(r, dn, c, f);
+                       int ret = x64_load_const(r, dn, c, f);
                        if (ret < 0)
                                return ret;
 
index 31b7bf02a6a10c6296c1e0969b2a8081b21c61db..7ac5dcdaabb0d99dd430b7667318b850d1bbb5a5 100644 (file)
@@ -133,10 +133,11 @@ int                 x64_push_regs(scf_vector_t* instructions, uint32_t* regs, in
 int                 x64_pop_regs (scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated);
 int                 x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
 
-int                 x64_save_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
+int                 x64_save_reg  (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
 
-int                 x64_load_reg(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
-int                 x64_reg_used(scf_register_t* r, scf_dag_node_t* dn);
+int                 x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
+int                 x64_load_reg  (scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
+int                 x64_reg_used  (scf_register_t* r, scf_dag_node_t* dn);
 
 int                 x64_overflow_reg (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
 int                 x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
index 7ea14d60f70f8e33893c46fad21d541bf704a444..51efbdbb0ea159be6018db3ba8d19fcca8472682 100644 (file)
@@ -59,10 +59,6 @@ CFILES += ../elf/scf_dwarf_abbrev.c
 CFILES += ../elf/scf_dwarf_info.c
 CFILES += ../elf/scf_dwarf_line.c
 
-CFILES += ../vm/scf_vm.c
-CFILES += ../vm/scf_vm_naja.c
-CFILES += ../vm/scf_vm_naja_asm.c
-
 CFILES += ../core/scf_lex_word.c
 CFILES += ../core/scf_type.c
 CFILES += ../core/scf_variable.c