From: yu.dongliang <18588496441@163.com> Date: Sun, 13 Oct 2024 13:17:09 +0000 (+0800) Subject: fix: multi-return-value error, return in rax/rdi/rsi/rdx to decrease the binary code... X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=a2e4eda9a01628d31a56361b6511b34160d6fd30;p=scf.git fix: multi-return-value error, return in rax/rdi/rsi/rdx to decrease the binary code for little function --- diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 951ef23..7f6a32e 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -409,6 +409,21 @@ static int _x64_call_update_dsts(scf_3ac_code_t* c, scf_function_t* f, scf_regis } else { scf_rela_t* rela = NULL; + if (0 == v->bp_offset && !v->global_flag && !v->local_flag) { + + int size = f->local_vars_size + dst_size; + + if (size & 0x7) + size = (size + 7) >> 3 << 3; + + v->bp_offset = -size; + v->tmp_flag = 1; + + f->local_vars_size = size; + + scf_logd("v->bp_offset: %d, local_flag: %d, tmp_flag: %d, rs->name: %s\n", v->bp_offset, v->local_flag, v->tmp_flag, rs->name); + } + inst = x64_make_inst_G2M(&rela, mov, dn->var, NULL, rs); X64_INST_ADD_CHECK(c->instructions, inst); X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL); @@ -1414,10 +1429,10 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_variable_t* v = NULL; scf_rela_t* rela = NULL; - scf_register_t* rd = NULL; - scf_register_t* rs = NULL; - scf_register_t* rsp = x64_find_register("rsp"); - scf_register_t* rbp = x64_find_register("rbp"); + scf_register_t* rd = NULL; + scf_register_t* rs = NULL; + scf_register_t* rsp = x64_find_register("rsp"); + scf_register_t* rbp = x64_find_register("rbp"); scf_x64_OpCode_t* pop; scf_x64_OpCode_t* mov; @@ -1445,6 +1460,11 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) int retsize = size > 4 ? 8 : 4; + if (src->dag_node->color > 0) + rs = x64_find_register_color_bytes(src->dag_node->color, size); + else + rs = NULL; + if (is_float) { rd = x64_find_register_type_id_bytes(is_float, 0, retsize); @@ -1457,20 +1477,9 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) mov = x64_find_OpCode(SCF_X64_MOVSS, size, rd->bytes, SCF_X64_E2G); else mov = x64_find_OpCode(SCF_X64_MOVSD, size, rd->bytes, SCF_X64_E2G); - } else { rd = x64_find_register_type_id_bytes(is_float, x64_abi_ret_regs[i], retsize); - if (0 == src->dag_node->color) { - if (rd->bytes > size) - scf_variable_extend_bytes(v, rd->bytes); - - mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G); - inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&v->data, rd->bytes); - X64_INST_ADD_CHECK(c->instructions, inst); - continue; - } - if (rd->bytes > size) { if (scf_variable_signed(v)) mov = x64_find_OpCode(SCF_X64_MOVSX, size, rd->bytes, SCF_X64_E2G); @@ -1482,38 +1491,48 @@ static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_logd("rd: %s, rd->dag_nodes->size: %d\n", rd->name, rd->dag_nodes->size); - if (src->dag_node->color > 0) { - - int start = c->instructions->size; + int ret = x64_save_reg(rd, c, f); + if (ret < 0) + return ret; - X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + if (src->dag_node->color > 0) { + int j; + for (j = 0; j < i; j++) { + if (x64_abi_ret_regs[j] == rs->id) + break; + } - if (!X64_COLOR_CONFLICT(rd->color, rs->color)) { + if (j < i) { + scf_vector_del(rs->dag_nodes, src->dag_node); - int ret = x64_save_reg(rd, c, f); - if (ret < 0) - return ret; + scf_logd("i: %d, j: %d, rd: %s, rs: %s, rs->dag_node->size: %d\n", i, j, rd->name, rs->name, rs->dag_nodes->size); - inst = x64_make_inst_E2G(mov, rd, rs); - X64_INST_ADD_CHECK(c->instructions, inst); + src->dag_node->color = x64_find_register_color_bytes(rd->color, size)->color; - scf_instruction_t* tmp; - int j; - int k; - for (j = start; j < c->instructions->size; j++) { - tmp = c->instructions->data[j]; + X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - for (k = j - 1; k >= j - start; k--) - c->instructions->data[k + 1] = c->instructions->data[k]; + if (rd->bytes > size) { + inst = x64_make_inst_E2G(mov, rd, rs); + X64_INST_ADD_CHECK(c->instructions, inst); + } + } else { + X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - c->instructions->data[j - start] = tmp; + if (!X64_COLOR_CONFLICT(rd->color, rs->color) || rd->bytes > size) { + inst = x64_make_inst_E2G(mov, rd, rs); + X64_INST_ADD_CHECK(c->instructions, inst); } } - } else { - int ret = x64_save_reg(rd, c, f); - if (ret < 0) - return ret; + } else if (0 == src->dag_node->color) { + assert(0 == is_float); + + if (rd->bytes > size) + scf_variable_extend_bytes(v, rd->bytes); + mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G); + inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&v->data, rd->bytes); + X64_INST_ADD_CHECK(c->instructions, inst); + } else { inst = x64_make_inst_M2G(&rela, mov, rd, NULL, v); X64_INST_ADD_CHECK(c->instructions, inst); X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); diff --git a/native/x64/scf_x64_peephole.c b/native/x64/scf_x64_peephole.c index 91d0545..76becf1 100644 --- a/native/x64/scf_x64_peephole.c +++ b/native/x64/scf_x64_peephole.c @@ -414,6 +414,8 @@ static void _x64_peephole_function(scf_vector_t* tmp_insts, scf_function_t* f, i f->bp_used_flag = 1; else f->bp_used_flag = 0; + + scf_logw("%s(), f->bp_used_flag: %d\n", f->node.w->text->data, f->bp_used_flag); } int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) @@ -446,7 +448,7 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) int ret = 0; for (l = scf_list_head(&f->basic_block_list_head); l != scf_list_sentinel(&f->basic_block_list_head); - l = scf_list_next(l)) { + l = scf_list_next(l)) { bb = scf_list_data(l, scf_basic_block_t, list); @@ -461,7 +463,6 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) if (dst->bb->index < bb->index) jmp_back_flag = 1; - continue; } @@ -469,9 +470,9 @@ int x64_optimize_peephole(scf_native_t* ctx, scf_function_t* f) scf_vector_clear(std_insts, NULL); for (l2 = scf_list_head(&bb->code_list_head); l2 != scf_list_sentinel(&bb->code_list_head); - l2 = scf_list_next(l2)) { + l2 = scf_list_next(l2)) { - c = scf_list_data(l2, scf_3ac_code_t, list); + c = scf_list_data(l2, scf_3ac_code_t, list); if (!c->instructions) continue; @@ -528,4 +529,3 @@ error: scf_vector_free(std_insts); return ret; } - diff --git a/native/x64/scf_x64_reg.c b/native/x64/scf_x64_reg.c index b4bb4ba..0bec392 100644 --- a/native/x64/scf_x64_reg.c +++ b/native/x64/scf_x64_reg.c @@ -1391,4 +1391,3 @@ int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f) return 0; } - diff --git a/native/x64/scf_x64_reg.h b/native/x64/scf_x64_reg.h index 4f2c555..832c62e 100644 --- a/native/x64/scf_x64_reg.h +++ b/native/x64/scf_x64_reg.h @@ -54,9 +54,9 @@ static uint32_t x64_abi_float_regs[] = static uint32_t x64_abi_ret_regs[] = { SCF_X64_REG_RAX, - SCF_X64_REG_RCX, - SCF_X64_REG_RDX, SCF_X64_REG_RDI, + SCF_X64_REG_RSI, + SCF_X64_REG_RDX, }; #define X64_ABI_RET_NB (sizeof(x64_abi_ret_regs) / sizeof(x64_abi_ret_regs[0]))