From 05b7a069d7011507a5a4732b363455f2046ba37d Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Thu, 22 Jun 2023 01:11:31 +0800 Subject: [PATCH] fix: x64 call argv register may be overlapped, sometimes like below: int main() { int a[4] = {0, 1, 2, 3}; sort(a, 0, 3); return 0; } --- native/x64/scf_x64_inst.c | 90 ++++----------------------------------- native/x64/scf_x64_reg.c | 54 ++++++++++++++++------- native/x64/scf_x64_reg.h | 7 +-- parse/Makefile | 4 -- 4 files changed, 52 insertions(+), 103 deletions(-) diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 52fd1a1..3cb5e45 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -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)) { diff --git a/native/x64/scf_x64_reg.c b/native/x64/scf_x64_reg.c index 5f893f7..0339d3f 100644 --- a/native/x64/scf_x64_reg.c +++ b/native/x64/scf_x64_reg.c @@ -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; diff --git a/native/x64/scf_x64_reg.h b/native/x64/scf_x64_reg.h index 31b7bf0..7ac5dcd 100644 --- a/native/x64/scf_x64_reg.h +++ b/native/x64/scf_x64_reg.h @@ -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); diff --git a/parse/Makefile b/parse/Makefile index 7ea14d6..51efbdb 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -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 -- 2.25.1