From: yu.dongliang <18588496441@163.com> Date: Tue, 21 Feb 2023 11:10:23 +0000 (+0800) Subject: support arm64: 'hanoi' test ok, ../examples/hanoi.c X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=3f89a75e2476106ce4c107c5140da461bddf468c;p=scf.git support arm64: 'hanoi' test ok, ../examples/hanoi.c --- diff --git a/examples/hanoi.c b/examples/hanoi.c index 1ebb025..2db3cc0 100644 --- a/examples/hanoi.c +++ b/examples/hanoi.c @@ -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; } diff --git a/native/arm64/scf_arm64.c b/native/arm64/scf_arm64.c index 9d9c145..e928850 100644 --- a/native/arm64/scf_arm64.c +++ b/native/arm64/scf_arm64.c @@ -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; diff --git a/native/arm64/scf_arm64_inst.c b/native/arm64/scf_arm64_inst.c index 9de9981..cc88022 100644 --- a/native/arm64/scf_arm64_inst.c +++ b/native/arm64/scf_arm64_inst.c @@ -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) { diff --git a/native/arm64/scf_arm64_reg.c b/native/arm64/scf_arm64_reg.c index 26ce7de..a5a39d5 100644 --- a/native/arm64/scf_arm64_reg.c +++ b/native/arm64/scf_arm64_reg.c @@ -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; diff --git a/native/arm64/scf_arm64_reg.h b/native/arm64/scf_arm64_reg.h index a460de1..7a9e221 100644 --- a/native/arm64/scf_arm64_reg.h +++ b/native/arm64/scf_arm64_reg.h @@ -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); diff --git a/native/arm64/scf_arm64_util.c b/native/arm64/scf_arm64_util.c index 6c3c9f1..68ccd4e 100644 --- a/native/arm64/scf_arm64_util.c +++ b/native/arm64/scf_arm64_util.c @@ -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");