From 2ca8f975506ebabbd75df251931d4cceb048e4b4 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Wed, 1 Mar 2023 20:26:56 +0800 Subject: [PATCH] support ARM64: float / double instructions --- core/scf_operator_dag.c | 38 +- native/arm64/scf_arm64.c | 27 +- native/arm64/scf_arm64.h | 9 +- native/arm64/scf_arm64_inst.c | 3662 ++++++++++++++++++++++++--------- native/arm64/scf_arm64_rcg.c | 221 +- native/arm64/scf_arm64_reg.c | 367 ++-- native/arm64/scf_arm64_reg.h | 6 +- native/arm64/scf_arm64_util.c | 250 ++- 8 files changed, 3291 insertions(+), 1289 deletions(-) diff --git a/core/scf_operator_dag.c b/core/scf_operator_dag.c index def6838..786a15b 100644 --- a/core/scf_operator_dag.c +++ b/core/scf_operator_dag.c @@ -294,11 +294,19 @@ SCF_DAG_ASSIGN_DEREFERENCE(or_assign, OR_ASSIGN); SCF_DAG_ASSIGN_DEREFERENCE(inc, INC); SCF_DAG_ASSIGN_DEREFERENCE(dec, DEC); -static int _scf_dag_op_assign_array_index(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) -{ - assert(4 == nb_nodes); - return _scf_3ac_code_N(h, SCF_OP_3AC_ASSIGN_ARRAY_INDEX, NULL, nodes, nb_nodes); +#define SCF_DAG_ASSIGN_ARRAY_INDEX(name, op) \ +static int _scf_dag_op_##name##_array_index(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) \ +{ \ + assert(4 == nb_nodes); \ + return _scf_3ac_code_N(h, SCF_OP_3AC_##op##_ARRAY_INDEX, NULL, nodes, nb_nodes); \ } +SCF_DAG_ASSIGN_ARRAY_INDEX(assign, ASSIGN); +SCF_DAG_ASSIGN_ARRAY_INDEX(add_assign, ADD_ASSIGN); +SCF_DAG_ASSIGN_ARRAY_INDEX(sub_assign, SUB_ASSIGN); +SCF_DAG_ASSIGN_ARRAY_INDEX(and_assign, AND_ASSIGN); +SCF_DAG_ASSIGN_ARRAY_INDEX(or_assign, OR_ASSIGN); +SCF_DAG_ASSIGN_ARRAY_INDEX(inc, INC); +SCF_DAG_ASSIGN_ARRAY_INDEX(dec, DEC); #define SCF_DAG_ASSIGN_POINTER(name, op) \ static int _scf_dag_op_##name##_pointer(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) \ @@ -310,6 +318,8 @@ SCF_DAG_ASSIGN_POINTER(add_assign, ADD_ASSIGN); SCF_DAG_ASSIGN_POINTER(sub_assign, SUB_ASSIGN); SCF_DAG_ASSIGN_POINTER(and_assign, AND_ASSIGN); SCF_DAG_ASSIGN_POINTER(or_assign, OR_ASSIGN); +SCF_DAG_ASSIGN_POINTER(inc, INC); +SCF_DAG_ASSIGN_POINTER(dec, DEC); static int _scf_dag_op_return(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) { @@ -410,13 +420,19 @@ scf_dag_operator_t dag_operators[] = {SCF_OP_AND_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign}, {SCF_OP_OR_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign}, - {SCF_OP_3AC_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_array_index}, - - {SCF_OP_3AC_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_pointer}, - {SCF_OP_3AC_ADD_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_add_assign_pointer}, - {SCF_OP_3AC_SUB_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_sub_assign_pointer}, - {SCF_OP_3AC_AND_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign_pointer}, - {SCF_OP_3AC_OR_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign_pointer}, + {SCF_OP_3AC_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_array_index}, + {SCF_OP_3AC_ADD_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_add_assign_array_index}, + {SCF_OP_3AC_SUB_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_sub_assign_array_index}, + {SCF_OP_3AC_AND_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign_array_index}, + {SCF_OP_3AC_OR_ASSIGN_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign_array_index}, + {SCF_OP_3AC_INC_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_inc_array_index}, + {SCF_OP_3AC_DEC_ARRAY_INDEX, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_dec_array_index}, + + {SCF_OP_3AC_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_pointer}, + {SCF_OP_3AC_ADD_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_add_assign_pointer}, + {SCF_OP_3AC_SUB_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_sub_assign_pointer}, + {SCF_OP_3AC_AND_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign_pointer}, + {SCF_OP_3AC_OR_ASSIGN_POINTER, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign_pointer}, {SCF_OP_3AC_ASSIGN_DEREFERENCE, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_assign_dereference}, {SCF_OP_3AC_ADD_ASSIGN_DEREFERENCE, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_add_assign_dereference}, diff --git a/native/arm64/scf_arm64.c b/native/arm64/scf_arm64.c index 0b28292..5fcb403 100644 --- a/native/arm64/scf_arm64.c +++ b/native/arm64/scf_arm64.c @@ -244,6 +244,13 @@ static int _arm64_function_finish(scf_function_t* f) r = arm64_find_register_type_id_bytes(0, arm64_abi_callee_saves[i], 8); + if (!r->used) { + r = arm64_find_register_type_id_bytes(0, arm64_abi_callee_saves[i], 4); + + if (!r->used) + continue; + } + opcode = (0xf8 << 24) | (0x1f8 << 12) | (0x3 << 10) | (sp->id << 5) | r->id; inst = arm64_make_inst(NULL, opcode); ARM64_INST_ADD_CHECK(f->init_insts, inst); @@ -341,7 +348,7 @@ static int _arm64_argv_prepare(scf_graph_t* g, scf_basic_block_t* bb, scf_functi if (l == scf_list_sentinel(&f->dag_list_head)) continue; - int ret = _arm64_rcg_make_node(&gn, g, dn, v->rabi, NULL); + int ret = _arm64_rcg_make_node(&gn, g, dn, v->rabi); if (ret < 0) return ret; @@ -959,10 +966,11 @@ static void _arm64_set_offsets(scf_function_t* f) int _scf_arm64_select_inst(scf_native_t* ctx) { - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_basic_block_t* bb; - scf_bb_group_t* bbg; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_basic_block_t* bb; + scf_basic_block_t* end; + scf_bb_group_t* bbg; int i; int ret = 0; @@ -976,6 +984,11 @@ int _scf_arm64_select_inst(scf_native_t* ctx) if (bb->group_flag || bb->loop_flag) continue; + if (bb->end_flag) { + end = bb; + continue; + } + ret = _arm64_select_bb_regs(bb, ctx); if (ret < 0) return ret; @@ -1091,6 +1104,10 @@ int _scf_arm64_select_inst(scf_native_t* ctx) return ret; } } + + ret = _arm64_make_insts_for_list(ctx, end, 0); + if (ret < 0) + return ret; #if 0 if (arm64_optimize_peephole(ctx, f) < 0) { scf_loge("\n"); diff --git a/native/arm64/scf_arm64.h b/native/arm64/scf_arm64.h index ec6eb1f..159baa0 100644 --- a/native/arm64/scf_arm64.h +++ b/native/arm64/scf_arm64.h @@ -73,8 +73,8 @@ typedef struct { arm64_rcg_handler_t* scf_arm64_find_rcg_handler(const int op_type); arm64_inst_handler_t* scf_arm64_find_inst_handler(const int op_type); -int arm64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg); -int _arm64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg, scf_arm64_OpCode_t* OpCode); +int arm64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg); +int _arm64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg); int scf_arm64_open(scf_native_t* ctx); int scf_arm64_close(scf_native_t* ctx); @@ -167,6 +167,7 @@ scf_instruction_t* arm64_make_inst(scf_3ac_code_t* c, uint32_t opcode); int arm64_make_inst_I2G (scf_3ac_code_t* c, scf_register_arm64_t* rd, uint64_t imm, int bytes); int arm64_make_inst_M2G (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, scf_variable_t* vs); +int arm64_make_inst_M2GF (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, scf_variable_t* vs); int arm64_make_inst_G2M (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rs, scf_register_arm64_t* rb, scf_variable_t* vs); int arm64_make_inst_G2P (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rs, scf_register_arm64_t* rb, int32_t offset, int size); int arm64_make_inst_P2G (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, int32_t offset, int size); @@ -174,6 +175,10 @@ int arm64_make_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_ar int arm64_make_inst_SIB2G (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, arm64_sib_t* sib); int arm64_make_inst_G2SIB (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, arm64_sib_t* sib); int arm64_make_inst_ADR2G (scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_variable_t* vs); +int arm64_make_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, int32_t offset); +int arm64_make_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, arm64_sib_t* sib); + +int arm64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg); #endif diff --git a/native/arm64/scf_arm64_inst.c b/native/arm64/scf_arm64_inst.c index a843b89..fb099b1 100644 --- a/native/arm64/scf_arm64_inst.c +++ b/native/arm64/scf_arm64_inst.c @@ -28,6 +28,7 @@ return -EINVAL; \ } + static int _arm64_inst_call_stack_size(scf_3ac_code_t* c) { int stack_size = 0; @@ -107,6 +108,7 @@ static int _arm64_load_const_arg(scf_register_arm64_t* rabi, scf_dag_node_t* dn, ARM64_INST_ADD_CHECK(c->instructions, inst); ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); #endif + return -EINVAL; } else { int ret = arm64_make_inst_I2G(c, rabi, v->data.u64, size); if (ret < 0) @@ -477,7 +479,7 @@ static int _arm64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_function_t* f = arm64->f; scf_3ac_operand_t* src0 = c->srcs->data[0]; scf_variable_t* var_pf = src0->dag_node->var; @@ -494,12 +496,16 @@ static int _arm64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } + scf_register_arm64_t* lr = arm64_find_register("lr"); scf_register_arm64_t* sp = arm64_find_register("sp"); scf_register_arm64_t* x0 = arm64_find_register("x0"); scf_instruction_t* inst; scf_instruction_t* inst_sp = NULL; scf_instruction_t* inst_sp2 = NULL; + lr->used = 1; + sp->used = 1; + int data_rela_size = f->data_relas->size; int text_rela_size = f->text_relas->size; scf_loge("f->data_relas->size: %d, f->text_relas->size: %d\n", f->data_relas->size, f->text_relas->size); @@ -646,7 +652,7 @@ static int _arm64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } -static int _arm64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type) +static int _arm64_inst_bit_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->dsts || c->dsts->size != 1) return -EINVAL; @@ -655,9 +661,9 @@ static int _arm64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_ty return -EINVAL; scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_3ac_operand_t* src = c->srcs->data[0]; - scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; if (!src || !src->dag_node) return -EINVAL; @@ -670,39 +676,35 @@ static int _arm64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_ty if (!c->instructions) return -ENOMEM; } -#if 0 - int ret = arm64_inst_op2(SCF_ARM64_MOV, dst->dag_node, src->dag_node, c, f); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - scf_instruction_t* inst = NULL; - scf_register_arm64_t* rd = NULL; - scf_variable_t* var = dst->dag_node->var; + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* s = src->dag_node; + scf_dag_node_t* d = dst->dag_node; - scf_arm64_OpCode_t* OpCode = arm64_find_OpCode(OpCode_type, var->size, var->size, SCF_ARM64_E); - if (!OpCode) { - scf_loge("\n"); - return -1; - } + uint32_t opcode; - if (dst->dag_node->color > 0) { - ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - inst = arm64_make_inst_E(OpCode, rd); - ARM64_INST_ADD_CHECK(c->instructions, inst); + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + uint64_t u = s->var->data.u64; + + int ret = arm64_make_inst_I2G(c, rd, u, 8); + if (ret < 0) + return ret; + + opcode = (0xaa << 24) | (0x1 << 21) | (rd->id << 16) | (0x1f << 10) | rd->id; } else { - scf_rela_t* rela = NULL; + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); - inst = arm64_make_inst_M(&rela, OpCode, var, NULL); - ARM64_INST_ADD_CHECK(c->instructions, inst); - ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL); + opcode = (0xaa << 24) | (0x1 << 21) | (rs->id << 16) | (0x1f << 10) | rd->id; } + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; -#endif - return -1; } static int _arm64_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c) @@ -869,12 +871,6 @@ static int _arm64_inst_dec_post_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } -static int _arm64_inst_bit_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ -// return _arm64_inst_unary(ctx, c, SCF_ARM64_NOT); - return -EINVAL; -} - static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->dsts || c->dsts->size != 1) @@ -884,9 +880,9 @@ static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -EINVAL; scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_3ac_operand_t* src = c->srcs->data[0]; - scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; if (!src || !src->dag_node) return -EINVAL; @@ -902,17 +898,43 @@ static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_variable_t* v = dst->dag_node->var; + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* s = src->dag_node; + scf_dag_node_t* d = dst->dag_node; + scf_variable_t* v = d->var; + + uint32_t opcode; + + int is_float = scf_variable_float(v); + int size = arm64_variable_size(v); - int is_float = scf_variable_float(v); - int size = arm64_variable_size (v); + if (!is_float) { - if (!is_float) - return _arm64_inst_unary(ctx, c, SCF_ARM64_NEG); + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - scf_instruction_t* inst = NULL; - scf_register_arm64_t* rd = NULL; - scf_register_arm64_t* rs = NULL; + if (0 == s->color) { + uint64_t u = s->var->data.u64; + + int ret = arm64_make_inst_I2G(c, rd, u, 8); + if (ret < 0) + return ret; + + opcode = (0xcb << 24) | (rd->id << 16) | (0x1f << 10) | rd->id; + + } else { + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0xcb << 24) | (rs->id << 16) | (0x1f << 10) | rd->id; + } + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + +#if 0 scf_arm64_OpCode_t* pxor = arm64_find_OpCode(SCF_ARM64_PXOR, 8, 8, SCF_ARM64_E2G); scf_arm64_OpCode_t* sub = arm64_find_OpCode(SCF_ARM64_SUBSS, 4, 4, SCF_ARM64_E2G); @@ -920,7 +942,6 @@ static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) sub = arm64_find_OpCode(SCF_ARM64_SUBSD, 8, 8, SCF_ARM64_E2G); ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); -#if 0 inst = arm64_make_inst_E2G(pxor, rd, rd); ARM64_INST_ADD_CHECK(c->instructions, inst); @@ -946,38 +967,29 @@ static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c) ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); } #endif - return 0; + return -1; } static int _arm64_inst_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) { -// return arm64_inst_pointer(ctx, c, 0); - return -1; -} + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; -static int _arm64_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - if (!c->srcs || c->srcs->size != 4) + if (!c->srcs || c->srcs->size != 2) return -EINVAL; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* dst = c->dsts->data[0]; scf_3ac_operand_t* base = c->srcs->data[0]; - scf_3ac_operand_t* index = c->srcs->data[1]; - scf_3ac_operand_t* scale = c->srcs->data[2]; - scf_3ac_operand_t* src = c->srcs->data[3]; + scf_3ac_operand_t* member = c->srcs->data[1]; + scf_instruction_t* inst; if (!base || !base->dag_node) return -EINVAL; - if (!index || !index->dag_node) - return -EINVAL; - - if (!scale || !scale->dag_node) - return -EINVAL; - - if (!src || !src->dag_node) + if (!member || !member->dag_node) return -EINVAL; if (!c->instructions) { @@ -986,90 +998,51 @@ static int _arm64_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_cod return -ENOMEM; } - scf_variable_t* vscale = scale->dag_node->var; - scf_variable_t* vb = base->dag_node->var; - scf_variable_t* vs = src ->dag_node->var; - - scf_register_arm64_t* rs = NULL; - arm64_sib_t sib = {0}; - - scf_instruction_t* inst; - - int is_float = scf_variable_float(vs); - int size = arm64_variable_size (vs); + scf_variable_t* vd = dst ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vm = member->dag_node->var; - if (size > vscale->data.i) - size = vscale->data.i; + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; - int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); - if (ret < 0) { - scf_loge("\n"); + int ret = arm64_select_reg(&rd, dst->dag_node, c, f, 0); + if (ret < 0) return ret; - } - - if (vb->nb_dimentions > 1) { - - } else { - if (is_float) { - - if (0 == src->dag_node->color) { - src->dag_node->color = -1; - vs->global_flag = 1; - } - scf_loge("\n"); - return -EINVAL; - - } - - if (0 == src->dag_node->color) - src->dag_node->color = -1; - } - - ret = arm64_select_reg(&rs, src->dag_node, c, f, 1); - if (ret < 0) { - scf_loge("\n"); + ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f); + if (ret < 0) return ret; - } - rs = arm64_find_register_color_bytes(rs->color, size); + if (scf_variable_is_struct(vm) || scf_variable_is_array(vm)) - if (sib.index) - ret = arm64_make_inst_G2SIB(c, f, rs, &sib); - else - ret = arm64_make_inst_G2P(c, f, rs, sib.base, sib.disp, size); + return arm64_make_inst_ADRP2G(c, f, rd, sib.base, sib.disp); - if (ret < 0) { - scf_loge("\n"); - return ret; - } + if (sib.index) + return arm64_make_inst_SIB2G(c, f, rd, &sib); - return 0; + return arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); } -static int _arm64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag) +static int _arm64_inst_binary_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) { - if (!c->dsts || c->dsts->size != 1) - return -EINVAL; - if (!c->srcs || c->srcs->size != 3) return -EINVAL; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - scf_3ac_operand_t* dst = c->dsts->data[0]; scf_3ac_operand_t* base = c->srcs->data[0]; - scf_3ac_operand_t* index = c->srcs->data[1]; - scf_3ac_operand_t* scale = c->srcs->data[2]; + scf_3ac_operand_t* member = c->srcs->data[1]; + scf_3ac_operand_t* src = c->srcs->data[2]; + scf_instruction_t* inst; if (!base || !base->dag_node) return -EINVAL; - if (!index || !index->dag_node) + if (!member || !member->dag_node) return -EINVAL; - if (!scale || !scale->dag_node) + if (!src || !src->dag_node) return -EINVAL; if (!c->instructions) { @@ -1078,90 +1051,86 @@ static int _arm64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea return -ENOMEM; } - scf_variable_t* vd = dst ->dag_node->var; - scf_variable_t* vb = base ->dag_node->var; - scf_variable_t* vi = index->dag_node->var; - scf_variable_t* vs = scale->dag_node->var; + scf_variable_t* vs = src ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vm = member->dag_node->var; scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; arm64_sib_t sib = {0}; - scf_instruction_t* inst; - - int ret = arm64_select_reg(&rd, dst->dag_node, c, f, 0); - if (ret < 0) { - scf_loge("\n"); + int ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f); + if (ret < 0) return ret; - } - ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); - if (ret < 0) { - scf_loge("\n"); - return ret; - } + if (scf_variable_is_struct(vm) || scf_variable_is_array(vm)) + return -EINVAL; - if (vb->nb_dimentions > 1 || lea_flag) { + int is_float = scf_variable_float(vs); - } else { - int is_float = scf_variable_float(vd); + if (0 == src->dag_node->color) { if (is_float) { - scf_loge("\n"); - return -EINVAL; + + src->dag_node->color = -1; + vs->global_flag = 1; + + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + + } else { + ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs, vs->data.u64, sib.size); + if (ret < 0) + return ret; + + rs = arm64_find_register_color_bytes(rs->color, sib.size); } - } + } else + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + + if (op) { + uint32_t opcode; + + ret = arm64_select_free_reg(&rd, c, f, is_float); + if (ret < 0) + return ret; - if (sib.index) - ret = arm64_make_inst_SIB2G(c, f, rd, &sib); - else ret = arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; - if (ret < 0) { - scf_loge("\n"); - return ret; - } - return 0; -} + opcode = ((8 == sib.size) << 31)| op | (rs->id << 16) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); -static int _arm64_inst_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - return _arm64_inst_array_index(ctx, c, 0); -} + rs = rd; + } -static int _arm64_inst_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ -// return arm64_inst_dereference(ctx, c); - return -1; + return arm64_make_inst_G2P(c, f, rs, sib.base, sib.disp, sib.size); } -static int _arm64_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_inc_dec_pointer(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) { - if (!c->dsts || c->dsts->size != 1) { - scf_loge("\n"); + if (!c->srcs || c->srcs->size != 2) return -EINVAL; - } - if (!c->srcs || c->srcs->size != 1) { - scf_loge("\n"); - return -EINVAL; - } + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* member = c->srcs->data[1]; + scf_instruction_t* inst; - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_3ac_operand_t* src = c->srcs->data[0]; - scf_register_arm64_t* rd = NULL; - scf_rela_t* rela = NULL; + uint32_t opcode; - scf_arm64_OpCode_t* lea; - scf_instruction_t* inst; + if (!base || !base->dag_node) + return -EINVAL; - if (!src || !src->dag_node) { - scf_loge("\n"); + if (!member || !member->dag_node) return -EINVAL; - } - assert(dst->dag_node->var->nb_pointers > 0); if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1169,55 +1138,74 @@ static int _arm64_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - int ret = arm64_select_reg(&rd, dst->dag_node, c, f, 0); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - assert(dst->dag_node->color > 0); + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vm = member->dag_node->var; + scf_register_arm64_t* r = NULL; + arm64_sib_t sib = {0}; - ret = arm64_overflow_reg2(rd, dst->dag_node, c, f); - if (ret < 0) { - scf_loge("\n"); + int size = arm64_variable_size(vm); + + int ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f); + if (ret < 0) return ret; + + if (scf_variable_is_struct(vm) || scf_variable_is_array(vm)) + return -EINVAL; + + int is_float = scf_variable_float(vm); + if (is_float) { + scf_loge("\n"); + return -EINVAL; } -#if 0 - lea = arm64_find_OpCode(SCF_ARM64_LEA, 8,8, SCF_ARM64_E2G); - inst = arm64_make_inst_M2G(&rela, lea, rd, NULL, src->dag_node->var); + + ret = arm64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; + + if (sib.index) + ret = arm64_make_inst_SIB2G(c, f, r, &sib); + else + ret = arm64_make_inst_P2G(c, f, r, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; + + opcode = ((8 == size) << 31) | (u24 << 24) | (0x1 << 10) | (r->id << 5) | r->id; + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); - ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, src->dag_node->var, NULL); - return 0; -#endif - return -1; -} -static int _arm64_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - return -1; + if (sib.index) + ret = arm64_make_inst_G2SIB(c, f, r, &sib); + else + ret = arm64_make_inst_G2P(c, f, r, sib.base, sib.disp, sib.size); + return ret; } -static int _arm64_inst_mod_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_inc_dec_post_pointer(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) { - return -1; -} + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; -static int _arm64_inst_mul_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - ARM64_INST_OP3_CHECK() + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; - scf_register_arm64_t* rm = NULL; - scf_register_arm64_t* rn = NULL; - scf_register_arm64_t* rd = NULL; - scf_instruction_t* inst = NULL; - scf_dag_node_t* d = dst ->dag_node; - scf_dag_node_t* s0 = src0->dag_node; - scf_dag_node_t* s1 = src1->dag_node; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - assert(0 != d->color); - assert(0 != s0->color || 0 != s1->color); + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* member = c->srcs->data[1]; + scf_instruction_t* inst; - if (0 == s0->color) - SCF_XCHG(s0, s1); + uint32_t opcode; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (!base || !base->dag_node) + return -EINVAL; + + if (!member || !member->dag_node) + return -EINVAL; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1225,190 +1213,141 @@ static int _arm64_inst_mul_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - if (scf_variable_float(src0->dag_node->var)) { - - assert(scf_variable_float(src1->dag_node->var)); - assert(scf_variable_float(dst->dag_node->var)); - return -EINVAL; - } - - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); - - if (0 == s1->color) { - - if (!scf_variable_const_interger(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } - - s1->color = -1; - s1->var->tmp_flag = 1; - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); - - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + scf_variable_t* vd = dst ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vm = member->dag_node->var; + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; - uint32_t opcode = (0x9b << 24) | (rm->id << 16) | (0x1f << 10) | (rn->id << 5) | rd->id; + int size = arm64_variable_size(vm); - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + int ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f); + if (ret < 0) + return ret; - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (scf_variable_is_struct(vm) || scf_variable_is_array(vm)) + return -EINVAL; - s1->color = 0; - s1->loaded = 0; - s1->var->tmp_flag = 0; - assert(0 == scf_vector_del(rm->dag_nodes, s1)); - return 0; + int is_float = scf_variable_float(vm); + if (is_float) { + scf_loge("\n"); + return -EINVAL; } - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + if (sib.index) + ret = arm64_make_inst_SIB2G(c, f, rd, &sib); + else + ret = arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; - uint32_t opcode = (0x9b << 24) | (rm->id << 16) | (0x1f << 10) | (rn->id << 5) | rd->id; + opcode = ((8 == size) << 31) | (u24 << 24) | (0x1 << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + if (sib.index) + ret = arm64_make_inst_G2SIB(c, f, rd, &sib); + else + ret = arm64_make_inst_G2P(c, f, rd, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; + opcode &= ~(1 << 30); + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } -static int _arm64_inst_add_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_inc_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - ARM64_INST_OP3_CHECK() - - scf_register_arm64_t* rm = NULL; - scf_register_arm64_t* rn = NULL; - scf_register_arm64_t* rd = NULL; - scf_instruction_t* inst = NULL; - scf_dag_node_t* d = dst ->dag_node; - scf_dag_node_t* s0 = src0->dag_node; - scf_dag_node_t* s1 = src1->dag_node; - - assert(0 != d->color); - assert(0 != s0->color || 0 != s1->color); + return _arm64_inst_inc_dec_pointer(ctx, c, 0x11); +} - if (0 == s0->color) - SCF_XCHG(s0, s1); +static int _arm64_inst_dec_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_inc_dec_pointer(ctx, c, 0x51); +} - if (!c->instructions) { - c->instructions = scf_vector_alloc(); - if (!c->instructions) - return -ENOMEM; - } +static int _arm64_inst_inc_post_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_inc_dec_post_pointer(ctx, c, 0x11); +} - if (scf_variable_float(src0->dag_node->var)) { +static int _arm64_inst_dec_post_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_inc_dec_post_pointer(ctx, c, 0x51); +} - assert(scf_variable_float(src1->dag_node->var)); - assert(scf_variable_float(dst->dag_node->var)); +static int _arm64_inst_address_of_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) return -EINVAL; - } - - if (0 == s1->color) { - - if (scf_variable_const_string(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } - - if (!scf_variable_const_interger(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } - - uint64_t u = s1->var->data.u64; - uint32_t sh = 0; - uint32_t imm = 0; + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; - if (u <= 0xfff) - imm = u; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) { - sh = 1; - imm = u >> 12; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* member = c->srcs->data[1]; + scf_instruction_t* inst; - } else { - scf_loge("\n"); - return -EINVAL; - } + if (!base || !base->dag_node) + return -EINVAL; - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + if (!member || !member->dag_node) + return -EINVAL; - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) return -ENOMEM; - - uint32_t opcode = (0x91 << 24) | (sh << 22) | (imm << 10) | (rn->id << 5) | rd->id; - - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; - - ARM64_INST_ADD_CHECK(c->instructions, inst); - return 0; } - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + scf_variable_t* vd = dst ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vm = member->dag_node->var; - uint32_t opcode = (0x8b << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + int ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f); + if (ret < 0) + return ret; - ARM64_INST_ADD_CHECK(c->instructions, inst); - return 0; + return arm64_make_inst_ADRP2G(c, f, rd, sib.base, sib.disp); } -static int _arm64_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_binary_assign_array_index(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) { - ARM64_INST_OP3_CHECK() + if (!c->srcs || c->srcs->size != 4) + return -EINVAL; - scf_register_arm64_t* rm = NULL; - scf_register_arm64_t* rn = NULL; - scf_register_arm64_t* rd = NULL; - scf_instruction_t* inst = NULL; - scf_dag_node_t* d = dst ->dag_node; - scf_dag_node_t* s0 = src0->dag_node; - scf_dag_node_t* s1 = src1->dag_node; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - assert(0 != d->color); - assert(0 != s0->color || 0 != s1->color); + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* index = c->srcs->data[1]; + scf_3ac_operand_t* scale = c->srcs->data[2]; + scf_3ac_operand_t* src = c->srcs->data[3]; - int neg = 0; + if (!base || !base->dag_node) + return -EINVAL; - if (0 == s0->color) { - neg = 1; - SCF_XCHG(s0, s1); - } + if (!index || !index->dag_node) + return -EINVAL; + + if (!scale || !scale->dag_node) + return -EINVAL; + + if (!src || !src->dag_node) + return -EINVAL; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1416,117 +1355,103 @@ static int _arm64_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - if (scf_variable_float(src0->dag_node->var)) { + scf_variable_t* vscale = scale->dag_node->var; + scf_variable_t* vb = base->dag_node->var; + scf_variable_t* vs = src ->dag_node->var; - assert(scf_variable_float(src1->dag_node->var)); - assert(scf_variable_float(dst->dag_node->var)); - return -EINVAL; - } + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; + arm64_sib_t sib = {0}; + scf_instruction_t* inst; - if (0 == s1->color) { + int is_float = scf_variable_float(vs); + int size = arm64_variable_size (vs); - if (scf_variable_const_string(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } + if (size > vscale->data.i) + size = vscale->data.i; - if (!scf_variable_const_interger(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } + int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; + } - uint64_t u = s1->var->data.u64; + if (0 == src->dag_node->color) { - uint32_t sh = 0; - uint32_t imm = 0; + if (is_float) { - if (u <= 0xfff) - imm = u; + src->dag_node->color = -1; + vs->global_flag = 1; - else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) { - sh = 1; - imm = u >> 12; + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); } else { - scf_loge("\n"); - return -EINVAL; - } - - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); - - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; - uint32_t opcode = (0xd1 << 24) | (sh << 22) | (imm << 10) | (rn->id << 5) | rd->id; + ret = arm64_make_inst_I2G(c, rs, vs->data.u64, size); + if (ret < 0) + return ret; - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + rs = arm64_find_register_color_bytes(rs->color, size); + } + } else + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (op) { + uint32_t opcode; - if (neg) { - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + ret = arm64_select_free_reg(&rd, c, f, is_float); + if (ret < 0) + return ret; - opcode = (0xcb << 24) | (rd->id << 16) | (0x1f << 5) | rd->id; + if (sib.index) + ret = arm64_make_inst_SIB2G(c, f, rd, &sib); + else + ret = arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + opcode = ((8 == size) << 31) | op | (rs->id << 16) | (rd->id << 5) | rd->id | (is_float << 26); + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); - ARM64_INST_ADD_CHECK(c->instructions, inst); - } - return 0; + rs = rd; } - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); - - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; - - uint32_t opcode = (0xcb << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; - - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + if (sib.index) + ret = arm64_make_inst_G2SIB(c, f, rs, &sib); + else + ret = arm64_make_inst_G2P(c, f, rs, sib.base, sib.disp, size); + if (ret < 0) + return ret; - ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } -int arm64_inst_bit_op(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) +static int _arm64_inst_inc_dec_array_index(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) { - ARM64_INST_OP3_CHECK() + if (!c->srcs || c->srcs->size != 3) + return -EINVAL; - scf_register_arm64_t* rm = NULL; - scf_register_arm64_t* rn = NULL; - scf_register_arm64_t* rd = NULL; - scf_instruction_t* inst = NULL; - scf_dag_node_t* d = dst ->dag_node; - scf_dag_node_t* s0 = src0->dag_node; - scf_dag_node_t* s1 = src1->dag_node; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - assert(0 != d->color); - assert(0 != s0->color || 0 != s1->color); + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* index = c->srcs->data[1]; + scf_3ac_operand_t* scale = c->srcs->data[2]; - if (0 == s0->color) - SCF_XCHG(s0, s1); + uint32_t opcode; + + if (!base || !base->dag_node) + return -EINVAL; + + if (!index || !index->dag_node) + return -EINVAL; + + if (!scale || !scale->dag_node) + return -EINVAL; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1534,122 +1459,166 @@ int arm64_inst_bit_op(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) return -ENOMEM; } - if (scf_variable_float(src0->dag_node->var)) { + scf_variable_t* vscale = scale->dag_node->var; + scf_variable_t* vb = base->dag_node->var; - assert(scf_variable_float(src1->dag_node->var)); - assert(scf_variable_float(dst->dag_node->var)); - return -EINVAL; + scf_register_arm64_t* r = NULL; + arm64_sib_t sib = {0}; + scf_instruction_t* inst; + + int size = vb->data_size; + + int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; } - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); - ARM64_SELECT_REG_CHECK(&rn, d, c, f, 1); + ret = arm64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; - if (0 == s1->color) { + r = arm64_find_register_color_bytes(r->color, size); - if (!scf_variable_const_interger(s1->var)) { - scf_loge("\n"); - return -EINVAL; - } + if (sib.index) + ret = arm64_make_inst_SIB2G(c, f, r, &sib); + else + ret = arm64_make_inst_P2G(c, f, r, sib.base, sib.disp, size); + if (ret < 0) + return ret; - s1->color = -1; - s1->var->tmp_flag = 1; - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + opcode = ((8 == size) << 31) | (u24 << 24) | (0x1 << 10) | (r->id << 5) | r->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + if (sib.index) + ret = arm64_make_inst_G2SIB(c, f, r, &sib); + else + ret = arm64_make_inst_G2P(c, f, r, sib.base, sib.disp, size); + return ret; +} + +static int _arm64_inst_inc_dec_post_array_index(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 3) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* index = c->srcs->data[1]; + scf_3ac_operand_t* scale = c->srcs->data[2]; + + uint32_t opcode; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (!base || !base->dag_node) + return -EINVAL; + + if (!index || !index->dag_node) + return -EINVAL; + + if (!scale || !scale->dag_node) + return -EINVAL; - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) return -ENOMEM; + } - uint32_t opcode = (op << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + scf_variable_t* vscale = scale->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vd = dst ->dag_node->var; - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; + scf_instruction_t* inst; - ARM64_INST_ADD_CHECK(c->instructions, inst); + int size = vb->data_size; - s1->color = 0; - s1->loaded = 0; - s1->var->tmp_flag = 0; - assert(0 == scf_vector_del(rm->dag_nodes, s1)); - return 0; + int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; } - ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + if (sib.index) + ret = arm64_make_inst_SIB2G(c, f, rd, &sib); + else + ret = arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, size); + if (ret < 0) + return ret; - uint32_t opcode = (op << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + opcode = ((8 == size) << 31) | (u24 << 24) | (0x1 << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); - inst->c = c; - inst->code[0] = opcode & 0xff; - inst->code[1] = (opcode >> 8) & 0xff; - inst->code[2] = (opcode >> 16) & 0xff; - inst->code[3] = (opcode >> 24) & 0xff; - inst->len = 4; + if (sib.index) + ret = arm64_make_inst_G2SIB(c, f, rd, &sib); + else + ret = arm64_make_inst_G2P(c, f, rd, sib.base, sib.disp, size); + if (ret < 0) + return ret; + opcode &= ~(0x1 << 30); + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } -static int _arm64_inst_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_inc_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - return arm64_inst_bit_op(ctx, c, 0x8a); + return _arm64_inst_inc_dec_array_index(ctx, c, 0x11); } -static int _arm64_inst_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_dec_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - return arm64_inst_bit_op(ctx, c, 0xaa); + return _arm64_inst_inc_dec_array_index(ctx, c, 0x51); } -static int _arm64_inst_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_inc_post_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - //return arm_inst_teq(ctx, c); - return -1; + return _arm64_inst_inc_dec_post_array_index(ctx, c, 0x11); } -static int _arm64_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_dec_post_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) { -#if 0 - int ret = arm64_inst_teq(ctx, c); - if (ret < 0) - return ret; - - return arm64_inst_set(ctx, c, SCF_ARM64_SETZ); -#endif - return -1; + return _arm64_inst_inc_dec_post_array_index(ctx, c, 0x51); } -static int _arm64_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - if (!c->srcs || c->srcs->size != 2) + if (!c->dsts || c->dsts->size != 1) return -EINVAL; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_3ac_operand_t* s0 = c->srcs->data[0]; - scf_3ac_operand_t* s1 = c->srcs->data[1]; - - if (!s0 || !s0->dag_node) + if (!c->srcs || c->srcs->size != 3) return -EINVAL; - if (!s1 || !s1->dag_node) - return -EINVAL; + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - scf_instruction_t* inst; - scf_register_arm64_t* rs1; - scf_register_arm64_t* rs0 = NULL; - scf_dag_node_t* ds0 = s0->dag_node; - scf_dag_node_t* ds1 = s1->dag_node; - scf_rela_t* rela = NULL; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* index = c->srcs->data[1]; + scf_3ac_operand_t* scale = c->srcs->data[2]; - uint32_t opcode; + if (!base || !base->dag_node) + return -EINVAL; - if (ds0->var->size != ds1->var->size) + if (!index || !index->dag_node) + return -EINVAL; + + if (!scale || !scale->dag_node) return -EINVAL; if (!c->instructions) { @@ -1658,122 +1627,111 @@ static int _arm64_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - if (0 == ds0->color) { - scf_loge("src0 should be a var\n"); - if (ds0->var->w) - scf_loge("src0: '%s'\n", ds0->var->w->text->data); - else - scf_loge("src0: v_%#lx\n", 0xffff & (uintptr_t)ds0->var); - return -EINVAL; - } + scf_variable_t* vd = dst ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vi = index->dag_node->var; + scf_variable_t* vs = scale->dag_node->var; - ARM64_SELECT_REG_CHECK(&rs0, ds0, c, f, 1); + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; - if (scf_variable_float(ds0->var)) { - assert(scf_variable_float(ds1->var)); + scf_instruction_t* inst; - if (0 == ds1->color) { - ds1->color = -1; - ds1->var->global_flag = 1; - -// ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); - return -EINVAL; - } + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); + int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); + if (ret < 0) { scf_loge("\n"); - return -EINVAL; + return ret; } - if (0 == ds1->color) { + if (vb->nb_dimentions > 1) { - uint64_t u = ds1->var->data.u64; + if (sib.index) + ret = arm64_make_inst_ADRSIB2G(c, f, rd, &sib); + else + ret = arm64_make_inst_ADRP2G(c, f, rd, sib.base, sib.disp); + return ret; + } - if (u <= 0xfff) - opcode = (0x71 << 24) | (u << 10) | (rs0->id << 5) | 0x1f; + if (sib.index) + return arm64_make_inst_SIB2G(c, f, rd, &sib); - else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) - opcode = (0x71 << 24) | (1 << 22) | (u << 10) | (rs0->id << 5) | 0x1f; + return arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); +} - else { - ds1->loaded = 0; - ds1->color = -1; - ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); +static int _arm64_inst_address_of_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; - opcode = (0x6b << 24) | (rs1->id << 16) | (rs0->id << 5) | 0x1f; + if (!c->srcs || c->srcs->size != 3) + return -EINVAL; - ds1->loaded = 0; - ds1->color = 0; - assert(0 == scf_vector_del(rs1->dag_nodes, ds1)); - } + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; - if (rs0->bytes > 4) - opcode |= (0x1 << 31); + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* index = c->srcs->data[1]; + scf_3ac_operand_t* scale = c->srcs->data[2]; + scf_instruction_t* inst; - inst = arm64_make_inst(c, opcode); - ARM64_INST_ADD_CHECK(c->instructions, inst); - return 0; - } + if (!base || !base->dag_node) + return -EINVAL; - ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); + if (!index || !index->dag_node) + return -EINVAL; - opcode = (0x6b << 24) | (rs1->id << 16) | (rs0->id << 5) | 0x1f; + if (!scale || !scale->dag_node) + return -EINVAL; - if (rs0->bytes > 4) - opcode |= (0x1 << 31); + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } - inst = arm64_make_inst(c, opcode); - ARM64_INST_ADD_CHECK(c->instructions, inst); + scf_variable_t* vd = dst ->dag_node->var; + scf_variable_t* vb = base ->dag_node->var; + scf_variable_t* vi = index->dag_node->var; + scf_variable_t* vs = scale->dag_node->var; - return 0; -} + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; -#define ARM64_INST_SET(name, op) \ -static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1; \ -} - //return arm64_inst_set(ctx, c, SCF_ARM64_##op); -ARM64_INST_SET(setz, SETZ) -ARM64_INST_SET(setnz, SETNZ) -ARM64_INST_SET(setgt, SETG) -ARM64_INST_SET(setge, SETGE) -ARM64_INST_SET(setlt, SETL) -ARM64_INST_SET(setle, SETLE) + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); + + int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + if (sib.index) + ret = arm64_make_inst_ADRSIB2G(c, f, rd, &sib); + else + ret = arm64_make_inst_ADRP2G(c, f, rd, sib.base, sib.disp); -#define ARM64_INST_CMP_SET(name, op) \ -static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1; \ + return ret; } - //return arm64_inst_cmp_set(ctx, c, SCF_ARM64_##op); -ARM64_INST_CMP_SET(eq, SETZ) -ARM64_INST_CMP_SET(ne, SETNZ) -ARM64_INST_CMP_SET(gt, SETG) -ARM64_INST_CMP_SET(ge, SETGE) -ARM64_INST_CMP_SET(lt, SETL) -ARM64_INST_CMP_SET(le, SETLE) -static int _arm64_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - if (!c->dsts || c->dsts->size != 1) - return -EINVAL; - if (!c->srcs || c->srcs->size != 1) return -EINVAL; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_3ac_operand_t* src = c->srcs->data[0]; - scf_3ac_operand_t* dst = c->dsts->data[0]; - - if (!src || !src->dag_node) + if (!c->dsts || c->dsts->size != 1) return -EINVAL; - if (!dst || !dst->dag_node) - return -EINVAL; + scf_register_arm64_t* rd = NULL; + scf_arm64_context_t* arm64 = 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 = arm64->f; - if (0 == dst->dag_node->color) + if (!base || !base->dag_node) return -EINVAL; if (!c->instructions) { @@ -1782,56 +1740,77 @@ static int _arm64_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_arm64_OpCode_t* lea; - scf_instruction_t* inst; + arm64_sib_t sib = {0}; - scf_register_arm64_t* rd = NULL; - scf_rela_t* rela = NULL; + int size = base->dag_node->var->data_size; - scf_variable_t* vd = dst->dag_node->var; - scf_variable_t* vs = src->dag_node->var; + int ret = arm64_dereference_reg(&sib, base->dag_node, NULL, c, f); + if (ret < 0) + return ret; - int src_size = arm64_variable_size(vs); - int dst_size = arm64_variable_size(vd); -#if 0 - if (scf_variable_float(vs) || scf_variable_float(vd)) - return arm64_inst_float_cast(dst->dag_node, src->dag_node, c, f); + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - if (src_size < dst_size) - return arm64_inst_movx(dst->dag_node, src->dag_node, c, f); + return arm64_make_inst_P2G(c, f, rd, sib.base, 0, size); +} - scf_logw("src_size: %d, dst_size: %d\n", src_size, dst_size); +static int _arm64_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } - if (src->dag_node->var->nb_dimentions > 0) - return arm64_inst_op2(SCF_ARM64_LEA, dst->dag_node, src->dag_node, c, f); + scf_register_arm64_t* rax = arm64_find_register("rax"); + scf_arm64_OpCode_t* push; + scf_instruction_t* inst; - return arm64_inst_op2(SCF_ARM64_MOV, dst->dag_node, src->dag_node, c, f); +#if 0 + push = arm64_find_OpCode(SCF_ARM64_PUSH, 8,8, SCF_ARM64_G); + inst = arm64_make_inst_G(push, rax); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; #endif return -1; } -static int _arm64_inst_mul_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - if (!c->dsts || c->dsts->size != 1) - return -EINVAL; - - if (!c->srcs || c->srcs->size != 1) - return -EINVAL; + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_register_arm64_t* rax = arm64_find_register("rax"); + scf_arm64_OpCode_t* pop; + scf_instruction_t* inst; +#if 0 + pop = arm64_find_OpCode(SCF_ARM64_POP, 8,8, SCF_ARM64_G); + inst = arm64_make_inst_G(pop, rax); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +#endif + return -1; +} - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_3ac_operand_t* src = c->srcs->data[0]; +/* - if (!src || !src->dag_node) - return -EINVAL; +struct va_list +{ + uint8_t* iptr; + uint8_t* fptr; + uint8_t* optr; - if (!dst || !dst->dag_node) - return -EINVAL; + intptr_t ireg; + intptr_t freg; +}; +*/ - if (src->dag_node->var->size != dst->dag_node->var->size) - return -EINVAL; +static int _arm64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1839,87 +1818,1696 @@ static int _arm64_inst_mul_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - if (scf_variable_float(src->dag_node->var)) { + scf_loge("c->srcs->size: %d\n", c->srcs->size); + assert(3 == c->srcs->size); - assert(scf_variable_float(dst->dag_node->var)); - } + scf_register_arm64_t* rbp = arm64_find_register("rbp"); + scf_register_arm64_t* rptr = NULL; + scf_register_arm64_t* rap = NULL; + scf_instruction_t* inst = NULL; + scf_3ac_operand_t* ap = c->srcs->data[0]; + scf_3ac_operand_t* ptr = c->srcs->data[2]; + scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_G2E); + scf_arm64_OpCode_t* lea = arm64_find_OpCode(SCF_ARM64_LEA, 8, 8, SCF_ARM64_E2G); + scf_variable_t* v = ap->dag_node->var; - return -EINVAL; -} + int offset_int = -f->args_int * 8 - 8; + int offset_float = -f->args_float * 8 - ARM64_ABI_NB * 8 - 8; + int offset_others = 16; -static int _div_mod_assign(scf_native_t* ctx, scf_3ac_code_t* c, int mod_flag) -{ - if (!c->dsts || c->dsts->size != 1) { + if (v->bp_offset >= 0) { scf_loge("\n"); - return -EINVAL; + return -1; } +#if 0 + ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); + ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); - if (!c->srcs || c->srcs->size != 1) { - scf_loge("\n"); - return -EINVAL; - } + inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_int); + ARM64_INST_ADD_CHECK(c->instructions, inst); - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + inst = arm64_make_inst_G2P(mov, rap, 0, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_3ac_operand_t* src = c->srcs->data[0]; - if (!src || !src->dag_node) { - scf_loge("\n"); - return -EINVAL; - } + inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_float); + ARM64_INST_ADD_CHECK(c->instructions, inst); - if (!dst || !dst->dag_node) { - scf_loge("\n"); - return -EINVAL; - } + inst = arm64_make_inst_G2P(mov, rap, 8, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); - if (src->dag_node->var->size != dst->dag_node->var->size) { - scf_loge("\n"); - return -EINVAL; - } - if (scf_variable_float(src->dag_node->var)) { - assert(scf_variable_float(dst->dag_node->var)); - } + inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_others); + ARM64_INST_ADD_CHECK(c->instructions, inst); - scf_loge("\n"); - return -EINVAL; -} + inst = arm64_make_inst_G2P(mov, rap, 16, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); -static int _arm64_inst_div_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - scf_loge("\n"); - return -EINVAL; -} -static int _arm64_inst_mod_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - scf_loge("\n"); - return -EINVAL; + mov = arm64_find_OpCode(SCF_ARM64_MOV, 4, 8, SCF_ARM64_I2E); + + inst = arm64_make_inst_I2P(mov, rap, 24, (uint8_t*)&f->args_int, 4); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_I2P(mov, rap, 32, (uint8_t*)&f->args_float, 4); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +#endif + return -1; } -static int _arm64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - if (!c->srcs || c->srcs->size < 1) - return -EINVAL; - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; - scf_3ac_operand_t* src = NULL; - scf_variable_t* v = NULL; - scf_instruction_t* inst = NULL; - scf_rela_t* rela = NULL; - - scf_register_arm64_t* rd = NULL; - scf_register_arm64_t* rs = NULL; - scf_register_arm64_t* sp = arm64_find_register("sp"); - scf_register_arm64_t* fp = arm64_find_register("fp"); - - scf_arm64_OpCode_t* pop; - scf_arm64_OpCode_t* mov; - scf_arm64_OpCode_t* ret; + scf_function_t* f = arm64->f; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + assert(2 == c->srcs->size); + + scf_register_arm64_t* rbp = arm64_find_register("rbp"); + scf_register_arm64_t* rptr = NULL; + scf_register_arm64_t* rap = NULL; + scf_instruction_t* inst = NULL; + scf_3ac_operand_t* ap = c->srcs->data[0]; + scf_3ac_operand_t* ptr = c->srcs->data[1]; + scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_G2E); + scf_arm64_OpCode_t* xor = arm64_find_OpCode(SCF_ARM64_XOR, 8, 8, SCF_ARM64_G2E); + scf_variable_t* v = ap->dag_node->var; + + if (v->bp_offset >= 0) { + scf_loge("\n"); + return -1; + } + + ptr->dag_node->var->tmp_flag = 1; + ptr->dag_node->color = -1; +#if 0 + ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); + ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); + + inst = arm64_make_inst_G2E(xor, rptr, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_G2P(mov, rap, 0, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_G2P(mov, rap, 8, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_G2P(mov, rap, 16, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_G2P(mov, rap, 24, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst = arm64_make_inst_G2P(mov, rap, 32, rptr); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + ptr->dag_node->var->tmp_flag = 0; + ptr->dag_node->color = 0; + ptr->dag_node->loaded = 0; + + assert(0 == scf_vector_del(rptr->dag_nodes, ptr->dag_node)); + return 0; +#endif + return -1; +} + +static int _arm64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + assert(1 == c->dsts->size && 3 == c->srcs->size); + + scf_register_arm64_t* rbp = arm64_find_register("rbp"); + scf_register_arm64_t* rd = NULL; // result + scf_register_arm64_t* rap = NULL; // ap + scf_register_arm64_t* rptr = NULL; // ptr + scf_instruction_t* inst = NULL; + + scf_instruction_t* inst_jge = NULL; + scf_instruction_t* inst_jmp = NULL; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* ap = c->srcs->data[0]; + scf_3ac_operand_t* src = c->srcs->data[1]; + scf_3ac_operand_t* ptr = c->srcs->data[2]; + scf_variable_t* v = src->dag_node->var; + +#if 0 + scf_arm64_OpCode_t* inc = arm64_find_OpCode(SCF_ARM64_INC, 8, 8, SCF_ARM64_E); + scf_arm64_OpCode_t* add = arm64_find_OpCode(SCF_ARM64_ADD, 4, 8, SCF_ARM64_I2E); + scf_arm64_OpCode_t* sub = arm64_find_OpCode(SCF_ARM64_SUB, 4, 8, SCF_ARM64_I2E); + scf_arm64_OpCode_t* cmp = arm64_find_OpCode(SCF_ARM64_CMP, 4, 8, SCF_ARM64_I2E); + scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_E2G); + scf_arm64_OpCode_t* jge = arm64_find_OpCode(SCF_ARM64_JGE, 4, 4, SCF_ARM64_I); + scf_arm64_OpCode_t* jmp = arm64_find_OpCode(SCF_ARM64_JMP, 4, 4, SCF_ARM64_I); + scf_arm64_OpCode_t* mov2 = NULL; + + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); + ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); + ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); + + int is_float = scf_variable_float(v); + int size = arm64_variable_size(v); + + uint32_t nints = ARM64_ABI_NB; + uint32_t nfloats = ARM64_ABI_NB; + uint32_t offset = 0; + uint32_t incptr = 8; + + int idx_offset = 24; + int ptr_offset = 0; + + if (is_float) { + idx_offset = 32; + ptr_offset = 8; + } + + inst = arm64_make_inst_I2P(cmp, rap, idx_offset, (uint8_t*)&nints, 4); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + inst_jge = arm64_make_inst_I(jge, (uint8_t*)&offset, sizeof(offset)); + ARM64_INST_ADD_CHECK(c->instructions, inst_jge); + + + inst = arm64_make_inst_P2G(mov, rptr, rap, ptr_offset); + ARM64_INST_ADD_CHECK(c->instructions, inst); + offset += inst->len; + + inst = arm64_make_inst_I2P(sub, rap, ptr_offset, (uint8_t*)&incptr, 4); + ARM64_INST_ADD_CHECK(c->instructions, inst); + offset += inst->len; + + inst_jmp = arm64_make_inst_I(jmp, (uint8_t*)&offset, sizeof(offset)); + ARM64_INST_ADD_CHECK(c->instructions, inst_jmp); + offset += inst_jmp->len; + + uint8_t* p = (uint8_t*)&offset; + int i; + for (i = 0; i < 4; i++) + inst_jge->code[jge->nb_OpCodes + i] = p[i]; + + offset = 0; + inst = arm64_make_inst_P2G(mov, rptr, rap, 16); + ARM64_INST_ADD_CHECK(c->instructions, inst); + offset += inst->len; + + inst = arm64_make_inst_I2P(add, rap, 16, (uint8_t*)&incptr, 4); + ARM64_INST_ADD_CHECK(c->instructions, inst); + offset += inst->len; + + for (i = 0; i < 4; i++) + inst_jmp->code[jmp->nb_OpCodes + i] = p[i]; + + inst = arm64_make_inst_P(inc, rap, idx_offset, 8); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + if (is_float) { + if (4 == size) + mov2 = arm64_find_OpCode(SCF_ARM64_MOVSS, 4, 4, SCF_ARM64_E2G); + else if (8 == size) + mov2 = arm64_find_OpCode(SCF_ARM64_MOVSD, 8, 8, SCF_ARM64_E2G); + else + assert(0); + } else + mov2 = arm64_find_OpCode(SCF_ARM64_MOV, size, size, SCF_ARM64_E2G); + + inst = arm64_make_inst_P2G(mov2, rd, rptr, 0); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + return 0; +#endif + return -1; +} + +static int _arm64_inst_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) { + scf_loge("\n"); + return -EINVAL; + } + + if (!c->srcs || c->srcs->size != 1) { + scf_loge("\n"); + return -EINVAL; + } + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst; + + if (!src || !src->dag_node) { + scf_loge("\n"); + return -EINVAL; + } + assert(dst->dag_node->var->nb_pointers > 0); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + int ret = arm64_select_reg(&rd, dst->dag_node, c, f, 0); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + assert(dst->dag_node->color > 0); + + ret = arm64_overflow_reg2(rd, dst->dag_node, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + + return arm64_make_inst_ADR2G(c, f, rd, src->dag_node->var); +} + +static int _arm64_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rs0 = NULL; + scf_register_arm64_t* rs1 = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(s0->var)) { + + if (0 == s0->color) { + s0->color = -1; + s0->var->global_flag = 1; + + } else if (0 == s1->color) { + s1->color = -1; + s1->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x3 << 11); + opcode |= (rs1->id << 16) | (rs0->id << 5) | rd->id; + opcode |= ((8 == rd->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s1->color) { + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + + int ret = arm64_select_free_reg(&rs1, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs1, s1->var->data.u64, rs1->bytes); + if (ret < 0) + return ret; + + } else if (0 == s0->color) { + + if (!scf_variable_const_interger(s0->var)) { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + + int ret = arm64_select_free_reg(&rs0, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs0, s0->var->data.u64, rs0->bytes); + if (ret < 0) + return ret; + + } else { + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + } + + opcode = ((8 == rs0->bytes) << 31) | (0x1a << 24) | (0x3 << 22) | (rs1->id << 16) | (0x2 << 10) | (rs0->id << 5) | rd->id; + + if (scf_variable_signed(s0->var)) + opcode |= 0x3 << 10; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_mod_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rs0 = NULL; + scf_register_arm64_t* rs1 = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src0->dag_node->var)) { + + assert(scf_variable_float(src1->dag_node->var)); + assert(scf_variable_float(dst->dag_node->var)); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s1->color) { + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + + int ret = arm64_select_free_reg(&rs1, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs1, s1->var->data.u64, rs1->bytes); + if (ret < 0) + return ret; + + } else if (0 == s0->color) { + + if (!scf_variable_const_interger(s0->var)) { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + + int ret = arm64_select_free_reg(&rs0, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs0, s0->var->data.u64, rs0->bytes); + if (ret < 0) + return ret; + + } else { + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + } + + opcode = ((8 == rs0->bytes) << 31) | (0x1a << 24) | (0x3 << 22) | (rs1->id << 16) | (0x2 << 10) | (rs0->id << 5) | rd->id; + + if (scf_variable_signed(s0->var)) + opcode |= 0x3 << 10; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + opcode = ((8 == rs0->bytes) << 31) | (0x1b << 24) | (rs1->id << 16) | (0x1 << 15) | (rs0->id << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_mul_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rm = NULL; + scf_register_arm64_t* rn = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (0 == s0->color) + SCF_XCHG(s0, s1); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(s0->var)) { + + if (0 == s0->color) { + s0->color = -1; + s0->var->global_flag = 1; + + } else if (0 == s1->color) { + s1->color = -1; + s1->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 11); + opcode |= (rm->id << 16) | (rn->id << 5) | rd->id; + opcode |= ((8 == rd->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + + if (0 == s1->color) { + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + s1->color = -1; + s1->var->tmp_flag = 1; + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x9b << 24) | (rm->id << 16) | (0x1f << 10) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + s1->color = 0; + s1->loaded = 0; + s1->var->tmp_flag = 0; + assert(0 == scf_vector_del(rm->dag_nodes, s1)); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x9b << 24) | (rm->id << 16) | (0x1f << 10) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_mul_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (src->dag_node->var->size != dst->dag_node->var->size) + return -EINVAL; + + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(s->var)) { + + if (0 == s->color) { + s->color = -1; + s->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 11); + opcode |= (rs->id << 16) | (rd->id << 5) | rd->id; + opcode |= ((8 == rd->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + + if (!scf_variable_const_interger(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + s->color = -1; + s->var->tmp_flag = 1; + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0x9b << 24) | (rs->id << 16) | (0x1f << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + s->color = 0; + s->loaded = 0; + s->var->tmp_flag = 0; + assert(0 == scf_vector_del(rs->dag_nodes, s)); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0x9b << 24) | (rs->id << 16) | (0x1f << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_add_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rm = NULL; + scf_register_arm64_t* rn = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (0 == s0->color) + SCF_XCHG(s0, s1); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src0->dag_node->var)) { + + if (0 == s1->color) { + s1->color = -1; + s1->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 13) | (0x1 << 11); + opcode |= (rm->id << 16) | (rn->id << 5) | rd->id; + opcode |= (8 == rd->bytes) << 22; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + if (0 == s1->color) { + + if (scf_variable_const_string(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + uint64_t u = s1->var->data.u64; + + uint32_t sh = 0; + uint32_t imm = 0; + + if (u <= 0xfff) + imm = u; + + else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) { + sh = 1; + imm = u >> 12; + + } else { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + + opcode = (0x91 << 24) | (sh << 22) | (imm << 10) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x8b << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_add_sub_assign(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24i, uint32_t u24r) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (src->dag_node->var->size != dst->dag_node->var->size) + return -EINVAL; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(s->var)) { + + if (0 == s->color) { + s->color = -1; + s->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + uint32_t op; + + if (0x11 == u24i) + op = 0x5; + + else if (0x51 == u24i) + op = 0x7; + else + return -EINVAL; + + opcode = (0x1e << 24) | (0x1 << 21) | (op << 11); + opcode |= (rs->id << 16) | (rd->id << 5) | rd->id; + opcode |= (8 == rd->bytes) << 22; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + if (0 == s->color) { + + if (scf_variable_const_string(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + if (!scf_variable_const_interger(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + uint64_t u = s->var->data.u64; + + uint32_t sh = 0; + uint32_t imm = 0; + + if (u <= 0xfff) + imm = u; + + else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) { + sh = 1; + imm = u >> 12; + + } else { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + opcode = ((8 == rd->bytes) << 31) | (u24i << 24) | (sh << 22) | (imm << 10) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = ((8 == rd->bytes) << 31) | (u24r << 24) | (rs->id << 16) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_add_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_add_sub_assign(ctx, c, 0x11, 0x0b); +} + +static int _arm64_inst_sub_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_add_sub_assign(ctx, c, 0x51, 0x4b); +} + +static int _arm64_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rm = NULL; + scf_register_arm64_t* rn = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src0->dag_node->var)) { + + if (0 == s0->color) { + s0->color = -1; + s0->var->global_flag = 1; + + } else if (0 == s1->color) { + s1->color = -1; + s1->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x7 << 11); + opcode |= (rm->id << 16) | (rn->id << 5) | rd->id; + opcode |= ((8 == rd->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + int neg = 0; + + if (0 == s0->color) { + neg = 1; + SCF_XCHG(s0, s1); + } + + if (0 == s1->color) { + + if (scf_variable_const_string(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + uint64_t u = s1->var->data.u64; + + uint32_t sh = 0; + uint32_t imm = 0; + + if (u <= 0xfff) + imm = u; + + else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) { + sh = 1; + imm = u >> 12; + + } else { + scf_loge("\n"); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + + opcode = ((8 == rn->bytes) << 31) | (0x51 << 24) | (sh << 22) | (imm << 10) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + if (neg) { + opcode = ((8 == rd->bytes) << 31) | (0x4b << 24) | (rd->id << 16) | (0x1f << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + } + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, s0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = ((8 == rn->bytes) << 31) | (0x4b << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +int arm64_inst_bit_op(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) +{ + ARM64_INST_OP3_CHECK() + + scf_register_arm64_t* rm = NULL; + scf_register_arm64_t* rn = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + assert(0 != s0->color || 0 != s1->color); + + if (0 == s0->color) + SCF_XCHG(s0, s1); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src0->dag_node->var)) { + + assert(scf_variable_float(src1->dag_node->var)); + assert(scf_variable_float(dst->dag_node->var)); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rn, d, c, f, 1); + + if (0 == s1->color) { + + if (!scf_variable_const_interger(s1->var)) { + scf_loge("\n"); + return -EINVAL; + } + + s1->color = -1; + s1->var->tmp_flag = 1; + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (op << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + s1->color = 0; + s1->loaded = 0; + s1->var->tmp_flag = 0; + assert(0 == scf_vector_del(rm->dag_nodes, s1)); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rm, s1, c, f, 1); + + opcode = (op << 24) | (rm->id << 16) | (rn->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +int arm64_inst_bit_op_assign(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (src->dag_node->var->size != dst->dag_node->var->size) + return -EINVAL; + + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src->dag_node->var)) { + + assert(scf_variable_float(dst->dag_node->var)); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + + if (!scf_variable_const_interger(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + s->color = -1; + s->var->tmp_flag = 1; + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (op << 24) | (rs->id << 16) | (rd->id << 5) | rd->id; + ARM64_INST_ADD_CHECK(c->instructions, inst); + + s->color = 0; + s->loaded = 0; + s->var->tmp_flag = 0; + assert(0 == scf_vector_del(rs->dag_nodes, s)); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (op << 24) | (rs->id << 16) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return arm64_inst_bit_op(ctx, c, 0x8a); +} + +static int _arm64_inst_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return arm64_inst_bit_op(ctx, c, 0xaa); +} + +static int _arm64_inst_and_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return arm64_inst_bit_op_assign(ctx, c, 0x8a); +} + +static int _arm64_inst_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return arm64_inst_bit_op_assign(ctx, c, 0xaa); +} + +static int _arm64_inst_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + scf_register_arm64_t* rs; + scf_instruction_t* inst; + + uint32_t opcode; + + if (0 == src->dag_node->color) { + scf_loge("src->dag_node->var: %p\n", src->dag_node->var); + return -1; + } + + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + + opcode = ((8 == rs->bytes) << 1) | (0x6a << 24) | (rs->id << 16) | (rs->id << 5) | 0x1f; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_set(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t cc) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* dst = c->dsts->data[0]; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + scf_register_arm64_t* rd; + scf_instruction_t* inst; + + uint32_t opcode; + + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); + + opcode = ((8 == rd->bytes) << 1) | (0x1a << 24) | (0x1 << 23) | (0x1f << 16) | (cc << 12) | (0x3f << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + int ret = _arm64_inst_teq_handler(ctx, c); + if (ret < 0) + return ret; + + return _arm64_inst_set(ctx, c, 0x1); +} + +static int _arm64_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* s0 = c->srcs->data[0]; + scf_3ac_operand_t* s1 = c->srcs->data[1]; + + if (!s0 || !s0->dag_node) + return -EINVAL; + + if (!s1 || !s1->dag_node) + return -EINVAL; + + scf_instruction_t* inst; + scf_register_arm64_t* rs1 = NULL; + scf_register_arm64_t* rs0 = NULL; + scf_dag_node_t* ds0 = s0->dag_node; + scf_dag_node_t* ds1 = s1->dag_node; + scf_rela_t* rela = NULL; + + uint32_t opcode; + + if (ds0->var->size != ds1->var->size) + return -EINVAL; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (0 == ds0->color) { + scf_loge("src0 should be a var\n"); + if (ds0->var->w) + scf_loge("src0: '%s'\n", ds0->var->w->text->data); + else + scf_loge("src0: v_%#lx\n", 0xffff & (uintptr_t)ds0->var); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rs0, ds0, c, f, 1); + + if (scf_variable_float(ds0->var)) { + + if (0 == ds1->color) { + ds1->color = -1; + ds1->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rs0, ds0, c, f, 1); + ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 13); + opcode |= (rs1->id << 16) | (rs0->id << 5); + opcode |= ((8 == rs0->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + if (0 == ds1->color) { + + uint64_t u = ds1->var->data.u64; + + if (u <= 0xfff) + opcode = (0x71 << 24) | (u << 10) | (rs0->id << 5) | 0x1f; + + else if (0 == (u & 0xfff) && (u >> 12) <= 0xfff) + opcode = (0x71 << 24) | (1 << 22) | (u << 10) | (rs0->id << 5) | 0x1f; + + else { + ds1->loaded = 0; + ds1->color = -1; + ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); + + opcode = (0x6b << 24) | (rs1->id << 16) | (rs0->id << 5) | 0x1f; + + ds1->loaded = 0; + ds1->color = 0; + assert(0 == scf_vector_del(rs1->dag_nodes, ds1)); + } + + if (rs0->bytes > 4) + opcode |= (0x1 << 31); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1); + + opcode = (0x6b << 24) | (rs1->id << 16) | (rs0->id << 5) | 0x1f; + + if (rs0->bytes > 4) + opcode |= (0x1 << 31); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + return 0; +} + +#define ARM64_INST_SET(name, cc) \ +static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ +{ \ + return _arm64_inst_set(ctx, c, cc); \ +} +ARM64_INST_SET(setz, 0x1) +ARM64_INST_SET(setnz, 0x0) +ARM64_INST_SET(setgt, 0xd) +ARM64_INST_SET(setge, 0xb) +ARM64_INST_SET(setlt, 0xa) +ARM64_INST_SET(setle, 0xc) + +#define ARM64_INST_CMP_SET(name, cc) \ +static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ +{ \ + int ret = _arm64_inst_cmp_handler(ctx, c); \ + if (ret < 0) \ + return ret; \ + return _arm64_inst_set(ctx, c, cc); \ +} +ARM64_INST_CMP_SET(eq, 0x1) +ARM64_INST_CMP_SET(ne, 0x0) +ARM64_INST_CMP_SET(gt, 0xd) +ARM64_INST_CMP_SET(ge, 0xb) +ARM64_INST_CMP_SET(lt, 0xa) +ARM64_INST_CMP_SET(le, 0xc) + +static int _arm64_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_instruction_t* inst; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (0 == dst->dag_node->color) + return -EINVAL; + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + scf_variable_t* vs = s->var; + scf_variable_t* vd = d->var; + + int src_size = arm64_variable_size(vs); + int dst_size = arm64_variable_size(vd); + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + uint32_t opcode = 0; + + if (scf_variable_float(vs)) { + + if (0 == s->color) { + s->color = -1; + vs->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + if (scf_variable_float(vd)) { + + if (rd->bytes == rs->bytes) + opcode = (0x1e << 24) | ((8 == rd->bytes) << 22) | (0x1 << 21) | (0x1 << 14) | (rs->id << 5) | rd->id; + + else if (4 == rs->bytes) + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 17) | (0x1 << 15) | (0x1 << 14) | (rs->id << 5) | rd->id; + else + opcode = (0x1e << 24) | (0x1 << 22) | (0x1 << 21) | (0x1 << 17) | (0x1 << 14) | (rs->id << 5) | rd->id; + + } else { + opcode = ((8 == rd->bytes) << 31) | (0x1e << 24) | ((8 == rs->bytes) << 22) | (0x7 << 19) | (rs->id << 5) | rd->id; + + opcode |= (!scf_variable_signed(vd)) << 16; + } + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + + } else if (scf_variable_float(vd)) { + + if (0 == s->color) { + + if (!scf_variable_const_interger(vs)) + return -EINVAL; + + if (src_size < dst_size) + scf_variable_extend_bytes(vs, 8); + + int ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs, vs->data.u64, dst_size); + if (ret < 0) + return ret; + + } else + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 17) | (rs->id << 5) | rd->id; + + opcode |= ((8 == rs->bytes) << 31) | ((8 == rd->bytes) << 22); + + opcode |= (!scf_variable_signed(vd)) << 16; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + if (vs->nb_dimentions > 0) + return arm64_make_inst_ADR2G(c, f, rd, vs); + + scf_logw("src_size: %d, dst_size: %d\n", src_size, dst_size); + + if (0 == s->color) { + + if (!scf_variable_const_interger(vs)) + return -EINVAL; + + if (src_size < dst_size) + scf_variable_extend_bytes(vs, 8); + + return arm64_make_inst_I2G(c, rd, vs->data.u64, dst_size); + } + + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + if (src_size < dst_size) { + + if (scf_variable_signed(vs)) { + + opcode = (0x93 << 24) | (0x1 << 22) | (rs->id << 5) | rd->id; + + if (1 == src_size) + opcode |= 0x7 << 10; + + else if (2 == src_size) + opcode |= 0xf << 10; + + else if (4 == src_size) + opcode |= 0x1f << 10; + + } else { + opcode = (0x53 << 24) | (rs->id << 5) | rd->id; + + if (1 == src_size) + opcode |= 0x7 << 10; + + else if (2 == src_size) + opcode |= 0xf << 10; + } + } + + if (0 == opcode) + opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_div_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (src->dag_node->var->size != dst->dag_node->var->size) + return -EINVAL; + + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(s->var)) { + + if (0 == s->color) { + s->color = -1; + s->var->global_flag = 1; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = (0x1e << 24) | (0x1 << 21) | (0x3 << 11); + opcode |= (rs->id << 16) | (rd->id << 5) | rd->id; + opcode |= ((8 == rd->bytes) << 22); + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + + if (!scf_variable_const_interger(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + int ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs, s->var->data.u64, rs->bytes); + if (ret < 0) + return ret; + + } else + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + opcode = ((8 == rd->bytes) << 31) | (0x1a << 24) | (0x3 << 22) | (rs->id << 16) | (0x2 << 10) | (rd->id << 5) | rd->id; + + if (scf_variable_signed(s->var)) + opcode |= 0x3 << 10; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_mod_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (src->dag_node->var->size != dst->dag_node->var->size) + return -EINVAL; + + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* r = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + assert(0 != d->color); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + if (scf_variable_float(src->dag_node->var)) { + + assert(scf_variable_float(dst->dag_node->var)); + return -EINVAL; + } + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + + if (!scf_variable_const_interger(s->var)) { + scf_loge("\n"); + return -EINVAL; + } + + int ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs, s->var->data.u64, rs->bytes); + if (ret < 0) + return ret; + + } else + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + int ret = arm64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; + + opcode = ((8 == rd->bytes) << 31) | (0x1a << 24) | (0x3 << 22) | (rs->id << 16) | (0x2 << 10) | (rd->id << 5) | r->id; + + if (scf_variable_signed(s->var)) + opcode |= 0x3 << 10; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + opcode = ((8 == rd->bytes) << 31) | (0x1b << 24) | (rs->id << 16) | (0x1 << 15) | (rd->id << 10) | (r->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +static int _arm64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->srcs || c->srcs->size < 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = NULL; + scf_variable_t* v = NULL; + scf_instruction_t* inst = NULL; + scf_rela_t* rela = NULL; + + scf_register_arm64_t* rd = NULL; + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* sp = arm64_find_register("sp"); + scf_register_arm64_t* fp = arm64_find_register("fp"); + + scf_arm64_OpCode_t* pop; + scf_arm64_OpCode_t* mov; + scf_arm64_OpCode_t* ret; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -2149,6 +3737,13 @@ static int _arm64_inst_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) r = arm64_find_register_type_id_bytes(0, arm64_abi_callee_saves[i], 8); + if (!r->used) { + r = arm64_find_register_type_id_bytes(0, arm64_abi_callee_saves[i], 4); + + if (!r->used) + continue; + } + uint32_t pop = (0xf8 << 24) | (0x1 << 22) | (0x8 << 12) | (0x1 << 10) | (0x1f << 5) | r->id; inst = arm64_make_inst(c, pop); @@ -2362,7 +3957,7 @@ static int _arm64_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_arm64_t* rm = NULL; + scf_register_arm64_t* rs = NULL; scf_register_arm64_t* rd = NULL; scf_instruction_t* inst = NULL; scf_dag_node_t* d = dst->dag_node; @@ -2376,13 +3971,24 @@ static int _arm64_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) int size = arm64_variable_size(v); int is_float = scf_variable_float(v); + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + if (is_float) { assert(scf_variable_float(v)); - scf_loge("\n"); - return -EINVAL; - } - ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + if (0 == s->color) { + s->color = -1; + v->global_flag = 1; + return arm64_make_inst_M2GF(c, f, rd, NULL, v); + } + + ARM64_SELECT_REG_CHECK(&rs, d, c, f, 1); + + opcode = (0x1e << 24) | ((8 == rd->bytes) << 22) | (0x1 << 21) | (rs->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; + } if (0 == s->color) { @@ -2400,182 +4006,196 @@ static int _arm64_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) return arm64_make_inst_I2G(c, rd, v->data.u64, rd->bytes); } - ARM64_SELECT_REG_CHECK(&rm, s, c, f, 1); + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); - opcode = (0xaa << 24) | (rm->id << 16) | (0x1f << 5) | rd->id; + opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id; inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } -static int _arm64_inst_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_shift(scf_native_t* ctx, scf_3ac_code_t* c) { - return -1; -} + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; -static int _arm64_inst_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - return -1; -} + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; -#define ARM64_INST_BINARY_ASSIGN(name, op) \ -static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} \ -static int _arm64_inst_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} \ -static int _arm64_inst_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -}\ -static int _arm64_inst_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -} -// return arm64_binary_assign(ctx, c, SCF_ARM64_##op); \ - return arm64_binary_assign_pointer(ctx, c, SCF_ARM64_##op); \ - return _arm64_inst_assign_array_index(ctx, c, SCF_ARM64_##op);\ - return arm64_binary_assign_dereference(ctx, c, SCF_ARM64_##op); - -ARM64_INST_BINARY_ASSIGN(add_assign, ADD) -ARM64_INST_BINARY_ASSIGN(sub_assign, SUB) -ARM64_INST_BINARY_ASSIGN(and_assign, AND) -ARM64_INST_BINARY_ASSIGN(or_assign, OR) - -#define ARM64_INST_SHIFT(name, op) \ -static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} \ -static int _arm64_inst_##name##_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} - //return arm64_shift(ctx, c, SCF_ARM64_##op); \ - return arm64_shift_assign(ctx, c, SCF_ARM64_##op); -ARM64_INST_SHIFT(shl, SHL) -ARM64_INST_SHIFT(shr, SHR) + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src0 = c->srcs->data[0]; + scf_3ac_operand_t* src1 = c->srcs->data[1]; + scf_3ac_operand_t* dst = c->dsts->data[0]; -#define ARM64_INST_UNARY_ASSIGN(name, op) \ -static int _arm64_inst_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} \ -static int _arm64_inst_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -}\ -static int _arm64_inst_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -} -// return arm64_unary_assign_pointer(ctx, c, SCF_ARM64_##op); \ - return arm64_unary_assign_array_index(ctx, c, SCF_ARM64_##op);\ - return arm64_unary_assign_dereference(ctx, c, SCF_ARM64_##op); -ARM64_INST_UNARY_ASSIGN(inc, INC) -ARM64_INST_UNARY_ASSIGN(dec, DEC) - -#define ARM64_INST_UNARY_POST_ASSIGN(name, op) \ -static int _arm64_inst_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) \ -{ \ - return -1;\ -} \ -static int _arm64_inst_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -}\ -static int _arm64_inst_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c)\ -{\ - return -1;\ -} - //int ret = arm64_inst_dereference(ctx, c); \ - if (ret < 0) \ - return ret; \ - return arm64_unary_assign_dereference(ctx, c, SCF_ARM64_##op); \ - int ret = _arm64_inst_array_index_handler(ctx, c); \ - if (ret < 0) \ - return ret; \ - return arm64_unary_assign_array_index(ctx, c, SCF_ARM64_##op);\ - int ret = arm64_inst_pointer(ctx, c, 0); \ - if (ret < 0) \ - return ret; \ - return arm64_unary_assign_pointer(ctx, c, SCF_ARM64_##op); -ARM64_INST_UNARY_POST_ASSIGN(inc_post, INC) -ARM64_INST_UNARY_POST_ASSIGN(dec_post, DEC) + if (!src0 || !src0->dag_node) + return -EINVAL; -static int _arm64_inst_address_of_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - //return _arm64_inst_array_index(ctx, c, 1); - return -1; -} + if (!src1 || !src1->dag_node) + return -EINVAL; -static int _arm64_inst_address_of_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ - //return arm64_inst_pointer(ctx, c, 1); - return -1; -} + if (!dst || !dst->dag_node) + return -EINVAL; -static int _arm64_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) -{ if (!c->instructions) { c->instructions = scf_vector_alloc(); if (!c->instructions) return -ENOMEM; } - scf_register_arm64_t* rax = arm64_find_register("rax"); - scf_arm64_OpCode_t* push; - scf_instruction_t* inst; + scf_register_arm64_t* rs0 = NULL; + scf_register_arm64_t* rs1 = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst ->dag_node; + scf_dag_node_t* s0 = src0->dag_node; + scf_dag_node_t* s1 = src1->dag_node; -#if 0 - push = arm64_find_OpCode(SCF_ARM64_PUSH, 8,8, SCF_ARM64_G); - inst = arm64_make_inst_G(push, rax); + uint32_t opcode; + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s0->color) { + + if (scf_variable_signed(s0->var)) + scf_variable_sign_extend(s0->var, 8); + else + scf_variable_zero_extend(s0->var, 8); + + int ret = arm64_make_inst_I2G(c, rd, s0->var->data.u64, rd->bytes); + if (ret < 0) + return ret; + + rs0 = rd; + } else + ARM64_SELECT_REG_CHECK(&rs0, s0, c, f, 1); + + if (0 == s1->color) { + + int ret = arm64_select_free_reg(&rs1, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs1, s1->var->data.u64, 1); + if (ret < 0) + return ret; + } else + ARM64_SELECT_REG_CHECK(&rs1, s1, c, f, 1); + + uint32_t op = (0x9a << 24) | (0x3 << 22) | (0x1 << 13); + + if (SCF_OP_SHR == c->op->type) { + if (scf_variable_signed(s0->var)) + op |= 0x1 << 11; + else + op |= 0x1 << 10; + } + + opcode = op | (rs1->id << 16) | (rs0->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; -#endif - return -1; } -static int _arm64_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_shift_assign(scf_native_t* ctx, scf_3ac_code_t* c) { + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* dst = c->dsts->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!dst || !dst->dag_node) + return -EINVAL; + if (!c->instructions) { c->instructions = scf_vector_alloc(); if (!c->instructions) return -ENOMEM; } - scf_register_arm64_t* rax = arm64_find_register("rax"); - scf_arm64_OpCode_t* pop; - scf_instruction_t* inst; -#if 0 - pop = arm64_find_OpCode(SCF_ARM64_POP, 8,8, SCF_ARM64_G); - inst = arm64_make_inst_G(pop, rax); + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + scf_instruction_t* inst = NULL; + scf_dag_node_t* d = dst->dag_node; + scf_dag_node_t* s = src->dag_node; + + uint32_t opcode; + + ARM64_SELECT_REG_CHECK(&rd, d, c, f, 0); + + if (0 == s->color) { + + int ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, rs, s->var->data.u64, 1); + if (ret < 0) + return ret; + } else + ARM64_SELECT_REG_CHECK(&rs, s, c, f, 1); + + uint32_t op = (0x9a << 24) | (0x3 << 22) | (0x1 << 13); + + if (SCF_OP_SHR == c->op->type) { + if (scf_variable_signed(s->var)) + op |= 0x1 << 11; + else + op |= 0x1 << 10; + } + + opcode = op | (rs->id << 16) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; -#endif - return -1; } -/* +static int _arm64_inst_shl_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_shift(ctx, c); +} -struct va_list +static int _arm64_inst_shr_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - uint8_t* iptr; - uint8_t* fptr; - uint8_t* optr; + return _arm64_inst_shift(ctx, c); +} - intptr_t ireg; - intptr_t freg; -}; -*/ +static int _arm64_inst_shl_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_shift_assign(ctx, c); +} -static int _arm64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_shr_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + return _arm64_inst_shift_assign(ctx, c); +} + +static int _arm64_inst_binary_assign_dereference(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op) +{ + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; + + scf_arm64_context_t* arm64 = ctx->priv; + scf_function_t* f = arm64->f; + + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_3ac_operand_t* src = c->srcs->data[1]; + scf_instruction_t* inst; + + if (!base || !base->dag_node) + return -EINVAL; + + if (!src || !src->dag_node) + return -EINVAL; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -2583,130 +4203,154 @@ static int _arm64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_loge("c->srcs->size: %d\n", c->srcs->size); - assert(3 == c->srcs->size); + scf_variable_t* vs = src ->dag_node->var; + scf_variable_t* vb = base->dag_node->var; - scf_register_arm64_t* rbp = arm64_find_register("rbp"); - scf_register_arm64_t* rptr = NULL; - scf_register_arm64_t* rap = NULL; - scf_instruction_t* inst = NULL; - scf_3ac_operand_t* ap = c->srcs->data[0]; - scf_3ac_operand_t* ptr = c->srcs->data[2]; - scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_G2E); - scf_arm64_OpCode_t* lea = arm64_find_OpCode(SCF_ARM64_LEA, 8, 8, SCF_ARM64_E2G); - scf_variable_t* v = ap->dag_node->var; + scf_register_arm64_t* rs = NULL; + scf_register_arm64_t* rd = NULL; + arm64_sib_t sib = {0}; - int offset_int = -f->args_int * 8 - 8; - int offset_float = -f->args_float * 8 - ARM64_ABI_NB * 8 - 8; - int offset_others = 16; + int ret = arm64_dereference_reg(&sib, base->dag_node, NULL, c, f); + if (ret < 0) + return ret; - if (v->bp_offset >= 0) { - scf_loge("\n"); - return -1; - } -#if 0 - ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); - ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); + int is_float = scf_variable_float(vs); - inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_int); - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (0 == src->dag_node->color) { - inst = arm64_make_inst_G2P(mov, rap, 0, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (is_float) { + src->dag_node->color = -1; + vs->global_flag = 1; - inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_float); - ARM64_INST_ADD_CHECK(c->instructions, inst); + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - inst = arm64_make_inst_G2P(mov, rap, 8, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); + } else { + ret = arm64_select_free_reg(&rs, c, f, 0); + if (ret < 0) + return ret; + ret = arm64_make_inst_I2G(c, rs, vs->data.u64, sib.size); + if (ret < 0) + return ret; - inst = arm64_make_inst_P2G(lea, rptr, rbp, offset_others); - ARM64_INST_ADD_CHECK(c->instructions, inst); + rs = arm64_find_register_color_bytes(rs->color, sib.size); + } + } else + ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); - inst = arm64_make_inst_G2P(mov, rap, 16, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (op) { + uint32_t opcode; - mov = arm64_find_OpCode(SCF_ARM64_MOV, 4, 8, SCF_ARM64_I2E); + ret = arm64_select_free_reg(&rd, c, f, is_float); + if (ret < 0) + return ret; - inst = arm64_make_inst_I2P(mov, rap, 24, (uint8_t*)&f->args_int, 4); - ARM64_INST_ADD_CHECK(c->instructions, inst); + ret = arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size); + if (ret < 0) + return ret; - inst = arm64_make_inst_I2P(mov, rap, 32, (uint8_t*)&f->args_float, 4); - ARM64_INST_ADD_CHECK(c->instructions, inst); - return 0; -#endif - return -1; + opcode = ((8 == sib.size) << 31)| op | (rs->id << 16) | (rd->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + rs = rd; + } + + return arm64_make_inst_G2P(c, f, rs, sib.base, sib.disp, sib.size); } -static int _arm64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + return _arm64_inst_binary_assign_dereference(ctx, c, 0); +} - if (!c->instructions) { - c->instructions = scf_vector_alloc(); - if (!c->instructions) - return -ENOMEM; - } +static int _arm64_inst_add_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_dereference(ctx, c, 0x0b << 24); +} - assert(2 == c->srcs->size); +static int _arm64_inst_sub_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_dereference(ctx, c, 0x4b << 24); +} - scf_register_arm64_t* rbp = arm64_find_register("rbp"); - scf_register_arm64_t* rptr = NULL; - scf_register_arm64_t* rap = NULL; - scf_instruction_t* inst = NULL; - scf_3ac_operand_t* ap = c->srcs->data[0]; - scf_3ac_operand_t* ptr = c->srcs->data[1]; - scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_G2E); - scf_arm64_OpCode_t* xor = arm64_find_OpCode(SCF_ARM64_XOR, 8, 8, SCF_ARM64_G2E); - scf_variable_t* v = ap->dag_node->var; +static int _arm64_inst_and_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_dereference(ctx, c, 0x0a << 24); +} - if (v->bp_offset >= 0) { - scf_loge("\n"); - return -1; - } +static int _arm64_inst_or_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_dereference(ctx, c, 0x2a << 24); +} - ptr->dag_node->var->tmp_flag = 1; - ptr->dag_node->color = -1; -#if 0 - ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); - ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); +static int _arm64_inst_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_pointer(ctx, c, 0); +} - inst = arm64_make_inst_G2E(xor, rptr, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_add_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_pointer(ctx, c, 0x0b << 24); +} - inst = arm64_make_inst_G2P(mov, rap, 0, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_sub_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_pointer(ctx, c, 0x4b << 24); +} - inst = arm64_make_inst_G2P(mov, rap, 8, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_and_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_pointer(ctx, c, 0x0a << 24); +} - inst = arm64_make_inst_G2P(mov, rap, 16, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_or_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_pointer(ctx, c, 0x2a << 24); +} - inst = arm64_make_inst_G2P(mov, rap, 24, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_array_index(ctx, c, 0); +} - inst = arm64_make_inst_G2P(mov, rap, 32, rptr); - ARM64_INST_ADD_CHECK(c->instructions, inst); +static int _arm64_inst_add_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_array_index(ctx, c, 0x0b << 24); +} - ptr->dag_node->var->tmp_flag = 0; - ptr->dag_node->color = 0; - ptr->dag_node->loaded = 0; +static int _arm64_inst_sub_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_array_index(ctx, c, 0x4b << 24); +} - assert(0 == scf_vector_del(rptr->dag_nodes, ptr->dag_node)); - return 0; -#endif - return -1; +static int _arm64_inst_and_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_array_index(ctx, c, 0x0a << 24); } -static int _arm64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _arm64_inst_or_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inst_binary_assign_array_index(ctx, c, 0x2a << 24); +} + +static int _arm64_inc_dec_dereference(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) { + if (!c->srcs || c->srcs->size != 1) { + scf_loge("\n"); + return -EINVAL; + } + + scf_register_arm64_t* r = NULL; scf_arm64_context_t* arm64 = ctx->priv; - scf_function_t* f = arm64->f; + scf_3ac_operand_t* base = c->srcs->data[0]; + scf_instruction_t* inst; + scf_function_t* f = arm64->f; + + if (!base || !base->dag_node) + return -EINVAL; if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -2714,108 +4358,106 @@ static int _arm64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - assert(1 == c->dsts->size && 3 == c->srcs->size); + arm64_sib_t sib = {0}; - scf_register_arm64_t* rbp = arm64_find_register("rbp"); - scf_register_arm64_t* rd = NULL; // result - scf_register_arm64_t* rap = NULL; // ap - scf_register_arm64_t* rptr = NULL; // ptr - scf_instruction_t* inst = NULL; + int size = base->dag_node->var->data_size; - scf_instruction_t* inst_jge = NULL; - scf_instruction_t* inst_jmp = NULL; + int ret = arm64_dereference_reg(&sib, base->dag_node, NULL, c, f); + if (ret < 0) + return ret; - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_3ac_operand_t* ap = c->srcs->data[0]; - scf_3ac_operand_t* src = c->srcs->data[1]; - scf_3ac_operand_t* ptr = c->srcs->data[2]; - scf_variable_t* v = src->dag_node->var; + ret = arm64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; -#if 0 - scf_arm64_OpCode_t* inc = arm64_find_OpCode(SCF_ARM64_INC, 8, 8, SCF_ARM64_E); - scf_arm64_OpCode_t* add = arm64_find_OpCode(SCF_ARM64_ADD, 4, 8, SCF_ARM64_I2E); - scf_arm64_OpCode_t* sub = arm64_find_OpCode(SCF_ARM64_SUB, 4, 8, SCF_ARM64_I2E); - scf_arm64_OpCode_t* cmp = arm64_find_OpCode(SCF_ARM64_CMP, 4, 8, SCF_ARM64_I2E); - scf_arm64_OpCode_t* mov = arm64_find_OpCode(SCF_ARM64_MOV, 8, 8, SCF_ARM64_E2G); - scf_arm64_OpCode_t* jge = arm64_find_OpCode(SCF_ARM64_JGE, 4, 4, SCF_ARM64_I); - scf_arm64_OpCode_t* jmp = arm64_find_OpCode(SCF_ARM64_JMP, 4, 4, SCF_ARM64_I); - scf_arm64_OpCode_t* mov2 = NULL; + ret = arm64_make_inst_P2G(c, f, r, sib.base, 0, size); + if (ret < 0) + return ret; - ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - ARM64_SELECT_REG_CHECK(&rap, ap ->dag_node, c, f, 1); - ARM64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0); + uint32_t opcode = (u24 << 24) | (0x1 << 10) | (r->id << 5) | r->id; - int is_float = scf_variable_float(v); - int size = arm64_variable_size(v); + if (size > 4) + opcode |= 0x1 << 31; - uint32_t nints = ARM64_ABI_NB; - uint32_t nfloats = ARM64_ABI_NB; - uint32_t offset = 0; - uint32_t incptr = 8; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); - int idx_offset = 24; - int ptr_offset = 0; + return arm64_make_inst_G2P(c, f, r, sib.base, 0, size); +} - if (is_float) { - idx_offset = 32; - ptr_offset = 8; - } +static int _arm64_inc_dec_post_dereference(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t u24) +{ + if (!c->srcs || c->srcs->size != 1) + return -EINVAL; - inst = arm64_make_inst_I2P(cmp, rap, idx_offset, (uint8_t*)&nints, 4); - ARM64_INST_ADD_CHECK(c->instructions, inst); + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; - inst_jge = arm64_make_inst_I(jge, (uint8_t*)&offset, sizeof(offset)); - ARM64_INST_ADD_CHECK(c->instructions, inst_jge); + scf_register_arm64_t* rd = NULL; + scf_arm64_context_t* arm64 = 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 = arm64->f; + if (!base || !base->dag_node) + return -EINVAL; - inst = arm64_make_inst_P2G(mov, rptr, rap, ptr_offset); - ARM64_INST_ADD_CHECK(c->instructions, inst); - offset += inst->len; + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } - inst = arm64_make_inst_I2P(sub, rap, ptr_offset, (uint8_t*)&incptr, 4); - ARM64_INST_ADD_CHECK(c->instructions, inst); - offset += inst->len; + arm64_sib_t sib = {0}; - inst_jmp = arm64_make_inst_I(jmp, (uint8_t*)&offset, sizeof(offset)); - ARM64_INST_ADD_CHECK(c->instructions, inst_jmp); - offset += inst_jmp->len; + int size = base->dag_node->var->data_size; - uint8_t* p = (uint8_t*)&offset; - int i; - for (i = 0; i < 4; i++) - inst_jge->code[jge->nb_OpCodes + i] = p[i]; + int ret = arm64_dereference_reg(&sib, base->dag_node, NULL, c, f); + if (ret < 0) + return ret; - offset = 0; - inst = arm64_make_inst_P2G(mov, rptr, rap, 16); - ARM64_INST_ADD_CHECK(c->instructions, inst); - offset += inst->len; + ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); - inst = arm64_make_inst_I2P(add, rap, 16, (uint8_t*)&incptr, 4); - ARM64_INST_ADD_CHECK(c->instructions, inst); - offset += inst->len; + ret = arm64_make_inst_P2G(c, f, rd, sib.base, 0, size); + if (ret < 0) + return ret; - for (i = 0; i < 4; i++) - inst_jmp->code[jmp->nb_OpCodes + i] = p[i]; + uint32_t opcode = (u24 << 24) | (0x1 << 10) | (rd->id << 5) | rd->id; - inst = arm64_make_inst_P(inc, rap, idx_offset, 8); + if (size > 4) + opcode |= 0x1 << 31; + + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); - if (is_float) { - if (4 == size) - mov2 = arm64_find_OpCode(SCF_ARM64_MOVSS, 4, 4, SCF_ARM64_E2G); - else if (8 == size) - mov2 = arm64_find_OpCode(SCF_ARM64_MOVSD, 8, 8, SCF_ARM64_E2G); - else - assert(0); - } else - mov2 = arm64_find_OpCode(SCF_ARM64_MOV, size, size, SCF_ARM64_E2G); + ret = arm64_make_inst_G2P(c, f, rd, sib.base, 0, size); + if (ret < 0) + return ret; - inst = arm64_make_inst_P2G(mov2, rd, rptr, 0); + opcode &= ~(0x1 << 30); ARM64_INST_ADD_CHECK(c->instructions, inst); - return 0; -#endif - return -1; +} + +static int _arm64_inst_dec_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inc_dec_dereference(ctx, c, 0x51); +} + +static int _arm64_inst_inc_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inc_dec_dereference(ctx, c, 0x11); +} + +static int _arm64_inst_dec_post_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inc_dec_post_dereference(ctx, c, 0x51); +} + +static int _arm64_inst_inc_post_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + return _arm64_inc_dec_post_dereference(ctx, c, 0x11); } static arm64_inst_handler_t arm64_inst_handlers[] = { diff --git a/native/arm64/scf_arm64_rcg.c b/native/arm64/scf_arm64_rcg.c index 5b0bf39..bb92b25 100644 --- a/native/arm64/scf_arm64_rcg.c +++ b/native/arm64/scf_arm64_rcg.c @@ -32,7 +32,7 @@ int arm64_rcg_find_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* d return 0; } -int _arm64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg, scf_arm64_OpCode_t* OpCode) +int _arm64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg) { arm64_rcg_node_t* rn = calloc(1, sizeof(arm64_rcg_node_t)); if (!rn) @@ -40,7 +40,7 @@ int _arm64_rcg_make_node(scf_graph_node_t** pp, scf_graph_t* g, scf_dag_node_t* rn->dag_node = dn; rn->reg = reg; - rn->OpCode = OpCode; + rn->OpCode = NULL; scf_graph_node_t* gn = scf_vector_find_cmp(g->nodes, rn, _arm64_rcg_node_cmp); if (!gn) { @@ -119,7 +119,7 @@ static int _arm64_rcg_active_vars(scf_graph_t* g, scf_vector_t* active_vars) if (!ds0->active) continue; - ret = _arm64_rcg_make_node(&gn0, g, dn0, NULL, NULL); + ret = _arm64_rcg_make_node(&gn0, g, dn0, NULL); if (ret < 0) return ret; @@ -131,7 +131,7 @@ static int _arm64_rcg_active_vars(scf_graph_t* g, scf_vector_t* active_vars) if (!ds1->active) continue; - ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL, NULL); + ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL); if (ret < 0) return ret; @@ -168,7 +168,7 @@ static int _arm64_rcg_operands(scf_graph_t* g, scf_vector_t* operands) if (scf_variable_const(dn0->var)) continue; - int ret = _arm64_rcg_make_node(&gn0, g, dn0, NULL, NULL); + int ret = _arm64_rcg_make_node(&gn0, g, dn0, NULL); if (ret < 0) return ret; @@ -180,7 +180,7 @@ static int _arm64_rcg_operands(scf_graph_t* g, scf_vector_t* operands) if (scf_variable_const(dn1->var)) continue; - ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL, NULL); + ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL); if (ret < 0) return ret; @@ -213,7 +213,7 @@ static int _arm64_rcg_to_active_vars(scf_graph_t* g, scf_graph_node_t* gn0, scf_ if (!ds1->active) continue; - ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL, NULL); + ret = _arm64_rcg_make_node(&gn1, g, dn1, NULL); if (ret < 0) return ret; @@ -228,8 +228,7 @@ static int _arm64_rcg_to_active_vars(scf_graph_t* g, scf_graph_node_t* gn0, scf_ return 0; } -static int _arm64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, - scf_register_arm64_t* reg, scf_arm64_OpCode_t* OpCode) +int arm64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_arm64_t* reg) { scf_graph_node_t* gn0 = NULL; scf_graph_node_t* gn1; @@ -240,7 +239,7 @@ static int _arm64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn int i; if (dn || reg) { - ret = _arm64_rcg_make_node(&gn0, g, dn, reg, OpCode); + ret = _arm64_rcg_make_node(&gn0, g, dn, reg); if (ret < 0) { scf_loge("\n"); return ret; @@ -261,7 +260,7 @@ static int _arm64_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn return 0; } -static int _arm64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_arm64_t* reg, scf_arm64_OpCode_t* OpCode) +static int _arm64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_arm64_t* reg) { if (c->rcg) scf_graph_free(c->rcg); @@ -270,7 +269,7 @@ static int _arm64_rcg_make2(scf_3ac_code_t* c, scf_dag_node_t* dn, scf_register_ if (!c->rcg) return -ENOMEM; - return _arm64_rcg_make(c, c->rcg, dn, reg, OpCode); + return arm64_rcg_make(c, c->rcg, dn, reg); } static int _arm64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -333,7 +332,7 @@ static int _arm64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) r = NULL; gn = NULL; - ret = _arm64_rcg_make_node(&gn, g, dn, r, NULL); + ret = _arm64_rcg_make_node(&gn, g, dn, r); if (ret < 0) { scf_loge("\n"); return ret; @@ -360,7 +359,7 @@ static int _arm64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) continue; gn = NULL; - ret = _arm64_rcg_make_node(&gn, g, dn, dn->rabi2, NULL); + ret = _arm64_rcg_make_node(&gn, g, dn, dn->rabi2); if (ret < 0) { scf_loge("\n"); return ret; @@ -373,7 +372,7 @@ static int _arm64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) if (!dn_pf->var->const_literal_flag) { - ret = _arm64_rcg_make_node(&gn_pf, g, dn_pf, NULL, NULL); + ret = _arm64_rcg_make_node(&gn_pf, g, dn_pf, NULL); if (ret < 0) { scf_loge("\n"); return ret; @@ -386,7 +385,7 @@ static int _arm64_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) rabi = arm64_find_register_type_id_bytes(0, arm64_abi_regs[i], dn_pf->var->size); - ret = _arm64_rcg_make_node(&gn_rabi, g, NULL, rabi, NULL); + ret = _arm64_rcg_make_node(&gn_rabi, g, NULL, rabi); if (ret < 0) { scf_loge("\n"); return ret; @@ -423,115 +422,115 @@ static int _arm64_rcg_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_ { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_bit_not_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_address_of_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -552,7 +551,7 @@ static int _arm64_rcg_mul_div_mod(scf_native_t* ctx, scf_3ac_code_t* c, scf_grap dn = dst->dag_node; } - return _arm64_rcg_make(c, g, dn, NULL, NULL); + return arm64_rcg_make(c, g, dn, NULL); } static int _arm64_rcg_mul_div_mod2(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -590,22 +589,22 @@ static int _arm64_rcg_add_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_grap { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -626,7 +625,7 @@ static int _arm64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g dn = dst->dag_node; } - return _arm64_rcg_make(c, g, dn, NULL, NULL); + return arm64_rcg_make(c, g, dn, NULL); } static int _arm64_rcg_shift2(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -659,40 +658,40 @@ static int _arm64_rcg_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_ { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } #define ARM64_RCG_SET(setcc) \ @@ -700,10 +699,10 @@ static int _arm64_rcg_##setcc##_handler(scf_native_t* ctx, scf_3ac_code_t* c, sc { \ scf_3ac_operand_t* dst = c->dsts->data[0]; \ \ - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ + return arm64_rcg_make(c, g, dst->dag_node, NULL); \ } ARM64_RCG_SET(setz) ARM64_RCG_SET(setnz) @@ -716,77 +715,77 @@ static int _arm64_rcg_eq_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_ne_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_gt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_lt_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_add_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_sub_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_mul_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -818,22 +817,22 @@ static int _arm64_rcg_and_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, s { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -845,11 +844,11 @@ static int _arm64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_g scf_graph_node_t* gn; scf_dag_node_t* dn; - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - ret = _arm64_rcg_make(c, g, NULL, NULL, NULL); + ret = arm64_rcg_make(c, g, NULL, NULL); if (ret < 0) return ret; @@ -875,7 +874,7 @@ static int _arm64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_g } else r = arm64_find_register_type_id_bytes(is_float, arm64_abi_ret_regs[i], size); - ret = _arm64_rcg_make_node(&gn, g, dn, r, NULL); + ret = _arm64_rcg_make_node(&gn, g, dn, r); if (ret < 0) return ret; } @@ -892,11 +891,11 @@ static int _arm64_rcg_memset_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_g scf_graph_node_t* gn; scf_dag_node_t* dn; - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - ret = _arm64_rcg_make(c, g, NULL, NULL, NULL); + ret = arm64_rcg_make(c, g, NULL, NULL); if (ret < 0) return ret; @@ -954,11 +953,11 @@ ARM64_RCG_JCC(jbe) static int _arm64_rcg_save_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_load_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -977,24 +976,24 @@ static int _arm64_rcg_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_grap #define ARM64_RCG_BINARY_ASSIGN(name) \ static int _arm64_rcg_##name##_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } \ static int _arm64_rcg_##name##_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } \ static int _arm64_rcg_##name##_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } ARM64_RCG_BINARY_ASSIGN(add) @@ -1021,31 +1020,31 @@ ARM64_RCG_SHIFT_ASSIGN(shr) #define ARM64_RCG_UNARY_ASSIGN(name) \ static int _arm64_rcg_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } \ static int _arm64_rcg_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } \ static int _arm64_rcg_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } \ static int _arm64_rcg_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, NULL, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, NULL, NULL, NULL); \ + return arm64_rcg_make(c, g, NULL, NULL); \ } ARM64_RCG_UNARY_ASSIGN(inc) ARM64_RCG_UNARY_ASSIGN(dec) @@ -1055,37 +1054,37 @@ static int _arm64_rcg_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf { \ scf_3ac_operand_t* dst = c->dsts->data[0]; \ \ - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ + return arm64_rcg_make(c, g, dst->dag_node, NULL); \ } \ static int _arm64_rcg_##name##_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ scf_3ac_operand_t* dst = c->dsts->data[0]; \ \ - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ + return arm64_rcg_make(c, g, dst->dag_node, NULL); \ } \ static int _arm64_rcg_##name##_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ scf_3ac_operand_t* dst = c->dsts->data[0]; \ \ - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ + return arm64_rcg_make(c, g, dst->dag_node, NULL); \ } \ static int _arm64_rcg_##name##_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \ { \ scf_3ac_operand_t* dst = c->dsts->data[0]; \ \ - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); \ + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); \ if (ret < 0) \ return ret; \ - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); \ + return arm64_rcg_make(c, g, dst->dag_node, NULL); \ } ARM64_RCG_UNARY_POST_ASSIGN(inc_post) ARM64_RCG_UNARY_POST_ASSIGN(dec_post) @@ -1094,20 +1093,20 @@ static int _arm64_rcg_address_of_array_index_handler(scf_native_t* ctx, scf_3ac_ { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_address_of_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static int _arm64_rcg_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) @@ -1121,28 +1120,28 @@ static int _arm64_rcg_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_ static int _arm64_rcg_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { - int ret = _arm64_rcg_make2(c, NULL, NULL, NULL); + int ret = _arm64_rcg_make2(c, NULL, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, NULL, NULL, NULL); + return arm64_rcg_make(c, g, NULL, NULL); } static int _arm64_rcg_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { scf_3ac_operand_t* dst = c->dsts->data[0]; - int ret = _arm64_rcg_make2(c, dst->dag_node, NULL, NULL); + int ret = _arm64_rcg_make2(c, dst->dag_node, NULL); if (ret < 0) return ret; - return _arm64_rcg_make(c, g, dst->dag_node, NULL, NULL); + return arm64_rcg_make(c, g, dst->dag_node, NULL); } static arm64_rcg_handler_t arm64_rcg_handlers[] = { diff --git a/native/arm64/scf_arm64_reg.c b/native/arm64/scf_arm64_reg.c index 4c66269..a6a717f 100644 --- a/native/arm64/scf_arm64_reg.c +++ b/native/arm64/scf_arm64_reg.c @@ -2,129 +2,233 @@ scf_register_arm64_t arm64_registers[] = { - {0, 4, "w0", ARM64_COLOR(0, 0, 0xf), NULL, 0}, - {0, 8, "x0", ARM64_COLOR(0, 0, 0xff), NULL, 0}, + {0, 4, "w0", ARM64_COLOR(0, 0, 0xf), NULL, 0, 0}, + {0, 8, "x0", ARM64_COLOR(0, 0, 0xff), NULL, 0, 0}, - {1, 4, "w1", ARM64_COLOR(0, 1, 0xf), NULL, 0}, - {1, 8, "x1", ARM64_COLOR(0, 1, 0xff), NULL, 0}, + {1, 4, "w1", ARM64_COLOR(0, 1, 0xf), NULL, 0, 0}, + {1, 8, "x1", ARM64_COLOR(0, 1, 0xff), NULL, 0, 0}, - {2, 4, "w2", ARM64_COLOR(0, 2, 0xf), NULL, 0}, - {2, 8, "x2", ARM64_COLOR(0, 2, 0xff), NULL, 0}, + {2, 4, "w2", ARM64_COLOR(0, 2, 0xf), NULL, 0, 0}, + {2, 8, "x2", ARM64_COLOR(0, 2, 0xff), NULL, 0, 0}, - {3, 4, "w3", ARM64_COLOR(0, 3, 0xf), NULL, 0}, - {3, 8, "x3", ARM64_COLOR(0, 3, 0xff), NULL, 0}, + {3, 4, "w3", ARM64_COLOR(0, 3, 0xf), NULL, 0, 0}, + {3, 8, "x3", ARM64_COLOR(0, 3, 0xff), NULL, 0, 0}, - {4, 4, "w4", ARM64_COLOR(0, 4, 0xf), NULL, 0}, - {4, 8, "x4", ARM64_COLOR(0, 4, 0xff), NULL, 0}, + {4, 4, "w4", ARM64_COLOR(0, 4, 0xf), NULL, 0, 0}, + {4, 8, "x4", ARM64_COLOR(0, 4, 0xff), NULL, 0, 0}, - {5, 4, "w5", ARM64_COLOR(0, 5, 0xf), NULL, 0}, - {5, 8, "x5", ARM64_COLOR(0, 5, 0xff), NULL, 0}, + {5, 4, "w5", ARM64_COLOR(0, 5, 0xf), NULL, 0, 0}, + {5, 8, "x5", ARM64_COLOR(0, 5, 0xff), NULL, 0, 0}, - {6, 4, "w6", ARM64_COLOR(0, 6, 0xf), NULL, 0}, - {6, 8, "x6", ARM64_COLOR(0, 6, 0xff), NULL, 0}, + {6, 4, "w6", ARM64_COLOR(0, 6, 0xf), NULL, 0, 0}, + {6, 8, "x6", ARM64_COLOR(0, 6, 0xff), NULL, 0, 0}, - {7, 4, "w7", ARM64_COLOR(0, 7, 0xf), NULL, 0}, - {7, 8, "x7", ARM64_COLOR(0, 7, 0xff), NULL, 0}, + {7, 4, "w7", ARM64_COLOR(0, 7, 0xf), NULL, 0, 0}, + {7, 8, "x7", ARM64_COLOR(0, 7, 0xff), NULL, 0, 0}, // not use x8 // {8, 4, "w8", ARM64_COLOR(0, 8, 0xf), NULL, 0}, // {8, 8, "x8", ARM64_COLOR(0, 8, 0xff), NULL, 0}, - {9, 4, "w9", ARM64_COLOR(0, 9, 0xf), NULL, 0}, - {9, 8, "x9", ARM64_COLOR(0, 9, 0xff), NULL, 0}, + {9, 4, "w9", ARM64_COLOR(0, 9, 0xf), NULL, 0, 0}, + {9, 8, "x9", ARM64_COLOR(0, 9, 0xff), NULL, 0, 0}, - {10, 4, "w10", ARM64_COLOR(0, 10, 0xf), NULL, 0}, - {10, 8, "x10", ARM64_COLOR(0, 10, 0xff), NULL, 0}, + {10, 4, "w10", ARM64_COLOR(0, 10, 0xf), NULL, 0, 0}, + {10, 8, "x10", ARM64_COLOR(0, 10, 0xff), NULL, 0, 0}, - {11, 4, "w11", ARM64_COLOR(0, 11, 0xf), NULL, 0}, - {11, 8, "x11", ARM64_COLOR(0, 11, 0xff), NULL, 0}, + {11, 4, "w11", ARM64_COLOR(0, 11, 0xf), NULL, 0, 0}, + {11, 8, "x11", ARM64_COLOR(0, 11, 0xff), NULL, 0, 0}, - {12, 4, "w12", ARM64_COLOR(0, 12, 0xf), NULL, 0}, - {12, 8, "x12", ARM64_COLOR(0, 12, 0xff), NULL, 0}, + {12, 4, "w12", ARM64_COLOR(0, 12, 0xf), NULL, 0, 0}, + {12, 8, "x12", ARM64_COLOR(0, 12, 0xff), NULL, 0, 0}, - {13, 4, "w13", ARM64_COLOR(0, 13, 0xf), NULL, 0}, - {13, 8, "x13", ARM64_COLOR(0, 13, 0xff), NULL, 0}, + {13, 4, "w13", ARM64_COLOR(0, 13, 0xf), NULL, 0, 0}, + {13, 8, "x13", ARM64_COLOR(0, 13, 0xff), NULL, 0, 0}, - {14, 4, "w14", ARM64_COLOR(0, 14, 0xf), NULL, 0}, - {14, 8, "x14", ARM64_COLOR(0, 14, 0xff), NULL, 0}, + {14, 4, "w14", ARM64_COLOR(0, 14, 0xf), NULL, 0, 0}, + {14, 8, "x14", ARM64_COLOR(0, 14, 0xff), NULL, 0, 0}, - {15, 4, "w15", ARM64_COLOR(0, 15, 0xf), NULL, 0}, - {15, 8, "x15", ARM64_COLOR(0, 15, 0xff), NULL, 0}, + {15, 4, "w15", ARM64_COLOR(0, 15, 0xf), NULL, 0, 0}, + {15, 8, "x15", ARM64_COLOR(0, 15, 0xff), NULL, 0, 0}, // not use x16, x17, x18 -// {16, 4, "w16", ARM64_COLOR(0, 16, 0xf), NULL, 0}, -// {16, 8, "x16", ARM64_COLOR(0, 16, 0xff), NULL, 0}, +// {16, 4, "w16", ARM64_COLOR(0, 16, 0xf), NULL, 0, 0}, +// {16, 8, "x16", ARM64_COLOR(0, 16, 0xff), NULL, 0, 0}, -// {17, 4, "w17", ARM64_COLOR(0, 17, 0xf), NULL, 0}, -// {17, 8, "x17", ARM64_COLOR(0, 17, 0xff), NULL, 0}, +// {17, 4, "w17", ARM64_COLOR(0, 17, 0xf), NULL, 0, 0}, +// {17, 8, "x17", ARM64_COLOR(0, 17, 0xff), NULL, 0, 0}, -// {18, 4, "w18", ARM64_COLOR(0, 18, 0xf), NULL, 0}, -// {18, 8, "x18", ARM64_COLOR(0, 18, 0xff), NULL, 0}, +// {18, 4, "w18", ARM64_COLOR(0, 18, 0xf), NULL, 0, 0}, +// {18, 8, "x18", ARM64_COLOR(0, 18, 0xff), NULL, 0, 0}, - {19, 4, "w19", ARM64_COLOR(0, 19, 0xf), NULL, 0}, - {19, 8, "x19", ARM64_COLOR(0, 19, 0xff), NULL, 0}, + {19, 4, "w19", ARM64_COLOR(0, 19, 0xf), NULL, 0, 0}, + {19, 8, "x19", ARM64_COLOR(0, 19, 0xff), NULL, 0, 0}, - {20, 4, "w20", ARM64_COLOR(0, 20, 0xf), NULL, 0}, - {20, 8, "x20", ARM64_COLOR(0, 20, 0xff), NULL, 0}, + {20, 4, "w20", ARM64_COLOR(0, 20, 0xf), NULL, 0, 0}, + {20, 8, "x20", ARM64_COLOR(0, 20, 0xff), NULL, 0, 0}, - {21, 4, "w21", ARM64_COLOR(0, 21, 0xf), NULL, 0}, - {21, 8, "x21", ARM64_COLOR(0, 21, 0xff), NULL, 0}, + {21, 4, "w21", ARM64_COLOR(0, 21, 0xf), NULL, 0, 0}, + {21, 8, "x21", ARM64_COLOR(0, 21, 0xff), NULL, 0, 0}, - {22, 4, "w22", ARM64_COLOR(0, 22, 0xf), NULL, 0}, - {22, 8, "x22", ARM64_COLOR(0, 22, 0xff), NULL, 0}, + {22, 4, "w22", ARM64_COLOR(0, 22, 0xf), NULL, 0, 0}, + {22, 8, "x22", ARM64_COLOR(0, 22, 0xff), NULL, 0, 0}, - {23, 4, "w23", ARM64_COLOR(0, 23, 0xf), NULL, 0}, - {23, 8, "x23", ARM64_COLOR(0, 23, 0xff), NULL, 0}, + {23, 4, "w23", ARM64_COLOR(0, 23, 0xf), NULL, 0, 0}, + {23, 8, "x23", ARM64_COLOR(0, 23, 0xff), NULL, 0, 0}, - {24, 4, "w24", ARM64_COLOR(0, 24, 0xf), NULL, 0}, - {24, 8, "x24", ARM64_COLOR(0, 24, 0xff), NULL, 0}, + {24, 4, "w24", ARM64_COLOR(0, 24, 0xf), NULL, 0, 0}, + {24, 8, "x24", ARM64_COLOR(0, 24, 0xff), NULL, 0, 0}, - {25, 4, "w25", ARM64_COLOR(0, 25, 0xf), NULL, 0}, - {25, 8, "x25", ARM64_COLOR(0, 25, 0xff), NULL, 0}, + {25, 4, "w25", ARM64_COLOR(0, 25, 0xf), NULL, 0, 0}, + {25, 8, "x25", ARM64_COLOR(0, 25, 0xff), NULL, 0, 0}, - {26, 4, "w26", ARM64_COLOR(0, 26, 0xf), NULL, 0}, - {26, 8, "x26", ARM64_COLOR(0, 26, 0xff), NULL, 0}, + {26, 4, "w26", ARM64_COLOR(0, 26, 0xf), NULL, 0, 0}, + {26, 8, "x26", ARM64_COLOR(0, 26, 0xff), NULL, 0, 0}, - {27, 4, "w27", ARM64_COLOR(0, 27, 0xf), NULL, 0}, - {27, 8, "x27", ARM64_COLOR(0, 27, 0xff), NULL, 0}, + {27, 4, "w27", ARM64_COLOR(0, 27, 0xf), NULL, 0, 0}, + {27, 8, "x27", ARM64_COLOR(0, 27, 0xff), NULL, 0, 0}, - {28, 4, "w28", ARM64_COLOR(0, 28, 0xf), NULL, 0}, - {28, 8, "x28", ARM64_COLOR(0, 28, 0xff), NULL, 0}, + {28, 4, "w28", ARM64_COLOR(0, 28, 0xf), NULL, 0, 0}, + {28, 8, "x28", ARM64_COLOR(0, 28, 0xff), NULL, 0, 0}, // fp = x29 = bp - {29, 8, "fp", ARM64_COLOR(0, 29, 0xff), NULL, 0}, - + {29, 4, "w29", ARM64_COLOR(0, 29, 0xf), NULL, 0, 0}, + {29, 8, "fp", ARM64_COLOR(0, 29, 0xff), NULL, 0, 0}, // lr = x30 - {30, 8, "lr", ARM64_COLOR(0, 30, 0xff), NULL, 0}, + {30, 4, "w30", ARM64_COLOR(0, 30, 0xf), NULL, 0, 0}, + {30, 8, "lr", ARM64_COLOR(0, 30, 0xff), NULL, 0, 0}, + {31, 8, "sp", ARM64_COLOR(0, 31, 0xff), NULL, 0, 0}, - {31, 8, "sp", ARM64_COLOR(0, 31, 0xff), NULL, 0}, -#if 0 - {0, 4, "mm0", ARM64_COLOR(1, 0, 0xf), NULL, 0}, - {0, 8, "xmm0", ARM64_COLOR(1, 0, 0xff), NULL, 0}, - {1, 4, "mm1", ARM64_COLOR(1, 1, 0xf), NULL, 0}, - {1, 8, "xmm1", ARM64_COLOR(1, 1, 0xff), NULL, 0}, + {0, 2, "h0", ARM64_COLOR(1, 0, 0x3), NULL, 0, 0}, + {0, 4, "s0", ARM64_COLOR(1, 0, 0xf), NULL, 0, 0}, + {0, 8, "d0", ARM64_COLOR(1, 0, 0xff), NULL, 0, 0}, - {2, 4, "mm2", ARM64_COLOR(1, 2, 0xf), NULL, 0}, - {2, 8, "xmm2", ARM64_COLOR(1, 2, 0xff), NULL, 0}, + {1, 2, "h1", ARM64_COLOR(1, 1, 0x3), NULL, 0, 0}, + {1, 4, "s1", ARM64_COLOR(1, 1, 0xf), NULL, 0, 0}, + {1, 8, "d1", ARM64_COLOR(1, 1, 0xff), NULL, 0, 0}, - {3, 4, "mm3", ARM64_COLOR(1, 3, 0xf), NULL, 0}, - {3, 8, "xmm3", ARM64_COLOR(1, 3, 0xff), NULL, 0}, + {2, 2, "h2", ARM64_COLOR(1, 2, 0x3), NULL, 0, 0}, + {2, 4, "s2", ARM64_COLOR(1, 2, 0xf), NULL, 0, 0}, + {2, 8, "d2", ARM64_COLOR(1, 2, 0xff), NULL, 0, 0}, - {4, 4, "mm4", ARM64_COLOR(1, 4, 0xf), NULL, 0}, - {4, 8, "xmm4", ARM64_COLOR(1, 4, 0xff), NULL, 0}, + {3, 2, "h3", ARM64_COLOR(1, 3, 0x3), NULL, 0, 0}, + {3, 4, "s3", ARM64_COLOR(1, 3, 0xf), NULL, 0, 0}, + {3, 8, "d3", ARM64_COLOR(1, 3, 0xff), NULL, 0, 0}, - {5, 4, "mm5", ARM64_COLOR(1, 5, 0xf), NULL, 0}, - {5, 8, "xmm5", ARM64_COLOR(1, 5, 0xff), NULL, 0}, + {4, 2, "h4", ARM64_COLOR(1, 4, 0x3), NULL, 0, 0}, + {4, 4, "s4", ARM64_COLOR(1, 4, 0xf), NULL, 0, 0}, + {4, 8, "d4", ARM64_COLOR(1, 4, 0xff), NULL, 0, 0}, - {6, 4, "mm6", ARM64_COLOR(1, 6, 0xf), NULL, 0}, - {6, 8, "xmm6", ARM64_COLOR(1, 6, 0xff), NULL, 0}, + {5, 2, "h5", ARM64_COLOR(1, 5, 0x3), NULL, 0, 0}, + {5, 4, "s5", ARM64_COLOR(1, 5, 0xf), NULL, 0, 0}, + {5, 8, "d5", ARM64_COLOR(1, 5, 0xff), NULL, 0, 0}, - {7, 4, "mm7", ARM64_COLOR(1, 7, 0xf), NULL, 0}, - {7, 8, "xmm7", ARM64_COLOR(1, 7, 0xff), NULL, 0}, -#endif + {6, 2, "h6", ARM64_COLOR(1, 6, 0x3), NULL, 0, 0}, + {6, 4, "s6", ARM64_COLOR(1, 6, 0xf), NULL, 0, 0}, + {6, 8, "d6", ARM64_COLOR(1, 6, 0xff), NULL, 0, 0}, + + {7, 2, "h7", ARM64_COLOR(1, 7, 0x3), NULL, 0, 0}, + {7, 4, "s7", ARM64_COLOR(1, 7, 0xf), NULL, 0, 0}, + {7, 8, "d7", ARM64_COLOR(1, 7, 0xff), NULL, 0, 0}, + + {8, 2, "h8", ARM64_COLOR(1, 8, 0x3), NULL, 0, 0}, + {8, 4, "s8", ARM64_COLOR(1, 8, 0xf), NULL, 0, 0}, + {8, 8, "d8", ARM64_COLOR(1, 8, 0xff), NULL, 0, 0}, + + {9, 2, "h9", ARM64_COLOR(1, 9, 0x3), NULL, 0, 0}, + {9, 4, "s9", ARM64_COLOR(1, 9, 0xf), NULL, 0, 0}, + {9, 8, "d9", ARM64_COLOR(1, 9, 0xff), NULL, 0, 0}, + + {10, 2, "h10", ARM64_COLOR(1, 10, 0x3), NULL, 0, 0}, + {10, 4, "s10", ARM64_COLOR(1, 10, 0xf), NULL, 0, 0}, + {10, 8, "d10", ARM64_COLOR(1, 10, 0xff), NULL, 0, 0}, + + {11, 2, "h11", ARM64_COLOR(1, 11, 0x3), NULL, 0, 0}, + {11, 4, "s11", ARM64_COLOR(1, 11, 0xf), NULL, 0, 0}, + {11, 8, "d11", ARM64_COLOR(1, 11, 0xff), NULL, 0, 0}, + + {12, 2, "h12", ARM64_COLOR(1, 12, 0x3), NULL, 0, 0}, + {12, 4, "s12", ARM64_COLOR(1, 12, 0xf), NULL, 0, 0}, + {12, 8, "d12", ARM64_COLOR(1, 12, 0xff), NULL, 0, 0}, + + {13, 2, "h13", ARM64_COLOR(1, 13, 0x3), NULL, 0, 0}, + {13, 4, "s13", ARM64_COLOR(1, 13, 0xf), NULL, 0, 0}, + {13, 8, "d13", ARM64_COLOR(1, 13, 0xff), NULL, 0, 0}, + + {14, 2, "h14", ARM64_COLOR(1, 14, 0x3), NULL, 0, 0}, + {14, 4, "s14", ARM64_COLOR(1, 14, 0xf), NULL, 0, 0}, + {14, 8, "d14", ARM64_COLOR(1, 14, 0xff), NULL, 0, 0}, + + {15, 2, "h15", ARM64_COLOR(1, 15, 0x3), NULL, 0, 0}, + {15, 4, "s15", ARM64_COLOR(1, 15, 0xf), NULL, 0, 0}, + {15, 8, "d15", ARM64_COLOR(1, 15, 0xff), NULL, 0, 0}, + + {16, 2, "h16", ARM64_COLOR(1, 16, 0x3), NULL, 0, 0}, + {16, 4, "s16", ARM64_COLOR(1, 16, 0xf), NULL, 0, 0}, + {16, 8, "d16", ARM64_COLOR(1, 16, 0xff), NULL, 0, 0}, + + {17, 2, "h17", ARM64_COLOR(1, 17, 0x3), NULL, 0, 0}, + {17, 4, "s17", ARM64_COLOR(1, 17, 0xf), NULL, 0, 0}, + {17, 8, "d17", ARM64_COLOR(1, 17, 0xff), NULL, 0, 0}, + + {18, 2, "h18", ARM64_COLOR(1, 18, 0x3), NULL, 0, 0}, + {18, 4, "s18", ARM64_COLOR(1, 18, 0xf), NULL, 0, 0}, + {18, 8, "d18", ARM64_COLOR(1, 18, 0xff), NULL, 0, 0}, + + {19, 2, "h19", ARM64_COLOR(1, 19, 0x3), NULL, 0, 0}, + {19, 4, "s19", ARM64_COLOR(1, 19, 0xf), NULL, 0, 0}, + {19, 8, "d19", ARM64_COLOR(1, 19, 0xff), NULL, 0, 0}, + + {20, 2, "h20", ARM64_COLOR(1, 20, 0x3), NULL, 0, 0}, + {20, 4, "s20", ARM64_COLOR(1, 20, 0xf), NULL, 0, 0}, + {20, 8, "d20", ARM64_COLOR(1, 20, 0xff), NULL, 0, 0}, + + {21, 2, "h21", ARM64_COLOR(1, 21, 0x3), NULL, 0, 0}, + {21, 4, "s21", ARM64_COLOR(1, 21, 0xf), NULL, 0, 0}, + {21, 8, "d21", ARM64_COLOR(1, 21, 0xff), NULL, 0, 0}, + + {22, 2, "h22", ARM64_COLOR(1, 22, 0x3), NULL, 0, 0}, + {22, 4, "s22", ARM64_COLOR(1, 22, 0xf), NULL, 0, 0}, + {22, 8, "d22", ARM64_COLOR(1, 22, 0xff), NULL, 0, 0}, + + {23, 2, "h23", ARM64_COLOR(1, 23, 0x3), NULL, 0, 0}, + {23, 4, "s23", ARM64_COLOR(1, 23, 0xf), NULL, 0, 0}, + {23, 8, "d23", ARM64_COLOR(1, 23, 0xff), NULL, 0, 0}, + + {24, 2, "h24", ARM64_COLOR(1, 24, 0x3), NULL, 0, 0}, + {24, 4, "s24", ARM64_COLOR(1, 24, 0xf), NULL, 0, 0}, + {24, 8, "d24", ARM64_COLOR(1, 24, 0xff), NULL, 0, 0}, + + {25, 2, "h25", ARM64_COLOR(1, 25, 0x3), NULL, 0, 0}, + {25, 4, "s25", ARM64_COLOR(1, 25, 0xf), NULL, 0, 0}, + {25, 8, "d25", ARM64_COLOR(1, 25, 0xff), NULL, 0, 0}, + + {26, 2, "h26", ARM64_COLOR(1, 26, 0x3), NULL, 0, 0}, + {26, 4, "s26", ARM64_COLOR(1, 26, 0xf), NULL, 0, 0}, + {26, 8, "d26", ARM64_COLOR(1, 26, 0xff), NULL, 0, 0}, + + {27, 2, "h27", ARM64_COLOR(1, 27, 0x3), NULL, 0, 0}, + {27, 4, "s27", ARM64_COLOR(1, 27, 0xf), NULL, 0, 0}, + {27, 8, "d27", ARM64_COLOR(1, 27, 0xff), NULL, 0, 0}, + + {28, 2, "h28", ARM64_COLOR(1, 28, 0x3), NULL, 0, 0}, + {28, 4, "s28", ARM64_COLOR(1, 28, 0xf), NULL, 0, 0}, + {28, 8, "d28", ARM64_COLOR(1, 28, 0xff), NULL, 0, 0}, + + {29, 2, "h29", ARM64_COLOR(1, 29, 0x3), NULL, 0, 0}, + {29, 4, "s29", ARM64_COLOR(1, 29, 0xf), NULL, 0, 0}, + {29, 8, "d29", ARM64_COLOR(1, 29, 0xff), NULL, 0, 0}, + + {30, 2, "h30", ARM64_COLOR(1, 30, 0x3), NULL, 0, 0}, + {30, 4, "s30", ARM64_COLOR(1, 30, 0xf), NULL, 0, 0}, + {30, 8, "d30", ARM64_COLOR(1, 30, 0xff), NULL, 0, 0}, + + {31, 2, "h31", ARM64_COLOR(1, 31, 0x3), NULL, 0, 0}, + {31, 4, "s31", ARM64_COLOR(1, 31, 0xf), NULL, 0, 0}, + {31, 8, "d31", ARM64_COLOR(1, 31, 0xff), NULL, 0, 0}, }; int arm64_reg_cached_vars(scf_register_arm64_t* r) @@ -167,6 +271,8 @@ int arm64_registers_init() r->dag_nodes = scf_vector_alloc(); if (!r->dag_nodes) return -ENOMEM; + + r->used = 0; } return 0; @@ -188,6 +294,8 @@ void arm64_registers_clear() scf_vector_free(r->dag_nodes); r->dag_nodes = NULL; } + + r->used = 0; } } @@ -606,6 +714,7 @@ int arm64_overflow_reg(scf_register_arm64_t* r, scf_3ac_code_t* c, scf_function_ } } + r->used = 1; return 0; } @@ -643,6 +752,7 @@ int arm64_overflow_reg2(scf_register_arm64_t* r, scf_dag_node_t* dn, scf_3ac_cod } } + r->used = 1; return 0; } @@ -705,6 +815,7 @@ static int _arm64_overflow_reg3(scf_register_arm64_t* r, scf_dag_node_t* dn, scf } } + r->used = 1; return 0; } @@ -765,7 +876,7 @@ static scf_register_arm64_t* _arm64_reg_cached_min_vars(scf_register_arm64_t** r return r_min; } -scf_register_arm64_t* arm64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c) +scf_register_arm64_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; @@ -773,7 +884,6 @@ scf_register_arm64_t* arm64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_co scf_register_arm64_t* free_regs[sizeof(arm64_registers) / sizeof(arm64_registers[0])]; int nb_free_regs = 0; - int is_float = 0; int bytes = 8; int ret; int i; @@ -886,6 +996,8 @@ static int _arm64_load_reg_const(scf_register_arm64_t* r, scf_dag_node_t* dn, sc scf_variable_t* v = dn->var; + r->used = 1; + int size = arm64_variable_size(v); if (SCF_FUNCTION_PTR == v->type) { @@ -920,6 +1032,8 @@ int arm64_load_reg(scf_register_arm64_t* r, scf_dag_node_t* dn, scf_3ac_code_t* int is_float = scf_variable_float(dn->var); int var_size = arm64_variable_size(dn->var); + r->used = 1; + if (!is_float) { if (scf_variable_const(dn->var)) { @@ -943,43 +1057,43 @@ int arm64_load_reg(scf_register_arm64_t* r, scf_dag_node_t* dn, scf_3ac_code_t* dn->loaded = 1; return 0; + } + if (0 == dn->var->bp_offset && !dn->var->global_flag) { + scf_loge("\n"); + return -EINVAL; } if ((dn->var->nb_dimentions > 0 && dn->var->const_literal_flag) || (dn->var->type >= SCF_STRUCT && 0 == dn->var->nb_pointers)) { - mov = arm64_find_OpCode(SCF_ARM64_LEA, var_size, var_size, SCF_ARM64_E2G); - scf_loge("\n"); - return -EINVAL; - } else - mov = arm64_find_OpCode(SCF_ARM64_MOV, var_size, var_size, SCF_ARM64_E2G); + int ret = arm64_make_inst_ADR2G(c, f, r, dn->var); + if (ret < 0) + return ret; - } else { - if (!dn->var->global_flag && !dn->var->local_flag && !dn->var->tmp_flag) + dn->loaded = 1; return 0; + } - if (SCF_VAR_FLOAT == dn->var->type) - mov = arm64_find_OpCode(SCF_ARM64_MOVSS, var_size, var_size, SCF_ARM64_E2G); - else - mov = arm64_find_OpCode(SCF_ARM64_MOVSD, var_size, var_size, SCF_ARM64_E2G); - } + int ret = arm64_make_inst_M2G(c, f, r, NULL, dn->var); + if (ret < 0) + return ret; - if (!mov) { - scf_loge("\n"); - return -EINVAL; + dn->loaded = 1; + return 0; } + if (!dn->var->global_flag && !dn->var->local_flag && !dn->var->tmp_flag) + return 0; + if (0 == dn->var->bp_offset && !dn->var->global_flag) { scf_loge("\n"); return -EINVAL; } - int ret = arm64_make_inst_M2G(c, f, r, NULL, dn->var); - if (ret < 0) { - scf_loge("\n"); + int ret = arm64_make_inst_M2GF(c, f, r, NULL, dn->var); + if (ret < 0) return ret; - } dn->loaded = 1; return 0; @@ -1006,7 +1120,7 @@ int arm64_select_reg(scf_register_arm64_t** preg, scf_dag_node_t* dn, scf_3ac_co } #endif } else { - r = arm64_select_overflowed_reg(dn, c); + r = arm64_select_overflowed_reg(dn, c, is_float); if (!r) { scf_loge("\n"); return -1; @@ -1040,23 +1154,22 @@ int arm64_select_reg(scf_register_arm64_t** preg, scf_dag_node_t* dn, scf_3ac_co } else dn->loaded = 1; + r->used = 1; *preg = r; return 0; } -int arm64_select_free_reg(scf_register_arm64_t** preg, scf_3ac_code_t* c, scf_function_t* f) +int arm64_select_free_reg(scf_register_arm64_t** preg, scf_3ac_code_t* c, scf_function_t* f, int is_float) { scf_register_arm64_t* r; - int ret; - - r = arm64_select_overflowed_reg(NULL, c); + r = arm64_select_overflowed_reg(NULL, c, is_float); if (!r) { scf_loge("\n"); return -1; } - ret = arm64_overflow_reg(r, c, f); + int ret = arm64_overflow_reg(r, c, f); if (ret < 0) { scf_loge("overflow reg failed\n"); return ret; @@ -1066,6 +1179,12 @@ int arm64_select_free_reg(scf_register_arm64_t** preg, scf_3ac_code_t* c, scf_fu r = arm64_find_register_type_id_bytes(0, r->id, 8); assert(0 == r->dag_nodes->size); + ret = arm64_rcg_make(c, c->rcg, NULL, r); + if (ret < 0) + return ret; + + r->used = 1; + *preg = r; return 0; } @@ -1100,47 +1219,39 @@ int arm64_dereference_reg(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t int arm64_pointer_reg(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* member, scf_3ac_code_t* c, scf_function_t* f) { - scf_variable_t* vb = base ->var; - scf_variable_t* vm = member->var; + scf_variable_t* vb = base ->var; + scf_variable_t* vm = member->var; scf_register_arm64_t* rb = NULL; - - scf_arm64_OpCode_t* lea; - scf_arm64_OpCode_t* mov; - scf_instruction_t* inst; + scf_instruction_t* inst; int ret; int32_t disp = 0; -#if 0 + if (vb->nb_pointers > 0 && 0 == vb->nb_dimentions) { + ret = arm64_select_reg(&rb, base, c, f, 1); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } + } else if (vb->local_flag) { + rb = arm64_find_register("fp"); disp = vb->bp_offset; } else if (vb->global_flag) { - scf_rela_t* rela = NULL; ret = arm64_select_reg(&rb, base, c, f, 0); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } - lea = arm64_find_OpCode(SCF_ARM64_LEA, 8, 8, SCF_ARM64_E2G); - inst = arm64_make_inst_M2G(&rela, lea, rb, NULL, vb); - ARM64_INST_ADD_CHECK(c->instructions, inst); - ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, vb, NULL); + ret = arm64_make_inst_ADR2G(c, f, rb, vb); + if (ret < 0) + return ret; } else { ret = arm64_select_reg(&rb, base, c, f, 0); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } } disp += vm->offset; @@ -1151,8 +1262,6 @@ int arm64_pointer_reg(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* me sib->disp = disp; sib->size = arm64_variable_size(vm); return 0; -#endif - return -1; } int arm64_array_index_reg(arm64_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) @@ -1329,7 +1438,7 @@ int arm64_array_index_reg(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t opcode = (0xd1 << 24) | ((-disp) << 10) | (rs->id << 5) | rs->id; else { - ret = arm64_select_free_reg(&rd, c, f); + ret = arm64_select_free_reg(&rd, c, f, 0); if (ret < 0) return ret; diff --git a/native/arm64/scf_arm64_reg.h b/native/arm64/scf_arm64_reg.h index 7a9e221..fb26abf 100644 --- a/native/arm64/scf_arm64_reg.h +++ b/native/arm64/scf_arm64_reg.h @@ -106,7 +106,7 @@ typedef struct { scf_vector_t* dag_nodes; uint32_t updated; - + uint32_t used; } scf_register_arm64_t; typedef struct { @@ -146,7 +146,7 @@ scf_register_arm64_t* arm64_find_register_color_bytes(intptr_t color, int bytes) scf_register_arm64_t* arm64_find_abi_register(int index, int bytes); -scf_register_arm64_t* arm64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c); +scf_register_arm64_t* arm64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float); int arm64_reg_cached_vars(scf_register_arm64_t* r); @@ -169,7 +169,7 @@ int arm64_overflow_reg2(scf_register_arm64_t* r, scf_dag_node_t* int arm64_select_reg(scf_register_arm64_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f, int load_flag); -int arm64_select_free_reg(scf_register_arm64_t** preg, scf_3ac_code_t* c, scf_function_t* f); +int arm64_select_free_reg(scf_register_arm64_t** preg, scf_3ac_code_t* c, scf_function_t* f, int is_float); int arm64_dereference_reg(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* member, scf_3ac_code_t* c, scf_function_t* f); diff --git a/native/arm64/scf_arm64_util.c b/native/arm64/scf_arm64_util.c index 02bc241..3de05ef 100644 --- a/native/arm64/scf_arm64_util.c +++ b/native/arm64/scf_arm64_util.c @@ -121,6 +121,7 @@ int arm64_make_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm int arm64_make_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, scf_variable_t* vs) { scf_register_arm64_t* fp = arm64_find_register("fp"); + scf_register_arm64_t* ri = NULL; scf_instruction_t* inst = NULL; scf_rela_t* rela = NULL; @@ -210,19 +211,23 @@ int arm64_make_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (0x38 << 24) | ((offset & 0x1ff) << 12); else { - assert(rd->id != rb->id); + int ret = arm64_select_free_reg(&ri, c, f, 0); + if (ret < 0) { + scf_loge("\n"); + return -EINVAL; + } - opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | rd->id; + opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id; inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); if (offset >> 16) { - opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | rd->id; + opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id; inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); } - opcode = (0x38 << 24) | (0x1 << 21) | (rd->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10); + opcode = (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10); } if (rd->bytes > size && scf_variable_signed(vs)) @@ -231,6 +236,9 @@ int arm64_make_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode |= 0x1 << 22; opcode |= (SIZE << 30) | (rb->id << 5) | rd->id; + + opcode |= ARM64_COLOR_TYPE(rd->color) << 26; + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); @@ -260,7 +268,7 @@ int arm64_make_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 } else if (vs->global_flag) { offset = 0; - int ret = arm64_select_free_reg(&rb, c, f); + int ret = arm64_select_free_reg(&rb, c, f, 0); if (ret < 0) { scf_loge("\n"); return -EINVAL; @@ -336,7 +344,7 @@ int arm64_make_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (SIZE << 30) | (0x38 << 24) | ((offset & 0x1ff) << 12) | (rb->id << 5) | rs->id; else { - int ret = arm64_select_free_reg(&ri, c, f); + int ret = arm64_select_free_reg(&ri, c, f, 0); if (ret < 0) { scf_loge("\n"); return -EINVAL; @@ -355,7 +363,9 @@ int arm64_make_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id; } - inst = arm64_make_inst(c, opcode); + opcode |= ARM64_COLOR_TYPE(rs->color) << 26; + + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; @@ -450,7 +460,7 @@ int arm64_make_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (SIZE << 30) | (0x38 << 24) | ((offset & 0x1ff) << 12) | (rb->id << 5) | rs->id; else { - int ret = arm64_select_free_reg(&ri, c, f); + int ret = arm64_select_free_reg(&ri, c, f, 0); if (ret < 0) { scf_loge("\n"); return -EINVAL; @@ -469,7 +479,9 @@ int arm64_make_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id; } - inst = arm64_make_inst(c, opcode); + opcode |= ARM64_COLOR_TYPE(rs->color) << 26; + + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; @@ -533,22 +545,102 @@ int arm64_make_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64 opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | ((offset & 0x1ff) << 12) | (rb->id << 5) | rd->id; else { - opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | rd->id; + int ret = arm64_select_free_reg(&ri, c, f, 0); + if (ret < 0) { + scf_loge("\n"); + return -EINVAL; + } + + opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id; inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); if (offset >> 16) { - opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | rd->id; + opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id; inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); } - opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | (0x1 << 21) | (rd->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rd->id; + opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rd->id; + } + + opcode |= ARM64_COLOR_TYPE(rd->color) << 26; + + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} + +int arm64_make_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, int32_t offset) +{ + scf_register_arm64_t* r = NULL; + scf_instruction_t* inst = NULL; + + uint32_t opcode = 0; + uint32_t u24i = 0x91; + uint32_t u24r = 0x8b; + + if (offset < 0) { + offset = -offset; + u24i = 0xd1; + u24r = 0xcb; + } + + if (offset <= 0xfff) + opcode = (u24i << 24) | (offset << 10) | (rd->id << 5) | rd->id; + + else if (0 == (offset & 0xfff) && (offset >> 12) <= 0xfff) + + opcode = (u24i << 24) | (0x1 << 22) | ((offset >> 12) << 10) | (rd->id << 5) | rd->id; + + else { + int ret = arm64_select_free_reg(&r, c, f, 0); + if (ret < 0) + return ret; + + ret = arm64_make_inst_I2G(c, r, offset, 4); + if (ret < 0) + return ret; + + opcode = (u24r << 24) | (r->id << 16) | (rd->id << 5) | rd->id; } inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); + return 0; +} +int arm64_make_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, arm64_sib_t* sib) +{ + scf_register_arm64_t* rb = sib->base; + scf_register_arm64_t* ri = sib->index; + scf_instruction_t* inst = NULL; + + assert(0 == sib->disp); + + if (!rb || !ri) + return -EINVAL; + + uint32_t opcode; + uint32_t SH; + + if (1 == sib->scale) + SH = 0; + + else if (2 == sib->scale) + SH = 1; + + else if (4 == sib->scale) + SH = 2; + + else if (8 == sib->scale) + SH = 3; + else + return -EINVAL; + + opcode = (0x8b << 24) | (ri->id << 16) | (SH << 10) | (rb->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } @@ -560,7 +652,7 @@ int arm64_make_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm assert(0 == sib->disp); - if (!rb) + if (!rb || !ri) return -EINVAL; int scale = sib->scale; @@ -588,9 +680,11 @@ int arm64_make_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm else return -EINVAL; - opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rd->id; + opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rd->id; - inst = arm64_make_inst(c, opcode); + opcode |= ARM64_COLOR_TYPE(rd->color) << 26; + + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; @@ -604,7 +698,7 @@ int arm64_make_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm assert(0 == sib->disp); - if (!rb) + if (!rb || !ri) return -EINVAL; int scale = sib->scale; @@ -632,11 +726,131 @@ int arm64_make_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm else return -EINVAL; - opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id; + opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id; - inst = arm64_make_inst(c, opcode); + opcode |= ARM64_COLOR_TYPE(rs->color) << 26; + + inst = arm64_make_inst(c, opcode); ARM64_INST_ADD_CHECK(c->instructions, inst); return 0; } +int arm64_make_inst_M2GF(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64_t* rd, scf_register_arm64_t* rb, scf_variable_t* vs) +{ + scf_register_arm64_t* fp = arm64_find_register("fp"); + scf_register_arm64_t* ro = NULL; + scf_instruction_t* inst = NULL; + scf_rela_t* rela = NULL; + + int32_t offset; + uint32_t opcode; + uint32_t SIZE = 0; + uint32_t S = 1; + + int size = arm64_variable_size(vs); + + if (!rb) { + if (vs->local_flag || vs->tmp_flag) { + + offset = vs->bp_offset; + rb = fp; + + } else if (vs->global_flag) { + offset = 0; + + int ret = arm64_select_free_reg(&rb, c, f, 0); + if (ret < 0) + return ret; + + opcode = (0x90 << 24) | rb->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); + rela->type = R_AARCH64_ADR_PREL_PG_HI21; + + opcode = (0x91 << 24) | (rb->id << 5) | rb->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); + rela->type = R_AARCH64_ADD_ABS_LO12_NC; + + } else { + scf_loge("temp var should give a register\n"); + return -EINVAL; + } + + } else { + if (vs->local_flag || vs->tmp_flag) + offset = vs->bp_offset; + else + offset = vs->offset; + } + + if (1 == size) { + S = 0; + SIZE = 0; + + } else if (2 == size) { + + if (offset & 0x1) { + scf_loge("memory align error\n"); + return -EINVAL; + } + + offset >> 1; + SIZE = 1; + + } else if (4 == size) { + + if (offset & 0x3) { + scf_loge("memory align error\n"); + return -EINVAL; + } + + offset >> 2; + SIZE = 2; + + } else if (8 == size) { + + if (offset & 0x7) { + scf_loge("memory align error\n"); + return -EINVAL; + } + + offset >> 3; + SIZE = 3; + } else + return -EINVAL; + + + if (offset >= 0 && offset < 0xfff) + opcode = (0x3d << 24) | (0x1 << 22) | (offset << 10); + + else if (offset < 0 && offset >= -0xff) + opcode = (0x3c << 24) | (0x1 << 22) | ((offset & 0x1ff) << 12); + + else { + int ret = arm64_select_free_reg(&ro, c, f, 0); + if (ret < 0) + return ret; + + opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ro->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + if (offset >> 16) { + opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ro->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + } + + opcode = (0x3c << 24) | (0x1 << 22) | (0x1 << 21) | (ro->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10); + } + + opcode |= (SIZE << 30) | (rb->id << 5) | rd->id; + inst = arm64_make_inst(c, opcode); + ARM64_INST_ADD_CHECK(c->instructions, inst); + + return 0; +} -- 2.25.1