support ARM64: float / double instructions
authoryu.dongliang <18588496441@163.com>
Wed, 1 Mar 2023 12:26:56 +0000 (20:26 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 1 Mar 2023 12:27:03 +0000 (20:27 +0800)
core/scf_operator_dag.c
native/arm64/scf_arm64.c
native/arm64/scf_arm64.h
native/arm64/scf_arm64_inst.c
native/arm64/scf_arm64_rcg.c
native/arm64/scf_arm64_reg.c
native/arm64/scf_arm64_reg.h
native/arm64/scf_arm64_util.c

index def6838114999be90173ca37a372a299a8308afd..786a15b54ce4ccbe35b81c14545c92de14fdf436 100644 (file)
@@ -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},
index 0b28292c2b45ea2ea603d8b13a11b02ca98016fd..5fcb4030276c36e82109ee60a9c1e972a555a748 100644 (file)
@@ -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");
index ec6eb1fa1b465977a09a30d8160a6f71d0ff3ec4..159baa0a3ba098cfa7c24f29e1cd00a80aab4641 100644 (file)
@@ -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
 
index a843b89a9511ad732f3f3260d1fb45266f9af253..fb099b1118e39512aadcfdb4043980226c212ecf 100644 (file)
@@ -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*          = 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*          = 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[] = {
index 5b0bf39e33cdddbf16e78e4dd6bbaf73d852a977..bb92b25e70a9076ce203e1f1f681a07033d69c86 100644 (file)
@@ -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[] = {
index 4c66269112e7161c8d9d944e905ab0c522dd4dee..a6a717fdf9c29ecdd1808a5e499e5c78be41d7dd 100644 (file)
 
 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;
 
index 7a9e221c81030c02f6c1022aa1cadb51647300ae..fb26abf32bc0c598c986a5571da6fe7a4e8b98bd 100644 (file)
@@ -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);
 
index 02bc24173abb970acbb8e9ceb2bd12808b221301..3de05ef56d67d8f4fa643fafe6c1244ef1ac9783 100644 (file)
@@ -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;
+}