support arm64: 'hanoi' test ok, ../examples/hanoi.c
authoryu.dongliang <18588496441@163.com>
Tue, 21 Feb 2023 11:10:23 +0000 (19:10 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 21 Feb 2023 11:10:47 +0000 (19:10 +0800)
examples/hanoi.c
native/arm64/scf_arm64.c
native/arm64/scf_arm64_inst.c
native/arm64/scf_arm64_reg.c
native/arm64/scf_arm64_reg.h
native/arm64/scf_arm64_util.c

index 1ebb025ac15a9d2d1ca5f27646036c7a8f670ca5..2db3cc05c6837c7604a6eb9267513a10a4df2d3c 100644 (file)
@@ -15,6 +15,6 @@ void hanoi(int n, char a, char b, char c)
 
 int main()
 {
-       hanoi(4, 'A', 'B', 'C');
+       hanoi(5, 'A', 'B', 'C');
        return 0;
 }
index 9d9c1452d9a10d6487d06c2a62d9e45785b281b7..e9288505e0bde264fccf69724f80f591bd613b78 100644 (file)
@@ -601,14 +601,23 @@ error:
        return ret;
 }
 
-static int _arm64_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_offset)
+static int _arm64_make_insts_for_list(scf_native_t* ctx, scf_basic_block_t* bb, int bb_offset)
 {
-       scf_list_t* l;
-       int ret;
+       scf_3ac_code_t* cmp = NULL;
+       scf_3ac_code_t* c   = NULL;
+       scf_list_t*     h   = &bb->code_list_head;
+       scf_list_t*     l;
 
        for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
 
-               scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list);
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+
+               if (bb->cmp_flag
+                               && (SCF_OP_3AC_CMP == c->op->type
+                                || SCF_OP_3AC_TEQ == c->op->type)) {
+                       assert(!cmp);
+                       cmp = c;
+               }
 
                arm64_inst_handler_t* h = scf_arm64_find_inst_handler(c->op->type);
                if (!h) {
@@ -616,7 +625,7 @@ static int _arm64_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_o
                        return -EINVAL;
                }
 
-               ret = h->func(ctx, c);
+               int ret = h->func(ctx, c);
                if (ret < 0) {
                        scf_3ac_code_print(c, NULL);
                        scf_loge("3ac op '%s' make inst failed\n", c->op->name);
@@ -630,68 +639,84 @@ static int _arm64_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_o
                _arm64_inst_printf(c);
        }
 
+       if (bb->cmp_flag) {
+
+               assert(cmp);
+
+               scf_list_del(&cmp->list);
+               scf_list_add_tail(&bb->code_list_head, &cmp->list);
+       }
+
        return bb_offset;
 }
 
 static void _arm64_set_offset_for_jmps(scf_native_t* ctx, scf_function_t* f)
 {
-#if 0
-       while (1) {
-               int drop_bytes = 0;
-               int i;
+       int i;
 
-               for (i = 0; i < f->jmps->size; i++) {
-                       scf_3ac_code_t*    c      = f->jmps->data[i];
+       for (i = 0; i < f->jmps->size; i++) {
+               scf_3ac_code_t*    c      = f->jmps->data[i];
 
-                       scf_3ac_operand_t* dst    = c->dsts->data[0];
-                       scf_basic_block_t* cur_bb = c->basic_block;
-                       scf_basic_block_t* dst_bb = dst->bb;
+               assert(c->instructions && 1 == c->instructions->size);
 
-                       scf_basic_block_t* bb     = NULL;
-                       scf_list_t*        l      = NULL;
-                       int32_t            bytes  = 0;
+               scf_3ac_operand_t* dst    = c->dsts->data[0];
+               scf_basic_block_t* cur_bb = c->basic_block;
+               scf_basic_block_t* dst_bb = dst->bb;
 
-                       if (cur_bb->index < dst_bb->index) {
-                               for (l = scf_list_next(&cur_bb->list); l != &dst_bb->list; l = scf_list_next(l)) {
+               scf_instruction_t* inst   = c->instructions->data[0];
+               scf_basic_block_t* bb     = NULL;
+               scf_list_t*        l      = NULL;
+               int32_t            bytes  = 0;
 
-                                       bb     = scf_list_data(l, scf_basic_block_t, list);
+               if (cur_bb->index < dst_bb->index) {
+                       for (l = &cur_bb->list; l != &dst_bb->list; l = scf_list_next(l)) {
 
-                                       bytes += bb->code_bytes;
-                               }
-                       } else {
-                               for (l = &cur_bb->list; l != scf_list_prev(&dst_bb->list); l = scf_list_prev(l)) {
+                               bb     = scf_list_data(l, scf_basic_block_t, list);
+
+                               bytes += bb->code_bytes;
+                       }
+               } else {
+                       for (l = &cur_bb->list; l != &dst_bb->list; l = scf_list_prev(l)) {
 
-                                       bb     = scf_list_data(l, scf_basic_block_t, list);
+                               bb     = scf_list_data(l, scf_basic_block_t, list);
 
-                                       bytes -= bb->code_bytes;
-                               }
+                               bytes -= bb->code_bytes;
                        }
+               }
 
-                       assert(c->instructions && 1 == c->instructions->size);
+               assert(0 == (bytes & 0x3));
 
-                       int nb_bytes;
-                       if (-128 <= bytes && bytes <= 127)
-                               nb_bytes = 1;
-                       else
-                               nb_bytes = 4;
+               if (0x54 == inst->code[3]) {
 
-                       scf_instruction_t* inst = c->instructions->data[0];
-                       scf_arm64_OpCode_t*  jcc  = arm64_find_OpCode(inst->OpCode->type, nb_bytes, nb_bytes, SCF_ARM64_I);
+                       if (bytes  >= 0 && bytes < (0x1 << 20)) {
+                               bytes >>= 2;
+                               bytes <<= 5;
 
-                       int old_len = inst->len;
-                       arm64_make_inst_I2(inst, jcc, (uint8_t*)&bytes, nb_bytes);
-                       int diff    = old_len - inst->len;
-                       assert(diff >= 0);
+                       } else if (bytes < 0 && bytes > -(0x1 << 20)) {
 
-                       cur_bb->code_bytes -= diff;
-                       c->inst_bytes      -= diff;
-                       drop_bytes         += diff;
-               }
+                               bytes >>= 2;
+                               bytes  &= 0x7ffff;
+                               bytes <<= 5;
+                       } else
+                               assert(0);
 
-               if (0 == drop_bytes)
-                       break;
+                       inst->code[0] |= 0xff &  bytes;
+                       inst->code[1] |= 0xff & (bytes >>  8);
+                       inst->code[2] |= 0xff & (bytes >> 16);
+
+               } else {
+                       assert(0x14 == inst->code[3]);
+
+                       bytes >>= 2;
+
+                       assert(bytes < (0x1 << 26) && bytes > -(0x1 << 26));
+
+                       inst->code[0] |= 0xff &  bytes;
+                       inst->code[1] |= 0xff & (bytes >>  8);
+                       inst->code[2] |= 0xff & (bytes >> 16);
+                       inst->code[3] |= 0x3  & (bytes >> 24);
+               }
        }
-#endif
 }
 
 static void _arm64_set_offset_for_relas(scf_native_t* ctx, scf_function_t* f, scf_vector_t* relas)
@@ -977,8 +1002,9 @@ int        _scf_arm64_select_inst(scf_native_t* ctx)
                        if (ret < 0)
                                return ret;
                }
+               scf_loge("************ bb: %d, cmp_flag: %d\n", bb->index, bb->cmp_flag);
 
-               ret = _arm64_make_insts_for_list(ctx, &bb->code_list_head, 0);
+               ret = _arm64_make_insts_for_list(ctx, bb, 0);
                if (ret < 0)
                        return ret;
        }
@@ -1010,8 +1036,8 @@ int       _scf_arm64_select_inst(scf_native_t* ctx)
                                        return ret;
                        }
 
-                       scf_loge("************ bb: %d\n", bb->index);
-                       ret = _arm64_make_insts_for_list(ctx, &bb->code_list_head, 0);
+                       scf_loge("************ bb: %d, cmp_flag: %d\n", bb->index, bb->cmp_flag);
+                       ret = _arm64_make_insts_for_list(ctx, bb, 0);
                        if (ret < 0)
                                return ret;
                        bb->native_flag = 1;
@@ -1038,7 +1064,7 @@ int       _scf_arm64_select_inst(scf_native_t* ctx)
                                return ret;
                }
 
-               ret = _arm64_make_insts_for_list(ctx, &bbg->pre->code_list_head, 0);
+               ret = _arm64_make_insts_for_list(ctx, bbg->pre, 0);
                if (ret < 0)
                        return ret;
 
@@ -1056,7 +1082,9 @@ int       _scf_arm64_select_inst(scf_native_t* ctx)
                        if (ret < 0)
                                return ret;
 
-                       ret = _arm64_make_insts_for_list(ctx, &bb->code_list_head, 0);
+                       scf_loge("************ bb: %d, cmp_flag: %d\n", bb->index, bb->cmp_flag);
+
+                       ret = _arm64_make_insts_for_list(ctx, bb, 0);
                        if (ret < 0)
                                return ret;
                        bb->native_flag = 1;
index 9de9981f0f427c73ef265ea865af76ab02726ef8..cc88022851a8c99167c84246d55952aed9f49fc9 100644 (file)
@@ -641,7 +641,7 @@ static int _arm64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        }
 
        if (save_size > 0) {
-               ret = arm64_pop_regs(c->instructions, saved_regs, save_size >> 3, updated_regs, nb_updated);
+               ret = arm64_pop_regs(c, saved_regs, save_size >> 3, updated_regs, nb_updated);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
@@ -710,56 +710,124 @@ static int _arm64_inst_unary(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_ty
        return -1;
 }
 
-static int _arm64_inst_unary_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type)
+static int _arm64_inst_inc_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];
+       scf_register_arm64_t* rs    = NULL;
+       scf_arm64_context_t*  arm64 = ctx->priv;
+       scf_3ac_operand_t*    src   = c->srcs->data[0];
+       scf_instruction_t*    inst  = NULL;
+       scf_function_t*       f     = arm64->f;
 
        if (!src || !src->dag_node)
                return -EINVAL;
 
+       if (0 == src->dag_node->color) {
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
        if (!c->instructions) {
                c->instructions = scf_vector_alloc();
                if (!c->instructions)
                        return -ENOMEM;
        }
 
-       scf_instruction_t*  inst   = NULL;
-       scf_register_arm64_t* rs     = NULL;
-       scf_variable_t*     var    = src->dag_node->var;
+       ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
 
-       scf_arm64_OpCode_t*   OpCode = arm64_find_OpCode(OpCode_type, var->size, var->size, SCF_ARM64_E);
-       if (!OpCode) {
+       uint32_t opcode = (0x91 << 24) | (0x1 << 10) | (rs->id << 5) | rs->id;
+
+       inst = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+
+       return 0;
+}
+
+static int _arm64_inst_inc_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size != 1)
+               return -EINVAL;
+
+       if (!c->dsts || c->dsts->size != 1)
+               return -EINVAL;
+
+       scf_register_arm64_t* rd    = NULL;
+       scf_register_arm64_t* rs    = NULL;
+       scf_arm64_context_t*  arm64 = ctx->priv;
+       scf_3ac_operand_t*    src   = c->srcs->data[0];
+       scf_3ac_operand_t*    dst   = c->dsts->data[0];
+       scf_instruction_t*    inst  = NULL;
+       scf_function_t*       f     = arm64->f;
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       if (!dst || !dst->dag_node)
+               return -EINVAL;
+
+       if (0 == src->dag_node->color) {
                scf_loge("\n");
-               return -1;
+               return -EINVAL;
        }
-#if 0
-       if (src->dag_node->color > 0) {
-               ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
-               inst = arm64_make_inst_E(OpCode, rs);
-               ARM64_INST_ADD_CHECK(c->instructions, inst);
 
-       } else if (0 == src->dag_node->color) {
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
+       }
+
+       ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
+       ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
+
+       uint32_t opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id;
+
+       inst = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+
+       opcode = (0x91 << 24) | (0x1 << 10) | (rs->id << 5) | rs->id;
+       inst   = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+       return 0;
+}
+
+static int _arm64_inst_dec_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size != 1)
+               return -EINVAL;
+
+       scf_register_arm64_t* rs    = NULL;
+       scf_arm64_context_t*  arm64 = ctx->priv;
+       scf_3ac_operand_t*    src   = c->srcs->data[0];
+       scf_instruction_t*    inst  = NULL;
+       scf_function_t*       f     = arm64->f;
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       if (0 == src->dag_node->color) {
                scf_loge("\n");
                return -EINVAL;
-       } else {
-               scf_rela_t* rela = NULL;
+       }
 
-               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);
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
        }
 
+       ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
+
+       uint32_t opcode = (0xd1 << 24) | (0x1 << 10) | (rs->id << 5) | rs->id;
+
+       inst = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+
        return 0;
-#endif
-       return -1;
 }
 
-static int _arm64_inst_unary_post_assign(scf_native_t* ctx, scf_3ac_code_t* c, int OpCode_type)
+static int _arm64_inst_dec_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
        if (!c->srcs || c->srcs->size != 1)
                return -EINVAL;
@@ -767,10 +835,13 @@ static int _arm64_inst_unary_post_assign(scf_native_t* ctx, scf_3ac_code_t* c, i
        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* src = c->srcs->data[0];
-       scf_3ac_operand_t* dst = c->dsts->data[0];
+       scf_register_arm64_t* rd    = NULL;
+       scf_register_arm64_t* rs    = NULL;
+       scf_arm64_context_t*  arm64 = ctx->priv;
+       scf_3ac_operand_t*    src   = c->srcs->data[0];
+       scf_3ac_operand_t*    dst   = c->dsts->data[0];
+       scf_instruction_t*    inst  = NULL;
+       scf_function_t*       f     = arm64->f;
 
        if (!src || !src->dag_node)
                return -EINVAL;
@@ -778,28 +849,35 @@ static int _arm64_inst_unary_post_assign(scf_native_t* ctx, scf_3ac_code_t* c, i
        if (!dst || !dst->dag_node)
                return -EINVAL;
 
+       if (0 == src->dag_node->color) {
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
        if (!c->instructions) {
                c->instructions = scf_vector_alloc();
                if (!c->instructions)
                        return -ENOMEM;
        }
 
-       scf_instruction_t*  inst   = NULL;
-       scf_register_arm64_t* rs     = NULL;
-       scf_variable_t*     var    = src->dag_node->var;
-#if 0
-       int ret = arm64_inst_op2(SCF_ARM64_MOV, dst->dag_node, src->dag_node, c, f);
-       if (ret < 0)
-               return ret;
+       ARM64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
+       ARM64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
 
-       return _arm64_inst_unary_assign(ctx, c, OpCode_type);
-#endif
-       return -1;
+       uint32_t opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id;
+
+       inst = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+
+       opcode = (0xd1 << 24) | (0x1 << 10) | (rs->id << 5) | rs->id;
+       inst   = arm64_make_inst(c, opcode);
+       ARM64_INST_ADD_CHECK(c->instructions, inst);
+       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 _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)
@@ -876,26 +954,6 @@ static int _arm64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        return 0;
 }
 
-static int _arm64_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
-       return _arm64_inst_unary_assign(ctx, c, SCF_ARM64_INC);
-}
-
-static int _arm64_inst_inc_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
-       return _arm64_inst_unary_post_assign(ctx, c, SCF_ARM64_INC);
-}
-
-static int _arm64_inst_dec_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
-       return _arm64_inst_unary_assign(ctx, c, SCF_ARM64_DEC);
-}
-
-static int _arm64_inst_dec_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
-       return _arm64_inst_unary_post_assign(ctx, c, SCF_ARM64_DEC);
-}
-
 static int _arm64_inst_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
 //     return arm64_inst_pointer(ctx, c, 0);
@@ -1600,8 +1658,105 @@ static int _arm64_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 
 static int _arm64_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
-       //return arm64_inst_cmp(ctx, c);
-       return -1;
+       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;
+       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)) {
+               assert(scf_variable_float(ds1->var));
+
+               if (0 == ds1->color) {
+                       ds1->color = -1;
+                       ds1->var->global_flag = 1;
+
+//                     ARM64_SELECT_REG_CHECK(&rs1, ds1, c, f, 1);
+                       return -EINVAL;
+               }
+
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
+       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, op) \
@@ -2044,25 +2199,44 @@ static int _arm64_inst_end_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        return 0;
 }
 
-#define ARM64_INST_JMP(name, op) \
+#define ARM64_INST_JMP(name, opcode) \
 static int _arm64_inst_##name##_handler(scf_native_t* ctx, scf_3ac_code_t* c) \
 { \
-       return -1;\
+       if (!c->dsts || c->dsts->size != 1) \
+               return -EINVAL; \
+       \
+       scf_3ac_operand_t* dst  = c->dsts->data[0]; \
+       scf_instruction_t* inst = NULL; \
+       \
+       if (!dst->bb) \
+               return -EINVAL; \
+       \
+       if (0 == opcode) \
+               return -EINVAL; \
+       \
+       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); \
+       return 0;\
 }
-//     return arm64_inst_jmp(ctx, c, SCF_ARM64_##op); \
 
-ARM64_INST_JMP(goto, JMP)
-ARM64_INST_JMP(jz,   JZ)
-ARM64_INST_JMP(jnz,  JNZ)
-ARM64_INST_JMP(jgt,  JG)
-ARM64_INST_JMP(jge,  JGE)
-ARM64_INST_JMP(jlt,  JL)
-ARM64_INST_JMP(jle,  JLE)
+ARM64_INST_JMP(goto, 0x14000000)
+ARM64_INST_JMP(jz,   0x54000000)
+ARM64_INST_JMP(jnz,  0x54000001)
+ARM64_INST_JMP(jgt,  0x5400000c)
+ARM64_INST_JMP(jge,  0x5400000a)
+ARM64_INST_JMP(jlt,  0x5400000b)
+ARM64_INST_JMP(jle,  0x5400000d)
 
-ARM64_INST_JMP(ja,   JA)
-ARM64_INST_JMP(jb,   JB)
-ARM64_INST_JMP(jae,  JAE)
-ARM64_INST_JMP(jbe,  JBE)
+ARM64_INST_JMP(ja,   0)
+ARM64_INST_JMP(jb,   0)
+ARM64_INST_JMP(jae,  0)
+ARM64_INST_JMP(jbe,  0)
 
 static int _arm64_inst_load_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
@@ -2102,8 +2276,10 @@ static int _arm64_inst_load_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        }
 
        ret = arm64_load_reg(r, dn, c, f);
-       if (ret < 0)
+       if (ret < 0) {
+               scf_loge("\n");
                return ret;
+       }
 
        ret = scf_vector_add_unique(r->dag_nodes, dn);
        if (ret < 0) {
index 26ce7de1eaee22b01a85bb0c32924e4df3157dc9..a5a39d5a64ebcf8e1f6b67acc62319b08a33bad1 100644 (file)
@@ -26,8 +26,10 @@ scf_register_arm64_t arm64_registers[] = {
        {7, 4, "w7",    ARM64_COLOR(0, 7, 0xf),  NULL, 0},
        {7, 8, "x7",    ARM64_COLOR(0, 7, 0xff), NULL, 0},
 
-       {8, 4, "w8",    ARM64_COLOR(0, 8,  0xf),  NULL, 0},
-       {8, 8, "x8",    ARM64_COLOR(0, 8,  0xff), NULL, 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},
@@ -50,14 +52,16 @@ scf_register_arm64_t        arm64_registers[] = {
        {15, 4, "w15",  ARM64_COLOR(0, 15, 0xf),  NULL, 0},
        {15, 8, "x15",  ARM64_COLOR(0, 15, 0xff), NULL, 0},
 
-       {16, 4, "w16",  ARM64_COLOR(0, 16, 0xf),  NULL, 0},
-       {16, 8, "x16",  ARM64_COLOR(0, 16, 0xff), NULL, 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},
 
-       {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},
+//     {17, 8, "x17",  ARM64_COLOR(0, 17, 0xff), NULL, 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},
+//     {18, 8, "x18",  ARM64_COLOR(0, 18, 0xff), NULL, 0},
 
        {19, 4, "w19",  ARM64_COLOR(0, 19, 0xf),  NULL, 0},
        {19, 8, "x19",  ARM64_COLOR(0, 19, 0xff), NULL, 0},
@@ -304,7 +308,7 @@ int arm64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs)
        return -1;
 }
 
-int arm64_pop_regs(scf_vector_t* instructions, scf_register_arm64_t** regs, int nb_regs, scf_register_arm64_t** updated_regs, int nb_updated)
+int arm64_pop_regs(scf_3ac_code_t* c, scf_register_arm64_t** regs, int nb_regs, scf_register_arm64_t** updated_regs, int nb_updated)
 {
        int i;
        int j;
@@ -313,11 +317,7 @@ int arm64_pop_regs(scf_vector_t* instructions, scf_register_arm64_t** regs, int
        scf_register_arm64_t* r;
        scf_register_arm64_t* r2;
        scf_instruction_t*    inst;
-       scf_arm64_OpCode_t*   pop = arm64_find_OpCode(SCF_ARM64_POP, 8, 8, SCF_ARM64_G);
-       scf_arm64_OpCode_t*   add = arm64_find_OpCode(SCF_ARM64_ADD, 4, 4, SCF_ARM64_I2E);
 
-       uint32_t imm = 8;
-#if 0
        for (j = nb_regs - 1; j >= 0; j--) {
                r2 = regs[j];
 
@@ -348,16 +348,17 @@ int arm64_pop_regs(scf_vector_t* instructions, scf_register_arm64_t** regs, int
                }
 
                if (i == nb_updated) {
-                       inst = arm64_make_inst_G(pop, r2);
-                       ARM64_INST_ADD_CHECK(instructions, inst);
+                       uint32_t pop = (0xf8 << 24) | (0x1 << 22) | (0x8 << 12) | (0x1 << 10) | (0x1f << 5) | r2->id;
+
+                       inst = arm64_make_inst(c, pop);
+                       ARM64_INST_ADD_CHECK(c->instructions, inst);
                } else {
-                       inst = arm64_make_inst_I2E(add, sp, (uint8_t*)&imm, 4);
-                       ARM64_INST_ADD_CHECK(instructions, inst);
+                       uint32_t add8 = (0x91 << 24) | (0x8 << 10) | (sp->id << 5) | sp->id;
+                       inst = arm64_make_inst(c, add8);
+                       ARM64_INST_ADD_CHECK(c->instructions, inst);
                }
        }
        return 0;
-#endif
-       return -1;
 }
 
 int arm64_registers_reset()
@@ -993,8 +994,10 @@ int arm64_load_reg(scf_register_arm64_t* r, scf_dag_node_t* dn, scf_3ac_code_t*
        }
 
        int ret = arm64_make_inst_M2G(c, f, r, NULL, dn->var);
-       if (ret < 0)
+       if (ret < 0) {
+               scf_loge("\n");
                return ret;
+       }
 
        dn->loaded = 1;
        return 0;
index a460de1813722748b0ba47050863e1189563c946..7a9e221c81030c02f6c1022aa1cadb51647300ae 100644 (file)
@@ -60,6 +60,15 @@ static uint32_t arm64_abi_ret_regs[] =
 
 static uint32_t arm64_abi_caller_saves[] =
 {
+       SCF_ARM64_REG_X0,
+       SCF_ARM64_REG_X1,
+       SCF_ARM64_REG_X2,
+       SCF_ARM64_REG_X3,
+       SCF_ARM64_REG_X4,
+       SCF_ARM64_REG_X5,
+       SCF_ARM64_REG_X6,
+       SCF_ARM64_REG_X7,
+
        SCF_ARM64_REG_X9,
        SCF_ARM64_REG_X10,
        SCF_ARM64_REG_X11,
@@ -117,7 +126,7 @@ static inline int arm64_variable_size(scf_variable_t* v)
        if (v->type >= SCF_STRUCT && 0 == v->nb_pointers)
                return 8;
 
-       return v->size;
+       return v->size < 4 ? 4 : v->size;
 }
 
 typedef int         (*arm64_sib_fill_pt)(arm64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* index, scf_3ac_code_t* c, scf_function_t* f);
@@ -146,7 +155,7 @@ int                 arm64_save_var(scf_dag_node_t* dn, scf_3ac_code_t* c, scf_fu
 int                 arm64_save_var2(scf_dag_node_t* dn, scf_register_arm64_t* r, scf_3ac_code_t* c, scf_function_t* f);
 
 int                 arm64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs);
-int                 arm64_pop_regs (scf_vector_t* instructions, scf_register_arm64_t** regs, int nb_regs, scf_register_arm64_t** updated_regs, int nb_updated);
+int                 arm64_pop_regs(scf_3ac_code_t* c, scf_register_arm64_t** regs, int nb_regs, scf_register_arm64_t** updated_regs, int nb_updated);
 
 int                 arm64_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, int nb_regs, int stack_size, scf_register_arm64_t** saved_regs);
 
index 6c3c9f109a7f10c3d77d7405f4c56d420064731f..68ccd4e5b01ec575d4a8e35399b3d7718f41e64f 100644 (file)
@@ -63,6 +63,7 @@ int arm64_make_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64
 {
        scf_register_arm64_t* fp   = arm64_find_register("fp");
        scf_instruction_t*    inst = NULL;
+       scf_rela_t*           rela = NULL;
 
        int32_t  offset;
        uint32_t opcode;
@@ -80,8 +81,19 @@ int arm64_make_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64
                } else if (vs->global_flag) {
                        offset = 0;
 
-                       //      ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
-                       return -EINVAL;
+                       opcode = (0x90 << 24) | rd->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) | (rd->id << 5) | rd->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;
+
+                       rb = rd;
 
                } else {
                        scf_loge("temp var should give a register\n");
@@ -171,6 +183,7 @@ int arm64_make_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64
        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;
 
        int32_t  offset;
        uint32_t opcode;
@@ -188,8 +201,23 @@ int arm64_make_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_arm64
                } else if (vs->global_flag) {
                        offset = 0;
 
-                       //      ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
-                       return -EINVAL;
+                       int ret = arm64_select_free_reg(&rb, c, f);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               return -EINVAL;
+                       }
+
+                       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");