From: yu.dongliang <18588496441@163.com> Date: Wed, 3 May 2023 07:21:57 +0000 (+0800) Subject: make a framework for RISC register selection X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=2b0c0991001bbf11f484da7ea2ad16af9d2303d0;p=scf.git make a framework for RISC register selection --- diff --git a/core/scf_core_types.h b/core/scf_core_types.h index 27cf38b..769e90d 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -19,6 +19,7 @@ typedef struct scf_scope_s scf_scope_t; typedef struct scf_3ac_code_s scf_3ac_code_t; typedef struct scf_inst_ops_s scf_inst_ops_t; +typedef struct scf_regs_ops_s scf_regs_ops_t; typedef struct scf_register_s scf_register_t; typedef struct scf_OpCode_s scf_OpCode_t; diff --git a/core/scf_function.h b/core/scf_function.h index 0158779..cdfa296 100644 --- a/core/scf_function.h +++ b/core/scf_function.h @@ -43,6 +43,7 @@ struct scf_function_s { scf_vector_t* data_relas; // re-localtions in .data segment scf_inst_ops_t* iops; + scf_regs_ops_t* rops; scf_vector_t* init_insts; int init_code_bytes; diff --git a/native/risc/scf_arm64.c b/native/risc/scf_arm64.c index b8e46e6..d51f810 100644 --- a/native/risc/scf_arm64.c +++ b/native/risc/scf_arm64.c @@ -61,7 +61,7 @@ int arm64_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int byte int arm64_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -120,7 +120,7 @@ int arm64_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s int arm64_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* ri = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -241,7 +241,7 @@ int arm64_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf int arm64_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* ri = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -706,7 +706,7 @@ int arm64_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, s int arm64_inst_M2GF(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* ro = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -1525,8 +1525,8 @@ void arm64_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) int arm64_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp) { scf_instruction_t* inst; - scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8); - scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8); + scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8); + scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8); scf_register_t* r0; uint32_t opcode; @@ -1543,7 +1543,7 @@ int arm64_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cm // arm64 case 0x71: // imm i0 = (opcode >> 5) & 0x1f; - r0 = risc_find_register_type_id_bytes(0, i0, 8); + r0 = f->rops->find_register_type_id_bytes(0, i0, 8); inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); @@ -1555,11 +1555,11 @@ int arm64_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cm i0 = (opcode >> 5) & 0x1f; i1 = (opcode >> 16) & 0x1f; - r0 = risc_find_register_type_id_bytes(0, i0, 8); + r0 = f->rops->find_register_type_id_bytes(0, i0, 8); inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); - r0 = risc_find_register_type_id_bytes(0, i1, 8); + r0 = f->rops->find_register_type_id_bytes(0, i1, 8); inst = f->iops->MOV_G(c, r17, r0); // use r17 to backup r1 RISC_INST_ADD_CHECK(c->instructions, inst); diff --git a/native/risc/scf_naja.c b/native/risc/scf_naja.c index 5f26d56..2fa5c4f 100644 --- a/native/risc/scf_naja.c +++ b/native/risc/scf_naja.c @@ -61,7 +61,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -120,7 +120,7 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* ri = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -228,7 +228,7 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, scf_variable_t* vs) { - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* ri = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -1342,8 +1342,8 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp) { scf_instruction_t* inst; - scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8); - scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8); + scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8); + scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8); scf_register_t* r0; uint32_t opcode; @@ -1361,7 +1361,7 @@ int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp case 0x24: if (cmp->code[2] & 0x10) { i0 = opcode & 0x1f; - r0 = risc_find_register_type_id_bytes(0, i0, 8); + r0 = f->rops->find_register_type_id_bytes(0, i0, 8); inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); @@ -1371,11 +1371,11 @@ int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp i0 = opcode & 0x1f; i1 = (opcode >> 5) & 0x1f; - r0 = risc_find_register_type_id_bytes(0, i0, 8); + r0 = f->rops->find_register_type_id_bytes(0, i0, 8); inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); - r0 = risc_find_register_type_id_bytes(0, i1, 8); + r0 = f->rops->find_register_type_id_bytes(0, i1, 8); inst = f->iops->MOV_G(c, r17, r0); // use r17 to backup r1 RISC_INST_ADD_CHECK(c->instructions, inst); diff --git a/native/risc/scf_risc.c b/native/risc/scf_risc.c index 9d80829..f338387 100644 --- a/native/risc/scf_risc.c +++ b/native/risc/scf_risc.c @@ -3,6 +3,9 @@ #include"scf_basic_block.h" #include"scf_3ac.h" +extern scf_regs_ops_t regs_ops_arm64; +extern scf_regs_ops_t regs_ops_naja; + extern scf_inst_ops_t inst_ops_arm64; extern scf_inst_ops_t inst_ops_naja; @@ -14,9 +17,18 @@ static scf_inst_ops_t* inst_ops_array[] = NULL }; +static scf_regs_ops_t* regs_ops_array[] = +{ + ®s_ops_arm64, + ®s_ops_naja, + + NULL +}; + int scf_risc_open(scf_native_t* ctx, const char* arch) { scf_inst_ops_t* iops = NULL; + scf_regs_ops_t* rops = NULL; int i; for (i = 0; inst_ops_array[i]; i++) { @@ -27,7 +39,15 @@ int scf_risc_open(scf_native_t* ctx, const char* arch) } } - if (!iops) + for (i = 0; regs_ops_array[i]; i++) { + + if (!strcmp(regs_ops_array[i]->name, arch)) { + rops = regs_ops_array[i]; + break; + } + } + + if (!iops || !rops) return -EINVAL; scf_risc_context_t* risc = calloc(1, sizeof(scf_risc_context_t)); @@ -35,6 +55,7 @@ int scf_risc_open(scf_native_t* ctx, const char* arch) return -ENOMEM; ctx->iops = iops; + ctx->rops = rops; ctx->priv = risc; return 0; } @@ -44,7 +65,7 @@ int scf_risc_close(scf_native_t* ctx) scf_risc_context_t* risc = ctx->priv; if (risc) { - risc_registers_clear(); + ctx->rops->registers_clear(); free(risc); risc = NULL; @@ -79,7 +100,7 @@ static void _risc_argv_rabi(scf_function_t* f) if (f->args_float < RISC_ABI_NB) { - v->rabi = risc_find_register_type_id_bytes(is_float, risc_abi_float_regs[f->args_float], size); + v->rabi = f->rops->find_register_type_id_bytes(is_float, risc_abi_float_regs[f->args_float], size); v->bp_offset = bp_floats; bp_floats -= 8; f->args_float++; @@ -87,7 +108,7 @@ static void _risc_argv_rabi(scf_function_t* f) } } else if (f->args_int < RISC_ABI_NB) { - v->rabi = risc_find_register_type_id_bytes(is_float, risc_abi_regs[f->args_int], size); + v->rabi = f->rops->find_register_type_id_bytes(is_float, risc_abi_regs[f->args_int], size); v->bp_offset = bp_int; bp_int -= 8; f->args_int++; @@ -104,7 +125,7 @@ static int _risc_function_init(scf_function_t* f, scf_vector_t* local_vars) { scf_variable_t* v; - int ret = risc_registers_init(); + int ret = f->rops->registers_init(); if (ret < 0) return ret; @@ -166,14 +187,14 @@ static int _risc_save_rabi(scf_function_t* f) inst = NULL; mov = risc_find_OpCode(SCF_RISC_MOV, 8,8, SCF_RISC_G2E); - rbp = risc_find_register("rbp"); + rbp = f->rops->find_register("rbp"); - rdi = risc_find_register("rdi"); - rsi = risc_find_register("rsi"); - rdx = risc_find_register("rdx"); - rcx = risc_find_register("rcx"); - r8 = risc_find_register("r8"); - r9 = risc_find_register("r9"); + rdi = f->rops->find_register("rdi"); + rsi = f->rops->find_register("rsi"); + rdx = f->rops->find_register("rdx"); + rcx = f->rops->find_register("rcx"); + r8 = f->rops->find_register("r8"); + r9 = f->rops->find_register("r9"); #define RISC_SAVE_RABI(offset, rabi) \ do { \ @@ -191,10 +212,10 @@ static int _risc_save_rabi(scf_function_t* f) mov = risc_find_OpCode(SCF_RISC_MOVSD, 8,8, SCF_RISC_G2E); - xmm0 = risc_find_register("xmm0"); - xmm1 = risc_find_register("xmm1"); - xmm2 = risc_find_register("xmm2"); - xmm3 = risc_find_register("xmm3"); + xmm0 = f->rops->find_register("xmm0"); + xmm1 = f->rops->find_register("xmm1"); + xmm2 = f->rops->find_register("xmm2"); + xmm3 = f->rops->find_register("xmm3"); RISC_SAVE_RABI(-56, xmm0); RISC_SAVE_RABI(-64, xmm1); @@ -214,8 +235,8 @@ static int _risc_function_finish(scf_native_t* ctx, scf_function_t* f) } else scf_vector_clear(f->init_insts, free); - scf_register_t* sp = risc_find_register("sp"); - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* sp = f->rops->find_register("sp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* r; scf_instruction_t* inst = NULL; @@ -262,10 +283,10 @@ static int _risc_function_finish(scf_native_t* ctx, scf_function_t* f) int i; for (i = 0; i < RISC_ABI_CALLEE_SAVES_NB; i++) { - r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8); + r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8); if (!r->used) { - r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4); + r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4); if (!r->used) continue; @@ -277,11 +298,11 @@ static int _risc_function_finish(scf_native_t* ctx, scf_function_t* f) f->init_code_bytes += inst->len; } - risc_registers_clear(); + f->rops->registers_clear(); return 0; } -static void _risc_rcg_node_printf(risc_rcg_node_t* rn) +static void _risc_rcg_node_printf(risc_rcg_node_t* rn, scf_function_t* f) { if (rn->dag_node) { scf_variable_t* v = rn->dag_node->var; @@ -312,7 +333,7 @@ static void _risc_rcg_node_printf(risc_rcg_node_t* rn) } if (rn->dag_node->color > 0) { - scf_register_t* r = risc_find_register_color(rn->dag_node->color); + scf_register_t* r = f->rops->find_register_color(rn->dag_node->color); printf(", reg: %s\n", r->name); } else { printf("\n"); @@ -496,7 +517,7 @@ static int _risc_make_bb_rcg(scf_graph_t* g, scf_basic_block_t* bb, scf_native_t return 0; } -static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g) +static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g, scf_function_t* f) { int i; for (i = 0; i < g->nodes->size; i++) { @@ -506,7 +527,7 @@ static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g) scf_dn_status_t* ds; if (!dn) { - _risc_rcg_node_printf(rn); + _risc_rcg_node_printf(rn, f); continue; } @@ -522,7 +543,7 @@ static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g) ds->color = gn->color; dn->color = gn->color; - _risc_rcg_node_printf(rn); + _risc_rcg_node_printf(rn, f); } printf("\n"); @@ -553,7 +574,7 @@ static int _risc_select_bb_regs(scf_basic_block_t* bb, scf_native_t* ctx) if (ret < 0) goto error; - colors = risc_register_colors(); + colors = f->rops->register_colors(); if (!colors) { ret = -ENOMEM; goto error; @@ -563,7 +584,7 @@ static int _risc_select_bb_regs(scf_basic_block_t* bb, scf_native_t* ctx) if (ret < 0) goto error; - ret = _risc_bb_regs_from_graph(bb, g); + ret = _risc_bb_regs_from_graph(bb, g, f); error: if (colors) @@ -578,7 +599,7 @@ error: static int _risc_select_bb_group_regs(scf_bb_group_t* bbg, scf_native_t* ctx) { scf_risc_context_t* risc = ctx->priv; - scf_function_t* f = risc->f; + scf_function_t* f = risc->f; scf_graph_t* g = scf_graph_alloc(); if (!g) @@ -604,7 +625,7 @@ static int _risc_select_bb_group_regs(scf_bb_group_t* bbg, scf_native_t* ctx) goto error; } - colors = risc_register_colors(); + colors = f->rops->register_colors(); if (!colors) { ret = -ENOMEM; goto error; @@ -614,7 +635,7 @@ static int _risc_select_bb_group_regs(scf_bb_group_t* bbg, scf_native_t* ctx) if (ret < 0) goto error; - ret = _risc_bb_regs_from_graph(bbg->pre, g); + ret = _risc_bb_regs_from_graph(bbg->pre, g, f); if (ret < 0) goto error; @@ -983,7 +1004,7 @@ int _scf_risc_select_inst(scf_native_t* ctx) if (ret < 0) return ret; - risc_init_bb_colors(bb); + risc_init_bb_colors(bb, f); if (0 == bb->index) { ret = _risc_argv_save(bb, f); @@ -1004,7 +1025,7 @@ int _scf_risc_select_inst(scf_native_t* ctx) if (ret < 0) return ret; - risc_init_bb_colors(bbg->pre); + risc_init_bb_colors(bbg->pre, f); if (0 == bbg->pre->index) { ret = _risc_argv_save(bbg->pre, f); @@ -1044,7 +1065,7 @@ int _scf_risc_select_inst(scf_native_t* ctx) if (ret < 0) return ret; - risc_init_bb_colors(bbg->pre); + risc_init_bb_colors(bbg->pre, f); if (0 == bbg->pre->index) { ret = _risc_argv_save(bbg->pre, f); @@ -1136,6 +1157,7 @@ int scf_risc_select_inst(scf_native_t* ctx, scf_function_t* f) risc->f = f; f->iops = ctx->iops; + f->rops = ctx->rops; scf_vector_t* local_vars = scf_vector_alloc(); if (!local_vars) diff --git a/native/risc/scf_risc.h b/native/risc/scf_risc.h index 0e50dca..4259da1 100644 --- a/native/risc/scf_risc.h +++ b/native/risc/scf_risc.h @@ -96,7 +96,7 @@ int risc_bb_save_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, int risc_fix_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f); int risc_load_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f); int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f); -void risc_init_bb_colors (scf_basic_block_t* bb); +void risc_init_bb_colors (scf_basic_block_t* bb, scf_function_t* f); scf_instruction_t* risc_make_inst (scf_3ac_code_t* c, uint32_t opcode); diff --git a/native/risc/scf_risc_bb_color.c b/native/risc/scf_risc_bb_color.c index 0cac255..a65991f 100644 --- a/native/risc/scf_risc_bb_color.c +++ b/native/risc/scf_risc_bb_color.c @@ -3,15 +3,16 @@ #include"scf_basic_block.h" #include"scf_3ac.h" -void risc_init_bb_colors(scf_basic_block_t* bb) +void risc_init_bb_colors(scf_basic_block_t* bb, scf_function_t* f) { scf_dag_node_t* dn; scf_dn_status_t* ds; + scf_variable_t* v; + scf_register_t* r; - int i; - - risc_registers_reset(); + f->rops->registers_reset(); + int i; for (i = 0; i < bb->dn_colors_entry->size; i++) { ds = bb->dn_colors_entry->data[i]; @@ -23,7 +24,8 @@ void risc_init_bb_colors(scf_basic_block_t* bb) dn->loaded = 1; if (scf_vector_find(bb->dn_loads, dn)) { - scf_variable_t* v = dn->var; + + v = dn->var; if (v->w) scf_loge("v_%d_%d/%s, ", v->w->line, v->w->pos, v->w->text->data); else @@ -32,7 +34,7 @@ void risc_init_bb_colors(scf_basic_block_t* bb) printf("color: %ld, loaded: %d", dn->color, dn->loaded); if (dn->color > 0) { - scf_register_t* r = risc_find_register_color(dn->color); + r = f->rops->find_register_color(dn->color); printf(", reg: %s", r->name); } printf("\n"); @@ -122,7 +124,7 @@ int risc_bb_load_dn(intptr_t color, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_b dn->loaded = 0; - r = risc_find_register_color(color); + r = f->rops->find_register_color(color); ret = risc_load_reg(r, dn, c, f); if (ret < 0) { @@ -154,7 +156,7 @@ int risc_bb_save_dn(intptr_t color, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_b return -ENOMEM; } - r = risc_find_register_color(color); + r = f->rops->find_register_color(color); ret = risc_save_var2(dn, r, c, f); if (ret < 0) { @@ -167,9 +169,9 @@ int risc_bb_save_dn(intptr_t color, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_b int risc_bb_load_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, scf_function_t* f) { - scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8); - scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8); - scf_register_t* r0; + scf_register_t* r0; + scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8); + scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8); scf_instruction_t* cmp = NULL; scf_instruction_t* inst; scf_3ac_code_t* c; @@ -319,7 +321,7 @@ int risc_load_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function } if (color != dn->color && color > 0) { - scf_register_t* r = risc_find_register_color(color); + scf_register_t* r = f->rops->find_register_color(color); scf_vector_del(r->dag_nodes, dn); } @@ -338,7 +340,7 @@ int risc_load_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function printf("v_%#lx", 0xffff & (uintptr_t)v); if (dn->color > 0) { - scf_register_t* r = risc_find_register_color(dn->color); + scf_register_t* r = f->rops->find_register_color(dn->color); printf(", %s", r->name); } @@ -415,12 +417,12 @@ int risc_fix_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_ int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f) { - scf_register_t* r; scf_basic_block_t* prev; scf_dn_status_t* ds; scf_dn_status_t* ds2; scf_dag_node_t* dn; scf_variable_t* v; + scf_register_t* r; int i; int j; @@ -493,7 +495,7 @@ int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_functio } if (color != dn->color && color > 0) { - r = risc_find_register_color(color); + r = f->rops->find_register_color(color); scf_vector_del(r->dag_nodes, dn); } @@ -515,7 +517,7 @@ int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_functio printf("v_%#lx", 0xffff & (uintptr_t)v); #endif if (dn->color > 0) { - r = risc_find_register_color(dn->color); + r = f->rops->find_register_color(dn->color); if (dn->loaded) assert(0 == scf_vector_add_unique(r->dag_nodes, dn)); diff --git a/native/risc/scf_risc_inst.c b/native/risc/scf_risc_inst.c index d266348..d6bedbd 100644 --- a/native/risc/scf_risc_inst.c +++ b/native/risc/scf_risc_inst.c @@ -58,7 +58,7 @@ static int _risc_inst_call_stack_size(scf_3ac_code_t* c) static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_function_t* f) { - scf_register_t* sp = risc_find_register("sp"); + scf_register_t* sp = f->rops->find_register("sp"); scf_risc_OpCode_t* lea; scf_risc_OpCode_t* mov; @@ -81,9 +81,9 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi int is_float = scf_variable_float(v); if (!rabi) { - rabi = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size); + rabi = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size); - ret = risc_overflow_reg(rabi, c, f); + ret = f->rops->overflow_reg(rabi, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -104,7 +104,7 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi if (0 == src->dag_node->color) { - ret = risc_overflow_reg(rabi, c, f); + ret = f->rops->overflow_reg(rabi, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -116,7 +116,7 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi return ret; } - rabi = risc_find_register_color_bytes(rabi->color, 8); + rabi = f->rops->find_register_color_bytes(rabi->color, 8); rs = rabi; } else { if (src->dag_node->color < 0) @@ -145,7 +145,7 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi if (rd && RISC_COLOR_CONFLICT(rd->color, src->dag_node->color)) { - ret = risc_overflow_reg2(rd, src->dag_node, c, f); + ret = f->rops->overflow_reg2(rd, src->dag_node, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -153,7 +153,7 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi } RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - rs = risc_find_register_color_bytes(rs->color, 8); + rs = f->rops->find_register_color_bytes(rs->color, 8); } if (movx) { @@ -183,14 +183,14 @@ static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_functi continue; } - ret = risc_overflow_reg2(rd, src->dag_node, c, f); + ret = f->rops->overflow_reg2(rd, src->dag_node, c, f); if (ret < 0) { scf_loge("\n"); return ret; } if (!RISC_COLOR_CONFLICT(rd->color, rs->color)) { - rd = risc_find_register_color_bytes(rd->color, rs->bytes); + rd = f->rops->find_register_color_bytes(rd->color, rs->bytes); if (!is_float) inst = ctx->iops->MOV_G(c, rd, rs); @@ -226,11 +226,11 @@ static int _risc_call_save_ret_regs(scf_3ac_code_t* c, scf_function_t* f, scf_fu return -1; } - r = risc_find_register_type_id_bytes(is_float, 0, 8); + r = f->rops->find_register_type_id_bytes(is_float, 0, 8); } else - r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], 8); + r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], 8); - int ret = risc_overflow_reg(r, c, f); + int ret = f->rops->overflow_reg(r, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -239,7 +239,7 @@ static int _risc_call_save_ret_regs(scf_3ac_code_t* c, scf_function_t* f, scf_fu return 0; } -static int _risc_dst_reg_valid(scf_register_t* rd, scf_register_t** updated_regs, int nb_updated, int abi_idx, int abi_total) +static int _risc_dst_reg_valid(scf_function_t* f, scf_register_t* rd, scf_register_t** updated_regs, int nb_updated, int abi_idx, int abi_total) { scf_register_t* r; @@ -254,7 +254,7 @@ static int _risc_dst_reg_valid(scf_register_t* rd, scf_register_t** updated_regs for (i = abi_idx; i < abi_total; i++) { - r = risc_find_register_type_id_bytes(RISC_COLOR_TYPE(rd->color), risc_abi_ret_regs[i], rd->bytes); + r = f->rops->find_register_type_id_bytes(RISC_COLOR_TYPE(rd->color), risc_abi_ret_regs[i], rd->bytes); if (RISC_COLOR_CONFLICT(r->color, rd->color)) return 0; @@ -319,7 +319,7 @@ static int _risc_call_update_dsts(scf_native_t* ctx, scf_3ac_code_t* c, scf_func scf_loge("\n"); return -EINVAL; - rs = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, dst_size); + rs = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, dst_size); if (SCF_VAR_FLOAT == dn->var->type) mov = risc_find_OpCode(SCF_RISC_MOVSS, dst_size, dst_size, SCF_RISC_G2E); @@ -328,7 +328,7 @@ static int _risc_call_update_dsts(scf_native_t* ctx, scf_3ac_code_t* c, scf_func idx_float++; } else { - rs = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[idx_int], dst_size); + rs = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[idx_int], dst_size); mov = risc_find_OpCode(SCF_RISC_MOV, dst_size, dst_size, SCF_RISC_G2E); @@ -338,9 +338,9 @@ static int _risc_call_update_dsts(scf_native_t* ctx, scf_3ac_code_t* c, scf_func scf_instruction_t* inst; if (dn->color > 0) { - rd = risc_find_register_color(dn->color); + rd = f->rops->find_register_color(dn->color); - int rd_vars = risc_reg_cached_vars(rd); + int rd_vars = f->rops->reg_cached_vars(rd); if (rd_vars > 1) { dn->color = -1; @@ -362,7 +362,7 @@ static int _risc_call_update_dsts(scf_native_t* ctx, scf_3ac_code_t* c, scf_func continue; } - int valid = _risc_dst_reg_valid(rd, updated_regs, nb_updated, idx_int, nb_int); + int valid = _risc_dst_reg_valid(f, rd, updated_regs, nb_updated, idx_int, nb_int); if (valid) { inst = ctx->iops->MOV_G(c, rd, rs); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -379,7 +379,7 @@ static int _risc_call_update_dsts(scf_native_t* ctx, scf_3ac_code_t* c, scf_func } } - int rs_vars = risc_reg_cached_vars(rs); + int rs_vars = f->rops->reg_cached_vars(rs); if (0 == rs_vars) { if (scf_vector_add(rs->dag_nodes, dn) < 0) @@ -426,9 +426,9 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_t* lr = risc_find_register("lr"); - scf_register_t* sp = risc_find_register("sp"); - scf_register_t* x0 = risc_find_register("x0"); + scf_register_t* lr = f->rops->find_register("lr"); + scf_register_t* sp = f->rops->find_register("sp"); + scf_register_t* x0 = f->rops->find_register("x0"); scf_instruction_t* inst; scf_instruction_t* inst_sp = NULL; scf_instruction_t* inst_sp2 = NULL; @@ -452,13 +452,13 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } } - ret = risc_overflow_reg(x0, c, f); + ret = f->rops->overflow_reg(x0, c, f); if (ret < 0) { scf_loge("\n"); return ret; } - risc_call_rabi(NULL, NULL, c); + risc_call_rabi(NULL, NULL, c, f); int32_t stack_size = _risc_inst_call_stack_size(c); if (stack_size > 0) { @@ -476,7 +476,7 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_register_t* saved_regs[RISC_ABI_CALLER_SAVES_NB]; - int save_size = risc_caller_save_regs(c, f, risc_abi_caller_saves, RISC_ABI_CALLER_SAVES_NB, stack_size, saved_regs); + int save_size = f->rops->caller_save_regs(c, f, risc_abi_caller_saves, RISC_ABI_CALLER_SAVES_NB, stack_size, saved_regs); if (save_size < 0) { scf_loge("\n"); return save_size; @@ -571,7 +571,7 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } if (save_size > 0) { - ret = risc_pop_regs(c, f, saved_regs, save_size >> 3, updated_regs, nb_updated); + ret = f->rops->pop_regs(c, f, saved_regs, save_size >> 3, updated_regs, nb_updated); if (ret < 0) { scf_loge("\n"); return ret; @@ -1336,7 +1336,7 @@ static int _risc_inst_inc_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* if (ret < 0) return ret; - r = risc_find_register_color_bytes(r->color, size); + r = f->rops->find_register_color_bytes(r->color, size); if (sib.index) ret = ctx->iops->SIB2G(c, f, r, &sib); @@ -1403,7 +1403,7 @@ static int _risc_inst_dec_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* if (ret < 0) return ret; - r = risc_find_register_color_bytes(r->color, size); + r = f->rops->find_register_color_bytes(r->color, size); if (sib.index) ret = ctx->iops->SIB2G(c, f, r, &sib); @@ -1702,12 +1702,12 @@ static int _risc_inst_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!c->dsts || c->dsts->size != 1) return -EINVAL; - scf_register_t* rd = NULL; - scf_risc_context_t* risc = ctx->priv; - scf_3ac_operand_t* base = c->srcs->data[0]; - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_instruction_t* inst; - scf_function_t* f = risc->f; + scf_risc_context_t* risc = ctx->priv; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_instruction_t* inst = NULL; + scf_function_t* f = risc->f; + scf_register_t* rd = NULL; if (!base || !base->dag_node) return -EINVAL; @@ -1739,9 +1739,11 @@ static int _risc_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_t* rax = risc_find_register("rax"); + scf_risc_context_t* risc = ctx->priv; + scf_function_t* f = risc->f; + scf_register_t* rax = f->rops->find_register("rax"); scf_risc_OpCode_t* push; - scf_instruction_t* inst; + scf_instruction_t* inst; #if 0 push = risc_find_OpCode(SCF_RISC_PUSH, 8,8, SCF_RISC_G); @@ -1760,9 +1762,11 @@ static int _risc_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_t* rax = risc_find_register("rax"); + scf_risc_context_t* risc = ctx->priv; + scf_function_t* f = risc->f; + scf_register_t* rax = f->rops->find_register("rax"); scf_risc_OpCode_t* pop; - scf_instruction_t* inst; + scf_instruction_t* inst; #if 0 pop = risc_find_OpCode(SCF_RISC_POP, 8,8, SCF_RISC_G); inst = ctx->iops->G(pop, rax); @@ -1799,7 +1803,7 @@ static int _risc_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_loge("c->srcs->size: %d\n", c->srcs->size); assert(3 == c->srcs->size); - scf_register_t* rbp = risc_find_register("rbp"); + scf_register_t* rbp = f->rops->find_register("rbp"); scf_register_t* rptr = NULL; scf_register_t* rap = NULL; scf_instruction_t* inst = NULL; @@ -1867,7 +1871,7 @@ static int _risc_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) assert(2 == c->srcs->size); - scf_register_t* rbp = risc_find_register("rbp"); + scf_register_t* rbp = f->rops->find_register("rbp"); scf_register_t* rptr = NULL; scf_register_t* rap = NULL; scf_instruction_t* inst = NULL; @@ -1929,7 +1933,7 @@ static int _risc_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) assert(1 == c->dsts->size && 3 == c->srcs->size); - scf_register_t* rbp = risc_find_register("rbp"); + scf_register_t* rbp = f->rops->find_register("rbp"); scf_register_t* rd = NULL; // result scf_register_t* rap = NULL; // ap scf_register_t* rptr = NULL; // ptr @@ -2070,7 +2074,7 @@ static int _risc_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c) } assert(dst->dag_node->color > 0); - ret = risc_overflow_reg2(rd, dst->dag_node, c, f); + ret = f->rops->overflow_reg2(rd, dst->dag_node, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -3562,8 +3566,8 @@ static int _risc_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_register_t* rd = NULL; scf_register_t* rs = NULL; - scf_register_t* sp = risc_find_register("sp"); - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* sp = f->rops->find_register("sp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_risc_OpCode_t* pop; scf_risc_OpCode_t* mov; @@ -3592,7 +3596,7 @@ static int _risc_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) int retsize = size > 4 ? 8 : 4; if (is_float) { - rd = risc_find_register_type_id_bytes(is_float, 0, retsize); + rd = f->rops->find_register_type_id_bytes(is_float, 0, retsize); if (0 == src->dag_node->color) { src->dag_node->color = -1; @@ -3603,7 +3607,7 @@ static int _risc_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -1; } else { - rd = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], retsize); + rd = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], retsize); if (0 == src->dag_node->color) { if (rd->bytes > size) @@ -3675,16 +3679,16 @@ static int _risc_inst_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!c->srcs || c->srcs->size != 3) return -EINVAL; - scf_risc_context_t* risc = ctx->priv; + scf_risc_context_t* risc = ctx->priv; scf_function_t* f = risc->f; scf_3ac_operand_t* dst = c->srcs->data[0]; scf_3ac_operand_t* data = c->srcs->data[1]; scf_3ac_operand_t* count = c->srcs->data[2]; scf_instruction_t* inst = NULL; - scf_register_t* rax = risc_find_register("rax"); - scf_register_t* rcx = risc_find_register("rcx"); - scf_register_t* rdi = risc_find_register("rdi"); + scf_register_t* rax = f->rops->find_register("rax"); + scf_register_t* rcx = f->rops->find_register("rcx"); + scf_register_t* rdi = f->rops->find_register("rdi"); scf_register_t* rd; scf_risc_OpCode_t* mov; scf_risc_OpCode_t* stos; @@ -3695,15 +3699,15 @@ static int _risc_inst_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - int ret = risc_overflow_reg2(rdi, dst->dag_node, c, f); + int ret = f->rops->overflow_reg2(rdi, dst->dag_node, c, f); if (ret < 0) return ret; - ret = risc_overflow_reg2(rax, data->dag_node, c, f); + ret = f->rops->overflow_reg2(rax, data->dag_node, c, f); if (ret < 0) return ret; - ret = risc_overflow_reg2(rcx, count->dag_node, c, f); + ret = f->rops->overflow_reg2(rcx, count->dag_node, c, f); if (ret < 0) return ret; @@ -3750,26 +3754,27 @@ static int _risc_inst_nop_handler(scf_native_t* ctx, scf_3ac_code_t* c) static int _risc_inst_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) { + scf_risc_context_t* risc = ctx->priv; + scf_instruction_t* inst = NULL; + scf_function_t* f = risc->f; + if (!c->instructions) { c->instructions = scf_vector_alloc(); if (!c->instructions) return -ENOMEM; } - scf_register_t* sp = risc_find_register("sp"); - scf_register_t* fp = risc_find_register("fp"); + scf_register_t* sp = f->rops->find_register("sp"); + scf_register_t* fp = f->rops->find_register("fp"); scf_register_t* r; - - scf_instruction_t* inst = NULL; - int i; for (i = RISC_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) { - r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8); + r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8); if (!r->used) { - r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4); + r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4); if (!r->used) continue; @@ -3854,9 +3859,9 @@ static int _risc_inst_load_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - r = risc_find_register_color(dn->color); + r = f->rops->find_register_color(dn->color); - if (risc_reg_used(r, dn)) { + if (f->rops->reg_used(r, dn)) { dn->color = -1; dn->loaded = 0; scf_vector_del(r->dag_nodes, dn); @@ -3903,9 +3908,9 @@ static int _risc_inst_reload_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - r = risc_find_register_color(dn->color); + r = f->rops->find_register_color(dn->color); - ret = risc_overflow_reg2(r, dn, c, f); + ret = f->rops->overflow_reg2(r, dn, c, f); if (ret < 0) { scf_loge("\n"); return ret; @@ -4254,7 +4259,7 @@ static int _risc_inst_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4317,7 +4322,7 @@ static int _risc_inst_add_assign_dereference_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4397,7 +4402,7 @@ static int _risc_inst_sub_assign_dereference_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4470,7 +4475,7 @@ static int _risc_inst_and_assign_dereference_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4545,7 +4550,7 @@ static int _risc_inst_or_assign_dereference_handler(scf_native_t* ctx, scf_3ac_c if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4572,7 +4577,7 @@ static int _risc_inst_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* if (!c->srcs || c->srcs->size != 3) return -EINVAL; - scf_risc_context_t* risc = ctx->priv; + scf_risc_context_t* risc = ctx->priv; scf_function_t* f = risc->f; scf_3ac_operand_t* base = c->srcs->data[0]; @@ -4630,7 +4635,7 @@ static int _risc_inst_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4701,7 +4706,7 @@ static int _risc_inst_add_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4782,7 +4787,7 @@ static int _risc_inst_sub_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4864,7 +4869,7 @@ static int _risc_inst_and_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -4946,7 +4951,7 @@ static int _risc_inst_or_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, sib.size); + rs = f->rops->find_register_color_bytes(rs->color, sib.size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5035,7 +5040,7 @@ static int _risc_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, size); + rs = f->rops->find_register_color_bytes(rs->color, size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5117,7 +5122,7 @@ static int _risc_inst_add_assign_array_index_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, size); + rs = f->rops->find_register_color_bytes(rs->color, size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5216,7 +5221,7 @@ static int _risc_inst_sub_assign_array_index_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, size); + rs = f->rops->find_register_color_bytes(rs->color, size); } } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5312,7 +5317,7 @@ static int _risc_inst_and_assign_array_index_handler(scf_native_t* ctx, scf_3ac_ if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, size); + rs = f->rops->find_register_color_bytes(rs->color, size); } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5402,7 +5407,7 @@ static int _risc_inst_or_assign_array_index_handler(scf_native_t* ctx, scf_3ac_c if (ret < 0) return ret; - rs = risc_find_register_color_bytes(rs->color, size); + rs = f->rops->find_register_color_bytes(rs->color, size); } else RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); @@ -5459,7 +5464,7 @@ static int _risc_inst_dec_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* ret = risc_select_free_reg(&r, c, f, 0); if (ret < 0) return ret; - r = risc_find_register_color_bytes(r->color, size); + r = f->rops->find_register_color_bytes(r->color, size); ret = ctx->iops->P2G(c, f, r, sib.base, 0, size); if (ret < 0) @@ -5504,7 +5509,7 @@ static int _risc_inst_inc_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* ret = risc_select_free_reg(&r, c, f, 0); if (ret < 0) return ret; - r = risc_find_register_color_bytes(r->color, size); + r = f->rops->find_register_color_bytes(r->color, size); ret = ctx->iops->P2G(c, f, r, sib.base, 0, size); if (ret < 0) diff --git a/native/risc/scf_risc_rcg.c b/native/risc/scf_risc_rcg.c index 7ad3ced..23af842 100644 --- a/native/risc/scf_risc_rcg.c +++ b/native/risc/scf_risc_rcg.c @@ -274,13 +274,13 @@ static int _risc_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_t static int _risc_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - scf_risc_context_t* risc = ctx->priv; - scf_function_t* f = risc->f; - scf_dag_node_t* dn = NULL; - scf_register_t* r = NULL; - scf_3ac_operand_t* src = NULL; - scf_3ac_operand_t* dst = NULL; - scf_graph_node_t* gn = NULL; + scf_risc_context_t* risc = ctx->priv; + scf_function_t* f = risc->f; + scf_dag_node_t* dn = NULL; + scf_register_t* r = NULL; + scf_3ac_operand_t* src = NULL; + scf_3ac_operand_t* dst = NULL; + scf_graph_node_t* gn = NULL; int i; int ret; @@ -324,10 +324,10 @@ static int _risc_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) int size = risc_variable_size (dn->var); if (0 == i) - r = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size); + r = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size); else if (!is_float) - r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size); + r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size); else r = NULL; @@ -349,7 +349,7 @@ static int _risc_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) int nb_ints = 0; int nb_floats = 0; - risc_call_rabi(&nb_ints, &nb_floats, c); + risc_call_rabi(&nb_ints, &nb_floats, c, f); for (i = 1; i < c->srcs->size; i++) { src = c->srcs->data[i]; @@ -380,10 +380,10 @@ static int _risc_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) for (i = 0; i < nb_ints; i++) { - scf_register_t* rabi = NULL; + scf_register_t* rabi = NULL; scf_graph_node_t* gn_rabi = NULL; - rabi = risc_find_register_type_id_bytes(0, risc_abi_regs[i], dn_pf->var->size); + rabi = f->rops->find_register_type_id_bytes(0, risc_abi_regs[i], dn_pf->var->size); ret = _risc_rcg_make_node(&gn_rabi, g, NULL, rabi); if (ret < 0) { @@ -837,12 +837,13 @@ static int _risc_rcg_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf static int _risc_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int i; + scf_risc_context_t* risc = ctx->priv; + scf_function_t* f = risc->f; - scf_register_t* r; scf_3ac_operand_t* src; scf_graph_node_t* gn; scf_dag_node_t* dn; + scf_register_t* r; int ret = _risc_rcg_make2(c, NULL, NULL); if (ret < 0) @@ -855,12 +856,13 @@ static int _risc_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gr if (!c->srcs) return 0; + int i; for (i = 0; i < c->srcs->size; i++) { src = c->srcs->data[i]; dn = src->dag_node; int is_float = scf_variable_float(dn->var); - int size = risc_variable_size (dn->var); + int size = risc_variable_size(dn->var); size = size > 4 ? 8 : 4; @@ -870,9 +872,9 @@ static int _risc_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_gr return -1; } - r = risc_find_register_type_id_bytes(is_float, 0, size); + r = f->rops->find_register_type_id_bytes(is_float, 0, size); } else - r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size); + r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size); ret = _risc_rcg_make_node(&gn, g, dn, r); if (ret < 0) diff --git a/native/risc/scf_risc_reg.c b/native/risc/scf_risc_reg.c index 1f3c080..3b7d661 100644 --- a/native/risc/scf_risc_reg.c +++ b/native/risc/scf_risc_reg.c @@ -1,569 +1,5 @@ #include"scf_risc.h" -scf_register_t risc_registers[] = { - - {0, 4, "w0", RISC_COLOR(0, 0, 0xf), NULL, 0, 0}, - {0, 8, "x0", RISC_COLOR(0, 0, 0xff), NULL, 0, 0}, - - {1, 4, "w1", RISC_COLOR(0, 1, 0xf), NULL, 0, 0}, - {1, 8, "x1", RISC_COLOR(0, 1, 0xff), NULL, 0, 0}, - - {2, 4, "w2", RISC_COLOR(0, 2, 0xf), NULL, 0, 0}, - {2, 8, "x2", RISC_COLOR(0, 2, 0xff), NULL, 0, 0}, - - {3, 4, "w3", RISC_COLOR(0, 3, 0xf), NULL, 0, 0}, - {3, 8, "x3", RISC_COLOR(0, 3, 0xff), NULL, 0, 0}, - - {4, 4, "w4", RISC_COLOR(0, 4, 0xf), NULL, 0, 0}, - {4, 8, "x4", RISC_COLOR(0, 4, 0xff), NULL, 0, 0}, - - {5, 4, "w5", RISC_COLOR(0, 5, 0xf), NULL, 0, 0}, - {5, 8, "x5", RISC_COLOR(0, 5, 0xff), NULL, 0, 0}, - - {6, 4, "w6", RISC_COLOR(0, 6, 0xf), NULL, 0, 0}, - {6, 8, "x6", RISC_COLOR(0, 6, 0xff), NULL, 0, 0}, - - {7, 4, "w7", RISC_COLOR(0, 7, 0xf), NULL, 0, 0}, - {7, 8, "x7", RISC_COLOR(0, 7, 0xff), NULL, 0, 0}, - -// not use x8 - -// {8, 4, "w8", RISC_COLOR(0, 8, 0xf), NULL, 0}, -// {8, 8, "x8", RISC_COLOR(0, 8, 0xff), NULL, 0}, - - {9, 4, "w9", RISC_COLOR(0, 9, 0xf), NULL, 0, 0}, - {9, 8, "x9", RISC_COLOR(0, 9, 0xff), NULL, 0, 0}, - - {10, 4, "w10", RISC_COLOR(0, 10, 0xf), NULL, 0, 0}, - {10, 8, "x10", RISC_COLOR(0, 10, 0xff), NULL, 0, 0}, - - {11, 4, "w11", RISC_COLOR(0, 11, 0xf), NULL, 0, 0}, - {11, 8, "x11", RISC_COLOR(0, 11, 0xff), NULL, 0, 0}, - - {12, 4, "w12", RISC_COLOR(0, 12, 0xf), NULL, 0, 0}, - {12, 8, "x12", RISC_COLOR(0, 12, 0xff), NULL, 0, 0}, - - {13, 4, "w13", RISC_COLOR(0, 13, 0xf), NULL, 0, 0}, - {13, 8, "x13", RISC_COLOR(0, 13, 0xff), NULL, 0, 0}, - - {14, 4, "w14", RISC_COLOR(0, 14, 0xf), NULL, 0, 0}, - {14, 8, "x14", RISC_COLOR(0, 14, 0xff), NULL, 0, 0}, - - {15, 4, "w15", RISC_COLOR(0, 15, 0xf), NULL, 0, 0}, - {15, 8, "x15", RISC_COLOR(0, 15, 0xff), NULL, 0, 0}, - -// not use x16, x17, x18 - - {16, 4, "w16", RISC_COLOR(0, 16, 0xf), NULL, 0, 0}, - {16, 8, "x16", RISC_COLOR(0, 16, 0xff), NULL, 0, 0}, - - {17, 4, "w17", RISC_COLOR(0, 17, 0xf), NULL, 0, 0}, - {17, 8, "x17", RISC_COLOR(0, 17, 0xff), NULL, 0, 0}, - -// {18, 4, "w18", RISC_COLOR(0, 18, 0xf), NULL, 0, 0}, -// {18, 8, "x18", RISC_COLOR(0, 18, 0xff), NULL, 0, 0}, - - {19, 4, "w19", RISC_COLOR(0, 19, 0xf), NULL, 0, 0}, - {19, 8, "x19", RISC_COLOR(0, 19, 0xff), NULL, 0, 0}, - - {20, 4, "w20", RISC_COLOR(0, 20, 0xf), NULL, 0, 0}, - {20, 8, "x20", RISC_COLOR(0, 20, 0xff), NULL, 0, 0}, - - {21, 4, "w21", RISC_COLOR(0, 21, 0xf), NULL, 0, 0}, - {21, 8, "x21", RISC_COLOR(0, 21, 0xff), NULL, 0, 0}, - - {22, 4, "w22", RISC_COLOR(0, 22, 0xf), NULL, 0, 0}, - {22, 8, "x22", RISC_COLOR(0, 22, 0xff), NULL, 0, 0}, - - {23, 4, "w23", RISC_COLOR(0, 23, 0xf), NULL, 0, 0}, - {23, 8, "x23", RISC_COLOR(0, 23, 0xff), NULL, 0, 0}, - - {24, 4, "w24", RISC_COLOR(0, 24, 0xf), NULL, 0, 0}, - {24, 8, "x24", RISC_COLOR(0, 24, 0xff), NULL, 0, 0}, - - {25, 4, "w25", RISC_COLOR(0, 25, 0xf), NULL, 0, 0}, - {25, 8, "x25", RISC_COLOR(0, 25, 0xff), NULL, 0, 0}, - - {26, 4, "w26", RISC_COLOR(0, 26, 0xf), NULL, 0, 0}, - {26, 8, "x26", RISC_COLOR(0, 26, 0xff), NULL, 0, 0}, - - {27, 4, "w27", RISC_COLOR(0, 27, 0xf), NULL, 0, 0}, - {27, 8, "x27", RISC_COLOR(0, 27, 0xff), NULL, 0, 0}, - - {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0}, - {28, 8, "x28", RISC_COLOR(0, 28, 0xff), NULL, 0, 0}, - -// fp = x29 = bp - {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0}, - {29, 8, "fp", RISC_COLOR(0, 29, 0xff), NULL, 0, 0}, -// lr = x30 - {30, 4, "w30", RISC_COLOR(0, 30, 0xf), NULL, 0, 0}, - {30, 8, "lr", RISC_COLOR(0, 30, 0xff), NULL, 0, 0}, - {31, 8, "sp", RISC_COLOR(0, 31, 0xff), NULL, 0, 0}, - - - {0, 2, "h0", RISC_COLOR(1, 0, 0x3), NULL, 0, 0}, - {0, 4, "s0", RISC_COLOR(1, 0, 0xf), NULL, 0, 0}, - {0, 8, "d0", RISC_COLOR(1, 0, 0xff), NULL, 0, 0}, - - {1, 2, "h1", RISC_COLOR(1, 1, 0x3), NULL, 0, 0}, - {1, 4, "s1", RISC_COLOR(1, 1, 0xf), NULL, 0, 0}, - {1, 8, "d1", RISC_COLOR(1, 1, 0xff), NULL, 0, 0}, - - {2, 2, "h2", RISC_COLOR(1, 2, 0x3), NULL, 0, 0}, - {2, 4, "s2", RISC_COLOR(1, 2, 0xf), NULL, 0, 0}, - {2, 8, "d2", RISC_COLOR(1, 2, 0xff), NULL, 0, 0}, - - {3, 2, "h3", RISC_COLOR(1, 3, 0x3), NULL, 0, 0}, - {3, 4, "s3", RISC_COLOR(1, 3, 0xf), NULL, 0, 0}, - {3, 8, "d3", RISC_COLOR(1, 3, 0xff), NULL, 0, 0}, - - {4, 2, "h4", RISC_COLOR(1, 4, 0x3), NULL, 0, 0}, - {4, 4, "s4", RISC_COLOR(1, 4, 0xf), NULL, 0, 0}, - {4, 8, "d4", RISC_COLOR(1, 4, 0xff), NULL, 0, 0}, - - {5, 2, "h5", RISC_COLOR(1, 5, 0x3), NULL, 0, 0}, - {5, 4, "s5", RISC_COLOR(1, 5, 0xf), NULL, 0, 0}, - {5, 8, "d5", RISC_COLOR(1, 5, 0xff), NULL, 0, 0}, - - {6, 2, "h6", RISC_COLOR(1, 6, 0x3), NULL, 0, 0}, - {6, 4, "s6", RISC_COLOR(1, 6, 0xf), NULL, 0, 0}, - {6, 8, "d6", RISC_COLOR(1, 6, 0xff), NULL, 0, 0}, - - {7, 2, "h7", RISC_COLOR(1, 7, 0x3), NULL, 0, 0}, - {7, 4, "s7", RISC_COLOR(1, 7, 0xf), NULL, 0, 0}, - {7, 8, "d7", RISC_COLOR(1, 7, 0xff), NULL, 0, 0}, - - {8, 2, "h8", RISC_COLOR(1, 8, 0x3), NULL, 0, 0}, - {8, 4, "s8", RISC_COLOR(1, 8, 0xf), NULL, 0, 0}, - {8, 8, "d8", RISC_COLOR(1, 8, 0xff), NULL, 0, 0}, - - {9, 2, "h9", RISC_COLOR(1, 9, 0x3), NULL, 0, 0}, - {9, 4, "s9", RISC_COLOR(1, 9, 0xf), NULL, 0, 0}, - {9, 8, "d9", RISC_COLOR(1, 9, 0xff), NULL, 0, 0}, - - {10, 2, "h10", RISC_COLOR(1, 10, 0x3), NULL, 0, 0}, - {10, 4, "s10", RISC_COLOR(1, 10, 0xf), NULL, 0, 0}, - {10, 8, "d10", RISC_COLOR(1, 10, 0xff), NULL, 0, 0}, - - {11, 2, "h11", RISC_COLOR(1, 11, 0x3), NULL, 0, 0}, - {11, 4, "s11", RISC_COLOR(1, 11, 0xf), NULL, 0, 0}, - {11, 8, "d11", RISC_COLOR(1, 11, 0xff), NULL, 0, 0}, - - {12, 2, "h12", RISC_COLOR(1, 12, 0x3), NULL, 0, 0}, - {12, 4, "s12", RISC_COLOR(1, 12, 0xf), NULL, 0, 0}, - {12, 8, "d12", RISC_COLOR(1, 12, 0xff), NULL, 0, 0}, - - {13, 2, "h13", RISC_COLOR(1, 13, 0x3), NULL, 0, 0}, - {13, 4, "s13", RISC_COLOR(1, 13, 0xf), NULL, 0, 0}, - {13, 8, "d13", RISC_COLOR(1, 13, 0xff), NULL, 0, 0}, - - {14, 2, "h14", RISC_COLOR(1, 14, 0x3), NULL, 0, 0}, - {14, 4, "s14", RISC_COLOR(1, 14, 0xf), NULL, 0, 0}, - {14, 8, "d14", RISC_COLOR(1, 14, 0xff), NULL, 0, 0}, - - {15, 2, "h15", RISC_COLOR(1, 15, 0x3), NULL, 0, 0}, - {15, 4, "s15", RISC_COLOR(1, 15, 0xf), NULL, 0, 0}, - {15, 8, "d15", RISC_COLOR(1, 15, 0xff), NULL, 0, 0}, - - {16, 2, "h16", RISC_COLOR(1, 16, 0x3), NULL, 0, 0}, - {16, 4, "s16", RISC_COLOR(1, 16, 0xf), NULL, 0, 0}, - {16, 8, "d16", RISC_COLOR(1, 16, 0xff), NULL, 0, 0}, - - {17, 2, "h17", RISC_COLOR(1, 17, 0x3), NULL, 0, 0}, - {17, 4, "s17", RISC_COLOR(1, 17, 0xf), NULL, 0, 0}, - {17, 8, "d17", RISC_COLOR(1, 17, 0xff), NULL, 0, 0}, - - {18, 2, "h18", RISC_COLOR(1, 18, 0x3), NULL, 0, 0}, - {18, 4, "s18", RISC_COLOR(1, 18, 0xf), NULL, 0, 0}, - {18, 8, "d18", RISC_COLOR(1, 18, 0xff), NULL, 0, 0}, - - {19, 2, "h19", RISC_COLOR(1, 19, 0x3), NULL, 0, 0}, - {19, 4, "s19", RISC_COLOR(1, 19, 0xf), NULL, 0, 0}, - {19, 8, "d19", RISC_COLOR(1, 19, 0xff), NULL, 0, 0}, - - {20, 2, "h20", RISC_COLOR(1, 20, 0x3), NULL, 0, 0}, - {20, 4, "s20", RISC_COLOR(1, 20, 0xf), NULL, 0, 0}, - {20, 8, "d20", RISC_COLOR(1, 20, 0xff), NULL, 0, 0}, - - {21, 2, "h21", RISC_COLOR(1, 21, 0x3), NULL, 0, 0}, - {21, 4, "s21", RISC_COLOR(1, 21, 0xf), NULL, 0, 0}, - {21, 8, "d21", RISC_COLOR(1, 21, 0xff), NULL, 0, 0}, - - {22, 2, "h22", RISC_COLOR(1, 22, 0x3), NULL, 0, 0}, - {22, 4, "s22", RISC_COLOR(1, 22, 0xf), NULL, 0, 0}, - {22, 8, "d22", RISC_COLOR(1, 22, 0xff), NULL, 0, 0}, - - {23, 2, "h23", RISC_COLOR(1, 23, 0x3), NULL, 0, 0}, - {23, 4, "s23", RISC_COLOR(1, 23, 0xf), NULL, 0, 0}, - {23, 8, "d23", RISC_COLOR(1, 23, 0xff), NULL, 0, 0}, - - {24, 2, "h24", RISC_COLOR(1, 24, 0x3), NULL, 0, 0}, - {24, 4, "s24", RISC_COLOR(1, 24, 0xf), NULL, 0, 0}, - {24, 8, "d24", RISC_COLOR(1, 24, 0xff), NULL, 0, 0}, - - {25, 2, "h25", RISC_COLOR(1, 25, 0x3), NULL, 0, 0}, - {25, 4, "s25", RISC_COLOR(1, 25, 0xf), NULL, 0, 0}, - {25, 8, "d25", RISC_COLOR(1, 25, 0xff), NULL, 0, 0}, - - {26, 2, "h26", RISC_COLOR(1, 26, 0x3), NULL, 0, 0}, - {26, 4, "s26", RISC_COLOR(1, 26, 0xf), NULL, 0, 0}, - {26, 8, "d26", RISC_COLOR(1, 26, 0xff), NULL, 0, 0}, - - {27, 2, "h27", RISC_COLOR(1, 27, 0x3), NULL, 0, 0}, - {27, 4, "s27", RISC_COLOR(1, 27, 0xf), NULL, 0, 0}, - {27, 8, "d27", RISC_COLOR(1, 27, 0xff), NULL, 0, 0}, - - {28, 2, "h28", RISC_COLOR(1, 28, 0x3), NULL, 0, 0}, - {28, 4, "s28", RISC_COLOR(1, 28, 0xf), NULL, 0, 0}, - {28, 8, "d28", RISC_COLOR(1, 28, 0xff), NULL, 0, 0}, - - {29, 2, "h29", RISC_COLOR(1, 29, 0x3), NULL, 0, 0}, - {29, 4, "s29", RISC_COLOR(1, 29, 0xf), NULL, 0, 0}, - {29, 8, "d29", RISC_COLOR(1, 29, 0xff), NULL, 0, 0}, - - {30, 2, "h30", RISC_COLOR(1, 30, 0x3), NULL, 0, 0}, - {30, 4, "s30", RISC_COLOR(1, 30, 0xf), NULL, 0, 0}, - {30, 8, "d30", RISC_COLOR(1, 30, 0xff), NULL, 0, 0}, - - {31, 2, "h31", RISC_COLOR(1, 31, 0x3), NULL, 0, 0}, - {31, 4, "s31", RISC_COLOR(1, 31, 0xf), NULL, 0, 0}, - {31, 8, "d31", RISC_COLOR(1, 31, 0xff), NULL, 0, 0}, -}; - -int risc_reg_cached_vars(scf_register_t* r) -{ - int nb_vars = 0; - int i; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r2 = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r2->id - || SCF_RISC_REG_FP == r2->id - || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) - continue; - - if (!RISC_COLOR_CONFLICT(r->color, r2->color)) - continue; - - nb_vars += r2->dag_nodes->size; - } - - return nb_vars; -} - -int risc_registers_init() -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - assert(!r->dag_nodes); - - r->dag_nodes = scf_vector_alloc(); - if (!r->dag_nodes) - return -ENOMEM; - - r->used = 0; - } - - return 0; -} - -void risc_registers_clear() -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (r->dag_nodes) { - scf_vector_free(r->dag_nodes); - r->dag_nodes = NULL; - } - - r->used = 0; - } -} - -int risc_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs) -{ - int i; - int j; - scf_register_t* r; - scf_register_t* r2; - scf_instruction_t* inst; - scf_register_t* sp = risc_find_register("sp"); - - uint32_t opcode; - - int ret; - int size = 0; - int k = 0; - - for (j = 0; j < nb_regs; j++) { - r2 = risc_find_register_type_id_bytes(0, regs[j], 8); - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (0 == r->dag_nodes->size) - continue; - - if (RISC_COLOR_CONFLICT(r2->color, r->color)) - break; - } - - if (i == sizeof(risc_registers) / sizeof(risc_registers[0])) - continue; - - if (stack_size > 0) { - ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); - if (ret < 0) - return ret; - } else { - inst = f->iops->PUSH(NULL, r2); - RISC_INST_ADD_CHECK(c->instructions, inst); - } - - saved_regs[k++] = r2; - size += 8; - } - - if (size & 0xf) { - r2 = saved_regs[k - 1]; - - if (stack_size > 0) { - ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); - if (ret < 0) - return ret; - } else { - inst = f->iops->PUSH(NULL, r2); - RISC_INST_ADD_CHECK(c->instructions, inst); - } - - saved_regs[k++] = r2; - size += 8; - } - - if (stack_size > 0) { - for (j = 0; j < k / 2; j++) { - - i = k - 1 - j; - SCF_XCHG(saved_regs[i], saved_regs[j]); - } - } - - return size; -} - -int risc_pop_regs(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated) -{ - int i; - int j; - - scf_register_t* sp = risc_find_register("sp"); - scf_register_t* r; - scf_register_t* r2; - scf_instruction_t* inst; - - for (j = nb_regs - 1; j >= 0; j--) { - r2 = regs[j]; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (0 == r->dag_nodes->size) - continue; - - if (RISC_COLOR_CONFLICT(r2->color, r->color)) - break; - } - - if (i == sizeof(risc_registers) / sizeof(risc_registers[0])) - continue; - - for (i = 0; i < nb_updated; i++) { - - r = updated_regs[i]; - - if (RISC_COLOR_CONFLICT(r2->color, r->color)) - break; - } - - if (i == nb_updated) { - inst = f->iops->POP(c, r2); - RISC_INST_ADD_CHECK(c->instructions, inst); - } else { - inst = f->iops->ADD_IMM(c, sp, sp, 8); - RISC_INST_ADD_CHECK(c->instructions, inst); - } - } - return 0; -} - -int risc_registers_reset() -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (!r->dag_nodes) - continue; - - int j = 0; - while (j < r->dag_nodes->size) { - scf_dag_node_t* dn = r->dag_nodes->data[j]; - - if (dn->var->w) - scf_logw("drop: v_%d_%d/%s\n", dn->var->w->line, dn->var->w->pos, dn->var->w->text->data); - else - scf_logw("drop: v_%#lx\n", 0xffff & (uintptr_t)dn->var); - - int ret = scf_vector_del(r->dag_nodes, dn); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - - dn->loaded = 0; - dn->color = 0; - } - } - - return 0; -} - -scf_register_t* risc_find_register(const char* name) -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (!strcmp(r->name, name)) - return r; - } - return NULL; -} - -scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes) -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes) - return r; - } - return NULL; -} - -scf_register_t* risc_find_register_color(intptr_t color) -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (r->color == color) - return r; - } - return NULL; -} - -scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes) -{ - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (RISC_COLOR_CONFLICT(r->color, color) && r->bytes == bytes) - return r; - } - return NULL; -} - -scf_vector_t* risc_register_colors() -{ - scf_vector_t* colors = scf_vector_alloc(); - if (!colors) - return NULL; - - int i; - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - int ret = scf_vector_add(colors, (void*)r->color); - if (ret < 0) { - scf_vector_free(colors); - return NULL; - } - } -#if 0 - srand(time(NULL)); - for (i = 0; i < colors->size; i++) { - int j = rand() % colors->size; - - void* t = colors->data[i]; - colors->data[i] = colors->data[j]; - colors->data[j] = t; - } -#endif - return colors; -} - int risc_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) { scf_variable_t* v = dn->var; @@ -623,7 +59,7 @@ int risc_save_var(scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) if (dn->color <= 0) return -EINVAL; - scf_register_t* r = risc_find_register_color(dn->color); + scf_register_t* r = f->rops->find_register_color(dn->color); return risc_save_var2(dn, r, c, f); } @@ -645,315 +81,6 @@ int risc_save_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) return 0; } -int risc_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) -{ - int i; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r2 = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r2->id - || SCF_RISC_REG_FP == r2->id - || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) - continue; - - if (!RISC_COLOR_CONFLICT(r->color, r2->color)) - continue; - - int ret = risc_save_reg(r2, c, f); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - } - - r->used = 1; - return 0; -} - -int risc_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) -{ - scf_register_t* r2; - scf_dag_node_t* dn2; - - int i; - int j; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - r2 = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r2->id - || SCF_RISC_REG_FP == r2->id - || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) - continue; - - if (!RISC_COLOR_CONFLICT(r->color, r2->color)) - continue; - - for (j = 0; j < r2->dag_nodes->size; ) { - dn2 = r2->dag_nodes->data[j]; - - if (dn2 == dn) { - j++; - continue; - } - - int ret = risc_save_var(dn2, c, f); - if (ret < 0) - return ret; - } - } - - r->used = 1; - return 0; -} - -static int _risc_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) -{ - scf_register_t* r2; - scf_dn_status_t* ds2; - scf_dag_node_t* dn2; - - int i; - int j; - int ret; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - r2 = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r2->id - || SCF_RISC_REG_FP == r2->id - || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) - continue; - - if (!RISC_COLOR_CONFLICT(r->color, r2->color)) - continue; - - for (j = 0; j < r2->dag_nodes->size; ) { - dn2 = r2->dag_nodes->data[j]; - - if (dn2 == dn) { - j++; - continue; - } - - ds2 = scf_vector_find_cmp(c->active_vars, dn2, scf_dn_status_cmp); - if (!ds2) { - j++; - continue; - } - - if (!ds2->active) { - j++; - continue; - } -#if 1 - scf_variable_t* v = dn->var; - scf_variable_t* v2 = dn2->var; - if (v->w) - scf_loge("v_%d_%d/%s, bp_offset: %d\n", v->w->line, v->w->pos, v->w->text->data, v->bp_offset); - else - scf_loge("v_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v, v->bp_offset); - - if (v2->w) - scf_loge("v2_%d_%d/%s, bp_offset: %d\n", v2->w->line, v2->w->pos, v2->w->text->data, v2->bp_offset); - else - scf_loge("v2_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v2, v2->bp_offset); -#endif - int ret = risc_save_var(dn2, c, f); - if (ret < 0) - return ret; - } - } - - r->used = 1; - return 0; -} - -int risc_reg_used(scf_register_t* r, scf_dag_node_t* dn) -{ - scf_register_t* r2; - scf_dag_node_t* dn2; - - int i; - int j; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - r2 = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r2->id - || SCF_RISC_REG_FP == r2->id - || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) - continue; - - if (!RISC_COLOR_CONFLICT(r->color, r2->color)) - continue; - - for (j = 0; j < r2->dag_nodes->size; j++) { - dn2 = r2->dag_nodes->data[j]; - - if (dn2 != dn) - return 1; - } - } - return 0; -} - -static scf_register_t* _risc_reg_cached_min_vars(scf_register_t** regs, int nb_regs) -{ - scf_register_t* r_min = NULL; - - int min = 0; - int i; - - for (i = 0; i < nb_regs; i++) { - scf_register_t* r = regs[i]; - - int nb_vars = risc_reg_cached_vars(r); - - if (!r_min) { - r_min = r; - min = nb_vars; - continue; - } - - if (min > nb_vars) { - r_min = r; - min = nb_vars; - } - } - - return r_min; -} - -scf_register_t* risc_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float) -{ - scf_vector_t* neighbors = NULL; - scf_graph_node_t* gn = NULL; - - scf_register_t* free_regs[sizeof(risc_registers) / sizeof(risc_registers[0])]; - - int nb_free_regs = 0; - int bytes = 8; - int ret; - int i; - int j; - - assert(c->rcg); - - if (dn) { - is_float = scf_variable_float(dn->var); - bytes = risc_variable_size (dn->var); - } - - ret = risc_rcg_find_node(&gn, c->rcg, dn, NULL); - if (ret < 0) - neighbors = c->rcg->nodes; - else - neighbors = gn->neighbors; - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) - continue; - - for (j = 0; j < neighbors->size; j++) { - - scf_graph_node_t* neighbor = neighbors->data[j]; - risc_rcg_node_t* rn = neighbor->data; - - if (rn->dag_node) { - if (rn->dag_node->color <= 0) - continue; - - if (RISC_COLOR_CONFLICT(r->color, rn->dag_node->color)) - break; - } else { - assert(rn->reg); - - if (RISC_COLOR_CONFLICT(r->color, rn->reg->color)) - break; - } - } - - if (j == neighbors->size) - free_regs[nb_free_regs++] = r; - } - - if (nb_free_regs > 0) - return _risc_reg_cached_min_vars(free_regs, nb_free_regs); - - for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) { - - scf_register_t* r = &(risc_registers[i]); - - if (SCF_RISC_REG_SP == r->id - || SCF_RISC_REG_FP == r->id - || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) - continue; - - if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) - continue; - - if (c->dsts) { - scf_3ac_operand_t* dst; - - for (j = 0; j < c->dsts->size; j++) { - dst = c->dsts->data[j]; - - if (dst->dag_node && dst->dag_node->color > 0 - && RISC_COLOR_CONFLICT(r->color, dst->dag_node->color)) - break; - } - - if (j < c->dsts->size) - continue; - } - - if (c->srcs) { - scf_3ac_operand_t* src; - - for (j = 0; j < c->srcs->size; j++) { - src = c->srcs->data[j]; - - if (src->dag_node && src->dag_node->color > 0 - && RISC_COLOR_CONFLICT(r->color, src->dag_node->color)) - break; - } - - if (j < c->srcs->size) - continue; - } - - return r; - } - - return NULL; -} - int risc_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) { scf_instruction_t* inst; @@ -1085,29 +212,29 @@ int risc_select_reg(scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c int var_size = risc_variable_size(dn->var); if (dn->color > 0) { - r = risc_find_register_color(dn->color); + r = f->rops->find_register_color(dn->color); #if 1 - ret = _risc_overflow_reg3(r, dn, c, f); + ret = f->rops->overflow_reg3(r, dn, c, f); if (ret < 0) { scf_loge("\n"); return -1; } #endif } else { - r = risc_select_overflowed_reg(dn, c, is_float); + r = f->rops->select_overflowed_reg(dn, c, is_float); if (!r) { scf_loge("\n"); return -1; } - ret = risc_overflow_reg(r, c, f); + ret = f->rops->overflow_reg(r, c, f); if (ret < 0) { scf_loge("overflow reg failed\n"); return ret; } assert(0 == r->dag_nodes->size); - r = risc_find_register_type_id_bytes(is_float, r->id, var_size); + r = f->rops->find_register_type_id_bytes(is_float, r->id, var_size); assert(0 == r->dag_nodes->size); dn->color = r->color; @@ -1137,20 +264,20 @@ int risc_select_free_reg(scf_register_t** preg, scf_3ac_code_t* c, scf_function_ { scf_register_t* r; - r = risc_select_overflowed_reg(NULL, c, is_float); + r = f->rops->select_overflowed_reg(NULL, c, is_float); if (!r) { scf_loge("\n"); return -1; } - int ret = risc_overflow_reg(r, c, f); + int ret = f->rops->overflow_reg(r, c, f); if (ret < 0) { scf_loge("overflow reg failed\n"); return ret; } assert(0 == r->dag_nodes->size); - r = risc_find_register_type_id_bytes(0, r->id, 8); + r = f->rops->find_register_type_id_bytes(0, r->id, 8); assert(0 == r->dag_nodes->size); ret = risc_rcg_make(c, c->rcg, NULL, r); @@ -1209,7 +336,7 @@ int risc_pointer_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* membe } else if (vb->local_flag) { - rb = risc_find_register("fp"); + rb = f->rops->find_register("fp"); disp = vb->bp_offset; } else if (vb->global_flag) { @@ -1270,7 +397,7 @@ int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* i } } else if (vb->local_flag) { - rb = risc_find_register("fp"); + rb = f->rops->find_register("fp"); disp = vb->bp_offset; } else if (vb->global_flag) { @@ -1325,7 +452,7 @@ int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* i return ret; } - scf_register_t* ri2 = risc_find_register_color_bytes(ri->color, 8); + scf_register_t* ri2 = f->rops->find_register_color_bytes(ri->color, 8); if (ri->bytes < ri2->bytes) { @@ -1422,7 +549,7 @@ int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* i return 0; } -void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c) +void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f) { scf_3ac_operand_t* src = NULL; scf_dag_node_t* dn = NULL; @@ -1440,12 +567,12 @@ void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c) if (is_float) { if (nfloats < RISC_ABI_NB) - dn->rabi2 = risc_find_register_type_id_bytes(is_float, risc_abi_float_regs[nfloats++], size); + dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, risc_abi_float_regs[nfloats++], size); else dn->rabi2 = NULL; } else { if (nints < RISC_ABI_NB) - dn->rabi2 = risc_find_register_type_id_bytes(is_float, risc_abi_regs[nints++], size); + dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, risc_abi_regs[nints++], size); else dn->rabi2 = NULL; } diff --git a/native/risc/scf_risc_reg.h b/native/risc/scf_risc_reg.h index 5f3514c..4fea8c2 100644 --- a/native/risc/scf_risc_reg.h +++ b/native/risc/scf_risc_reg.h @@ -121,17 +121,17 @@ int risc_registers_reset(); void risc_registers_clear(); scf_vector_t* risc_register_colors(); -scf_register_t* risc_find_register(const char* name); +scf_register_t* risc_find_register(const char* name); -scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes); +scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes); -scf_register_t* risc_find_register_color(intptr_t color); +scf_register_t* risc_find_register_color(intptr_t color); -scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes); +scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes); -scf_register_t* risc_find_abi_register(int index, int bytes); +scf_register_t* risc_find_abi_register(int index, int bytes); -scf_register_t* risc_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float); +scf_register_t* risc_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float); int risc_reg_cached_vars(scf_register_t* r); @@ -151,6 +151,7 @@ int risc_reg_used (scf_register_t* r, scf_dag_node_t* dn); int risc_overflow_reg (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f); int risc_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f); +int risc_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f); int risc_select_reg(scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f, int load_flag); @@ -162,8 +163,7 @@ int risc_pointer_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_d int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* index, scf_dag_node_t* scale, scf_3ac_code_t* c, scf_function_t* f); -void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c); - +void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f); static inline int risc_inst_data_is_reg(scf_inst_data_t* id) { diff --git a/native/risc/scf_risc_reg_arm64.c b/native/risc/scf_risc_reg_arm64.c new file mode 100644 index 0000000..4560f4b --- /dev/null +++ b/native/risc/scf_risc_reg_arm64.c @@ -0,0 +1,928 @@ +#include"scf_risc.h" + +scf_register_t arm64_registers[] = { + + {0, 4, "w0", RISC_COLOR(0, 0, 0xf), NULL, 0, 0}, + {0, 8, "x0", RISC_COLOR(0, 0, 0xff), NULL, 0, 0}, + + {1, 4, "w1", RISC_COLOR(0, 1, 0xf), NULL, 0, 0}, + {1, 8, "x1", RISC_COLOR(0, 1, 0xff), NULL, 0, 0}, + + {2, 4, "w2", RISC_COLOR(0, 2, 0xf), NULL, 0, 0}, + {2, 8, "x2", RISC_COLOR(0, 2, 0xff), NULL, 0, 0}, + + {3, 4, "w3", RISC_COLOR(0, 3, 0xf), NULL, 0, 0}, + {3, 8, "x3", RISC_COLOR(0, 3, 0xff), NULL, 0, 0}, + + {4, 4, "w4", RISC_COLOR(0, 4, 0xf), NULL, 0, 0}, + {4, 8, "x4", RISC_COLOR(0, 4, 0xff), NULL, 0, 0}, + + {5, 4, "w5", RISC_COLOR(0, 5, 0xf), NULL, 0, 0}, + {5, 8, "x5", RISC_COLOR(0, 5, 0xff), NULL, 0, 0}, + + {6, 4, "w6", RISC_COLOR(0, 6, 0xf), NULL, 0, 0}, + {6, 8, "x6", RISC_COLOR(0, 6, 0xff), NULL, 0, 0}, + + {7, 4, "w7", RISC_COLOR(0, 7, 0xf), NULL, 0, 0}, + {7, 8, "x7", RISC_COLOR(0, 7, 0xff), NULL, 0, 0}, + +// not use x8 + +// {8, 4, "w8", RISC_COLOR(0, 8, 0xf), NULL, 0}, +// {8, 8, "x8", RISC_COLOR(0, 8, 0xff), NULL, 0}, + + {9, 4, "w9", RISC_COLOR(0, 9, 0xf), NULL, 0, 0}, + {9, 8, "x9", RISC_COLOR(0, 9, 0xff), NULL, 0, 0}, + + {10, 4, "w10", RISC_COLOR(0, 10, 0xf), NULL, 0, 0}, + {10, 8, "x10", RISC_COLOR(0, 10, 0xff), NULL, 0, 0}, + + {11, 4, "w11", RISC_COLOR(0, 11, 0xf), NULL, 0, 0}, + {11, 8, "x11", RISC_COLOR(0, 11, 0xff), NULL, 0, 0}, + + {12, 4, "w12", RISC_COLOR(0, 12, 0xf), NULL, 0, 0}, + {12, 8, "x12", RISC_COLOR(0, 12, 0xff), NULL, 0, 0}, + + {13, 4, "w13", RISC_COLOR(0, 13, 0xf), NULL, 0, 0}, + {13, 8, "x13", RISC_COLOR(0, 13, 0xff), NULL, 0, 0}, + + {14, 4, "w14", RISC_COLOR(0, 14, 0xf), NULL, 0, 0}, + {14, 8, "x14", RISC_COLOR(0, 14, 0xff), NULL, 0, 0}, + + {15, 4, "w15", RISC_COLOR(0, 15, 0xf), NULL, 0, 0}, + {15, 8, "x15", RISC_COLOR(0, 15, 0xff), NULL, 0, 0}, + +// not use x16, x17, x18 + + {16, 4, "w16", RISC_COLOR(0, 16, 0xf), NULL, 0, 0}, + {16, 8, "x16", RISC_COLOR(0, 16, 0xff), NULL, 0, 0}, + + {17, 4, "w17", RISC_COLOR(0, 17, 0xf), NULL, 0, 0}, + {17, 8, "x17", RISC_COLOR(0, 17, 0xff), NULL, 0, 0}, + +// {18, 4, "w18", RISC_COLOR(0, 18, 0xf), NULL, 0, 0}, +// {18, 8, "x18", RISC_COLOR(0, 18, 0xff), NULL, 0, 0}, + + {19, 4, "w19", RISC_COLOR(0, 19, 0xf), NULL, 0, 0}, + {19, 8, "x19", RISC_COLOR(0, 19, 0xff), NULL, 0, 0}, + + {20, 4, "w20", RISC_COLOR(0, 20, 0xf), NULL, 0, 0}, + {20, 8, "x20", RISC_COLOR(0, 20, 0xff), NULL, 0, 0}, + + {21, 4, "w21", RISC_COLOR(0, 21, 0xf), NULL, 0, 0}, + {21, 8, "x21", RISC_COLOR(0, 21, 0xff), NULL, 0, 0}, + + {22, 4, "w22", RISC_COLOR(0, 22, 0xf), NULL, 0, 0}, + {22, 8, "x22", RISC_COLOR(0, 22, 0xff), NULL, 0, 0}, + + {23, 4, "w23", RISC_COLOR(0, 23, 0xf), NULL, 0, 0}, + {23, 8, "x23", RISC_COLOR(0, 23, 0xff), NULL, 0, 0}, + + {24, 4, "w24", RISC_COLOR(0, 24, 0xf), NULL, 0, 0}, + {24, 8, "x24", RISC_COLOR(0, 24, 0xff), NULL, 0, 0}, + + {25, 4, "w25", RISC_COLOR(0, 25, 0xf), NULL, 0, 0}, + {25, 8, "x25", RISC_COLOR(0, 25, 0xff), NULL, 0, 0}, + + {26, 4, "w26", RISC_COLOR(0, 26, 0xf), NULL, 0, 0}, + {26, 8, "x26", RISC_COLOR(0, 26, 0xff), NULL, 0, 0}, + + {27, 4, "w27", RISC_COLOR(0, 27, 0xf), NULL, 0, 0}, + {27, 8, "x27", RISC_COLOR(0, 27, 0xff), NULL, 0, 0}, + + {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0}, + {28, 8, "x28", RISC_COLOR(0, 28, 0xff), NULL, 0, 0}, + +// fp = x29 = bp + {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0}, + {29, 8, "fp", RISC_COLOR(0, 29, 0xff), NULL, 0, 0}, +// lr = x30 + {30, 4, "w30", RISC_COLOR(0, 30, 0xf), NULL, 0, 0}, + {30, 8, "lr", RISC_COLOR(0, 30, 0xff), NULL, 0, 0}, + {31, 8, "sp", RISC_COLOR(0, 31, 0xff), NULL, 0, 0}, + + + {0, 2, "h0", RISC_COLOR(1, 0, 0x3), NULL, 0, 0}, + {0, 4, "s0", RISC_COLOR(1, 0, 0xf), NULL, 0, 0}, + {0, 8, "d0", RISC_COLOR(1, 0, 0xff), NULL, 0, 0}, + + {1, 2, "h1", RISC_COLOR(1, 1, 0x3), NULL, 0, 0}, + {1, 4, "s1", RISC_COLOR(1, 1, 0xf), NULL, 0, 0}, + {1, 8, "d1", RISC_COLOR(1, 1, 0xff), NULL, 0, 0}, + + {2, 2, "h2", RISC_COLOR(1, 2, 0x3), NULL, 0, 0}, + {2, 4, "s2", RISC_COLOR(1, 2, 0xf), NULL, 0, 0}, + {2, 8, "d2", RISC_COLOR(1, 2, 0xff), NULL, 0, 0}, + + {3, 2, "h3", RISC_COLOR(1, 3, 0x3), NULL, 0, 0}, + {3, 4, "s3", RISC_COLOR(1, 3, 0xf), NULL, 0, 0}, + {3, 8, "d3", RISC_COLOR(1, 3, 0xff), NULL, 0, 0}, + + {4, 2, "h4", RISC_COLOR(1, 4, 0x3), NULL, 0, 0}, + {4, 4, "s4", RISC_COLOR(1, 4, 0xf), NULL, 0, 0}, + {4, 8, "d4", RISC_COLOR(1, 4, 0xff), NULL, 0, 0}, + + {5, 2, "h5", RISC_COLOR(1, 5, 0x3), NULL, 0, 0}, + {5, 4, "s5", RISC_COLOR(1, 5, 0xf), NULL, 0, 0}, + {5, 8, "d5", RISC_COLOR(1, 5, 0xff), NULL, 0, 0}, + + {6, 2, "h6", RISC_COLOR(1, 6, 0x3), NULL, 0, 0}, + {6, 4, "s6", RISC_COLOR(1, 6, 0xf), NULL, 0, 0}, + {6, 8, "d6", RISC_COLOR(1, 6, 0xff), NULL, 0, 0}, + + {7, 2, "h7", RISC_COLOR(1, 7, 0x3), NULL, 0, 0}, + {7, 4, "s7", RISC_COLOR(1, 7, 0xf), NULL, 0, 0}, + {7, 8, "d7", RISC_COLOR(1, 7, 0xff), NULL, 0, 0}, + + {8, 2, "h8", RISC_COLOR(1, 8, 0x3), NULL, 0, 0}, + {8, 4, "s8", RISC_COLOR(1, 8, 0xf), NULL, 0, 0}, + {8, 8, "d8", RISC_COLOR(1, 8, 0xff), NULL, 0, 0}, + + {9, 2, "h9", RISC_COLOR(1, 9, 0x3), NULL, 0, 0}, + {9, 4, "s9", RISC_COLOR(1, 9, 0xf), NULL, 0, 0}, + {9, 8, "d9", RISC_COLOR(1, 9, 0xff), NULL, 0, 0}, + + {10, 2, "h10", RISC_COLOR(1, 10, 0x3), NULL, 0, 0}, + {10, 4, "s10", RISC_COLOR(1, 10, 0xf), NULL, 0, 0}, + {10, 8, "d10", RISC_COLOR(1, 10, 0xff), NULL, 0, 0}, + + {11, 2, "h11", RISC_COLOR(1, 11, 0x3), NULL, 0, 0}, + {11, 4, "s11", RISC_COLOR(1, 11, 0xf), NULL, 0, 0}, + {11, 8, "d11", RISC_COLOR(1, 11, 0xff), NULL, 0, 0}, + + {12, 2, "h12", RISC_COLOR(1, 12, 0x3), NULL, 0, 0}, + {12, 4, "s12", RISC_COLOR(1, 12, 0xf), NULL, 0, 0}, + {12, 8, "d12", RISC_COLOR(1, 12, 0xff), NULL, 0, 0}, + + {13, 2, "h13", RISC_COLOR(1, 13, 0x3), NULL, 0, 0}, + {13, 4, "s13", RISC_COLOR(1, 13, 0xf), NULL, 0, 0}, + {13, 8, "d13", RISC_COLOR(1, 13, 0xff), NULL, 0, 0}, + + {14, 2, "h14", RISC_COLOR(1, 14, 0x3), NULL, 0, 0}, + {14, 4, "s14", RISC_COLOR(1, 14, 0xf), NULL, 0, 0}, + {14, 8, "d14", RISC_COLOR(1, 14, 0xff), NULL, 0, 0}, + + {15, 2, "h15", RISC_COLOR(1, 15, 0x3), NULL, 0, 0}, + {15, 4, "s15", RISC_COLOR(1, 15, 0xf), NULL, 0, 0}, + {15, 8, "d15", RISC_COLOR(1, 15, 0xff), NULL, 0, 0}, + + {16, 2, "h16", RISC_COLOR(1, 16, 0x3), NULL, 0, 0}, + {16, 4, "s16", RISC_COLOR(1, 16, 0xf), NULL, 0, 0}, + {16, 8, "d16", RISC_COLOR(1, 16, 0xff), NULL, 0, 0}, + + {17, 2, "h17", RISC_COLOR(1, 17, 0x3), NULL, 0, 0}, + {17, 4, "s17", RISC_COLOR(1, 17, 0xf), NULL, 0, 0}, + {17, 8, "d17", RISC_COLOR(1, 17, 0xff), NULL, 0, 0}, + + {18, 2, "h18", RISC_COLOR(1, 18, 0x3), NULL, 0, 0}, + {18, 4, "s18", RISC_COLOR(1, 18, 0xf), NULL, 0, 0}, + {18, 8, "d18", RISC_COLOR(1, 18, 0xff), NULL, 0, 0}, + + {19, 2, "h19", RISC_COLOR(1, 19, 0x3), NULL, 0, 0}, + {19, 4, "s19", RISC_COLOR(1, 19, 0xf), NULL, 0, 0}, + {19, 8, "d19", RISC_COLOR(1, 19, 0xff), NULL, 0, 0}, + + {20, 2, "h20", RISC_COLOR(1, 20, 0x3), NULL, 0, 0}, + {20, 4, "s20", RISC_COLOR(1, 20, 0xf), NULL, 0, 0}, + {20, 8, "d20", RISC_COLOR(1, 20, 0xff), NULL, 0, 0}, + + {21, 2, "h21", RISC_COLOR(1, 21, 0x3), NULL, 0, 0}, + {21, 4, "s21", RISC_COLOR(1, 21, 0xf), NULL, 0, 0}, + {21, 8, "d21", RISC_COLOR(1, 21, 0xff), NULL, 0, 0}, + + {22, 2, "h22", RISC_COLOR(1, 22, 0x3), NULL, 0, 0}, + {22, 4, "s22", RISC_COLOR(1, 22, 0xf), NULL, 0, 0}, + {22, 8, "d22", RISC_COLOR(1, 22, 0xff), NULL, 0, 0}, + + {23, 2, "h23", RISC_COLOR(1, 23, 0x3), NULL, 0, 0}, + {23, 4, "s23", RISC_COLOR(1, 23, 0xf), NULL, 0, 0}, + {23, 8, "d23", RISC_COLOR(1, 23, 0xff), NULL, 0, 0}, + + {24, 2, "h24", RISC_COLOR(1, 24, 0x3), NULL, 0, 0}, + {24, 4, "s24", RISC_COLOR(1, 24, 0xf), NULL, 0, 0}, + {24, 8, "d24", RISC_COLOR(1, 24, 0xff), NULL, 0, 0}, + + {25, 2, "h25", RISC_COLOR(1, 25, 0x3), NULL, 0, 0}, + {25, 4, "s25", RISC_COLOR(1, 25, 0xf), NULL, 0, 0}, + {25, 8, "d25", RISC_COLOR(1, 25, 0xff), NULL, 0, 0}, + + {26, 2, "h26", RISC_COLOR(1, 26, 0x3), NULL, 0, 0}, + {26, 4, "s26", RISC_COLOR(1, 26, 0xf), NULL, 0, 0}, + {26, 8, "d26", RISC_COLOR(1, 26, 0xff), NULL, 0, 0}, + + {27, 2, "h27", RISC_COLOR(1, 27, 0x3), NULL, 0, 0}, + {27, 4, "s27", RISC_COLOR(1, 27, 0xf), NULL, 0, 0}, + {27, 8, "d27", RISC_COLOR(1, 27, 0xff), NULL, 0, 0}, + + {28, 2, "h28", RISC_COLOR(1, 28, 0x3), NULL, 0, 0}, + {28, 4, "s28", RISC_COLOR(1, 28, 0xf), NULL, 0, 0}, + {28, 8, "d28", RISC_COLOR(1, 28, 0xff), NULL, 0, 0}, + + {29, 2, "h29", RISC_COLOR(1, 29, 0x3), NULL, 0, 0}, + {29, 4, "s29", RISC_COLOR(1, 29, 0xf), NULL, 0, 0}, + {29, 8, "d29", RISC_COLOR(1, 29, 0xff), NULL, 0, 0}, + + {30, 2, "h30", RISC_COLOR(1, 30, 0x3), NULL, 0, 0}, + {30, 4, "s30", RISC_COLOR(1, 30, 0xf), NULL, 0, 0}, + {30, 8, "d30", RISC_COLOR(1, 30, 0xff), NULL, 0, 0}, + + {31, 2, "h31", RISC_COLOR(1, 31, 0x3), NULL, 0, 0}, + {31, 4, "s31", RISC_COLOR(1, 31, 0xf), NULL, 0, 0}, + {31, 8, "d31", RISC_COLOR(1, 31, 0xff), NULL, 0, 0}, +}; + +scf_register_t* arm64_find_register(const char* name) +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (!strcmp(r->name, name)) + return r; + } + return NULL; +} + +scf_register_t* arm64_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes) +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes) + return r; + } + return NULL; +} + +scf_register_t* arm64_find_register_color(intptr_t color) +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (r->color == color) + return r; + } + return NULL; +} + +scf_register_t* arm64_find_register_color_bytes(intptr_t color, int bytes) +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (RISC_COLOR_CONFLICT(r->color, color) && r->bytes == bytes) + return r; + } + return NULL; +} + +scf_vector_t* arm64_register_colors() +{ + scf_vector_t* colors = scf_vector_alloc(); + if (!colors) + return NULL; + + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + int ret = scf_vector_add(colors, (void*)r->color); + if (ret < 0) { + scf_vector_free(colors); + return NULL; + } + } +#if 0 + srand(time(NULL)); + for (i = 0; i < colors->size; i++) { + int j = rand() % colors->size; + + void* t = colors->data[i]; + colors->data[i] = colors->data[j]; + colors->data[j] = t; + } +#endif + return colors; +} + +int arm64_reg_cached_vars(scf_register_t* r) +{ + int nb_vars = 0; + int i; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r2 = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!RISC_COLOR_CONFLICT(r->color, r2->color)) + continue; + + nb_vars += r2->dag_nodes->size; + } + + return nb_vars; +} + +int arm64_registers_init() +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + assert(!r->dag_nodes); + + r->dag_nodes = scf_vector_alloc(); + if (!r->dag_nodes) + return -ENOMEM; + + r->used = 0; + } + + return 0; +} + +void arm64_registers_clear() +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->dag_nodes) { + scf_vector_free(r->dag_nodes); + r->dag_nodes = NULL; + } + + r->used = 0; + } +} + +scf_register_t* risc_reg_cached_min_vars(scf_register_t** regs, int nb_regs) +{ + scf_register_t* r_min = NULL; + + int min = 0; + int i; + + for (i = 0; i < nb_regs; i++) { + scf_register_t* r = regs[i]; + + int nb_vars = arm64_reg_cached_vars(r); + + if (!r_min) { + r_min = r; + min = nb_vars; + continue; + } + + if (min > nb_vars) { + r_min = r; + min = nb_vars; + } + } + + return r_min; +} + +int arm64_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs) +{ + int i; + int j; + scf_register_t* r; + scf_register_t* r2; + scf_instruction_t* inst; + scf_register_t* sp = arm64_find_register("sp"); + + uint32_t opcode; + + int ret; + int size = 0; + int k = 0; + + for (j = 0; j < nb_regs; j++) { + r2 = arm64_find_register_type_id_bytes(0, regs[j], 8); + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (0 == r->dag_nodes->size) + continue; + + if (RISC_COLOR_CONFLICT(r2->color, r->color)) + break; + } + + if (i == sizeof(arm64_registers) / sizeof(arm64_registers[0])) + continue; + + if (stack_size > 0) { + ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); + if (ret < 0) + return ret; + } else { + inst = f->iops->PUSH(NULL, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + + saved_regs[k++] = r2; + size += 8; + } + + if (size & 0xf) { + r2 = saved_regs[k - 1]; + + if (stack_size > 0) { + ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); + if (ret < 0) + return ret; + } else { + inst = f->iops->PUSH(NULL, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + + saved_regs[k++] = r2; + size += 8; + } + + if (stack_size > 0) { + for (j = 0; j < k / 2; j++) { + + i = k - 1 - j; + SCF_XCHG(saved_regs[i], saved_regs[j]); + } + } + + return size; +} + +int arm64_pop_regs(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated) +{ + int i; + int j; + + scf_register_t* sp = arm64_find_register("sp"); + scf_register_t* r; + scf_register_t* r2; + scf_instruction_t* inst; + + for (j = nb_regs - 1; j >= 0; j--) { + r2 = regs[j]; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (0 == r->dag_nodes->size) + continue; + + if (RISC_COLOR_CONFLICT(r2->color, r->color)) + break; + } + + if (i == sizeof(arm64_registers) / sizeof(arm64_registers[0])) + continue; + + for (i = 0; i < nb_updated; i++) { + + r = updated_regs[i]; + + if (RISC_COLOR_CONFLICT(r2->color, r->color)) + break; + } + + if (i == nb_updated) { + inst = f->iops->POP(c, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } else { + inst = f->iops->ADD_IMM(c, sp, sp, 8); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + } + return 0; +} + +int arm64_registers_reset() +{ + int i; + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (!r->dag_nodes) + continue; + + int j = 0; + while (j < r->dag_nodes->size) { + scf_dag_node_t* dn = r->dag_nodes->data[j]; + + if (dn->var->w) + scf_logw("drop: v_%d_%d/%s\n", dn->var->w->line, dn->var->w->pos, dn->var->w->text->data); + else + scf_logw("drop: v_%#lx\n", 0xffff & (uintptr_t)dn->var); + + int ret = scf_vector_del(r->dag_nodes, dn); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + + dn->loaded = 0; + dn->color = 0; + } + } + + return 0; +} + + +int arm64_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) +{ + int i; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r2 = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!RISC_COLOR_CONFLICT(r->color, r2->color)) + continue; + + int ret = risc_save_reg(r2, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } + + r->used = 1; + return 0; +} + +int arm64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) +{ + scf_register_t* r2; + scf_dag_node_t* dn2; + + int i; + int j; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + r2 = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!RISC_COLOR_CONFLICT(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; ) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 == dn) { + j++; + continue; + } + + int ret = risc_save_var(dn2, c, f); + if (ret < 0) + return ret; + } + } + + r->used = 1; + return 0; +} + +int arm64_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) +{ + scf_register_t* r2; + scf_dn_status_t* ds2; + scf_dag_node_t* dn2; + + int i; + int j; + int ret; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + r2 = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!RISC_COLOR_CONFLICT(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; ) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 == dn) { + j++; + continue; + } + + ds2 = scf_vector_find_cmp(c->active_vars, dn2, scf_dn_status_cmp); + if (!ds2) { + j++; + continue; + } + + if (!ds2->active) { + j++; + continue; + } +#if 1 + scf_variable_t* v = dn->var; + scf_variable_t* v2 = dn2->var; + if (v->w) + scf_loge("v_%d_%d/%s, bp_offset: %d\n", v->w->line, v->w->pos, v->w->text->data, v->bp_offset); + else + scf_loge("v_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v, v->bp_offset); + + if (v2->w) + scf_loge("v2_%d_%d/%s, bp_offset: %d\n", v2->w->line, v2->w->pos, v2->w->text->data, v2->bp_offset); + else + scf_loge("v2_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v2, v2->bp_offset); +#endif + int ret = risc_save_var(dn2, c, f); + if (ret < 0) + return ret; + } + } + + r->used = 1; + return 0; +} + +int arm64_reg_used(scf_register_t* r, scf_dag_node_t* dn) +{ + scf_register_t* r2; + scf_dag_node_t* dn2; + + int i; + int j; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + r2 = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!RISC_COLOR_CONFLICT(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; j++) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 != dn) + return 1; + } + } + return 0; +} + +scf_register_t* arm64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float) +{ + scf_vector_t* neighbors = NULL; + scf_graph_node_t* gn = NULL; + + scf_register_t* free_regs[sizeof(arm64_registers) / sizeof(arm64_registers[0])]; + + int nb_free_regs = 0; + int bytes = 8; + int ret; + int i; + int j; + + assert(c->rcg); + + if (dn) { + is_float = scf_variable_float(dn->var); + bytes = risc_variable_size (dn->var); + } + + ret = risc_rcg_find_node(&gn, c->rcg, dn, NULL); + if (ret < 0) + neighbors = c->rcg->nodes; + else + neighbors = gn->neighbors; + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) + continue; + + for (j = 0; j < neighbors->size; j++) { + + scf_graph_node_t* neighbor = neighbors->data[j]; + risc_rcg_node_t* rn = neighbor->data; + + if (rn->dag_node) { + if (rn->dag_node->color <= 0) + continue; + + if (RISC_COLOR_CONFLICT(r->color, rn->dag_node->color)) + break; + } else { + assert(rn->reg); + + if (RISC_COLOR_CONFLICT(r->color, rn->reg->color)) + break; + } + } + + if (j == neighbors->size) + free_regs[nb_free_regs++] = r; + } + + if (nb_free_regs > 0) + return risc_reg_cached_min_vars(free_regs, nb_free_regs); + + for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) { + + scf_register_t* r = &(arm64_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) + continue; + + if (c->dsts) { + scf_3ac_operand_t* dst; + + for (j = 0; j < c->dsts->size; j++) { + dst = c->dsts->data[j]; + + if (dst->dag_node && dst->dag_node->color > 0 + && RISC_COLOR_CONFLICT(r->color, dst->dag_node->color)) + break; + } + + if (j < c->dsts->size) + continue; + } + + if (c->srcs) { + scf_3ac_operand_t* src; + + for (j = 0; j < c->srcs->size; j++) { + src = c->srcs->data[j]; + + if (src->dag_node && src->dag_node->color > 0 + && RISC_COLOR_CONFLICT(r->color, src->dag_node->color)) + break; + } + + if (j < c->srcs->size) + continue; + } + + return r; + } + + return NULL; +} + +scf_regs_ops_t regs_ops_arm64 = +{ + .name = "arm64", + + .registers_init = arm64_registers_init, + .registers_reset = arm64_registers_reset, + .registers_clear = arm64_registers_clear, + .register_colors = arm64_register_colors, + + .reg_used = arm64_reg_used, + .reg_cached_vars = arm64_reg_cached_vars, + + .caller_save_regs = arm64_caller_save_regs, + .pop_regs = arm64_pop_regs, + + .find_register = arm64_find_register, + .find_register_color = arm64_find_register_color, + .find_register_color_bytes = arm64_find_register_color_bytes, + .find_register_type_id_bytes = arm64_find_register_type_id_bytes, + + .select_overflowed_reg = arm64_select_overflowed_reg, + .overflow_reg = arm64_overflow_reg, + .overflow_reg2 = arm64_overflow_reg2, + .overflow_reg3 = arm64_overflow_reg3, +}; + +scf_regs_ops_t regs_ops_naja = +{ + .name = "naja", + + .registers_init = arm64_registers_init, + .registers_reset = arm64_registers_reset, + .registers_clear = arm64_registers_clear, + .register_colors = arm64_register_colors, + + .reg_used = arm64_reg_used, + .reg_cached_vars = arm64_reg_cached_vars, + + .caller_save_regs = arm64_caller_save_regs, + .pop_regs = arm64_pop_regs, + + .find_register = arm64_find_register, + .find_register_color = arm64_find_register_color, + .find_register_color_bytes = arm64_find_register_color_bytes, + .find_register_type_id_bytes = arm64_find_register_type_id_bytes, + + .select_overflowed_reg = arm64_select_overflowed_reg, + .overflow_reg = arm64_overflow_reg, + .overflow_reg2 = arm64_overflow_reg2, + .overflow_reg3 = arm64_overflow_reg3, +}; + diff --git a/native/scf_native.h b/native/scf_native.h index 9124750..e5b0b66 100644 --- a/native/scf_native.h +++ b/native/scf_native.h @@ -79,6 +79,7 @@ typedef struct { scf_native_ops_t* ops; scf_inst_ops_t* iops; + scf_regs_ops_t* rops; void* priv; @@ -94,6 +95,33 @@ struct scf_native_ops_s int (*select_inst)(scf_native_t* ctx, scf_function_t* f); }; +struct scf_regs_ops_s +{ + const char* name; + + int (*registers_init )(); + int (*registers_reset )(); + void (*registers_clear )(); + scf_vector_t* (*register_colors )(); + + int (*reg_used )(scf_register_t* r, scf_dag_node_t* dn); + int (*reg_cached_vars )(scf_register_t* r); + + int (*caller_save_regs)(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs); + int (*pop_regs )(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated); + + scf_register_t* (*find_register )(const char* name); + scf_register_t* (*find_register_color )(intptr_t color); + scf_register_t* (*find_register_color_bytes )(intptr_t color, int bytes); + scf_register_t* (*find_register_type_id_bytes)(uint32_t type, uint32_t id, int bytes); + + scf_register_t* (*select_overflowed_reg )(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float); + + int (*overflow_reg )(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f); + int (*overflow_reg2)(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f); + int (*overflow_reg3)(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f); +}; + struct scf_inst_ops_s { const char* name; diff --git a/parse/Makefile b/parse/Makefile index 10395df..f6faa4c 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -36,6 +36,7 @@ CFILES += ../native/risc/scf_risc_inst.c CFILES += ../native/risc/scf_risc_opcode.c CFILES += ../native/risc/scf_risc_rcg.c CFILES += ../native/risc/scf_risc_reg.c +CFILES += ../native/risc/scf_risc_reg_arm64.c CFILES += ../native/risc/scf_arm64.c CFILES += ../native/risc/scf_naja.c diff --git a/vm/scf_vm.h b/vm/scf_vm.h index da0b7dc..85031ef 100644 --- a/vm/scf_vm.h +++ b/vm/scf_vm.h @@ -4,7 +4,7 @@ #include"scf_elf.h" #include -#if 1 +#if 0 #define NAJA_PRINTF printf #else #define NAJA_PRINTF