int main()
{
- hanoi(4, 'A', 'B', 'C');
+ hanoi(5, 'A', 'B', 'C');
return 0;
}
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) {
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);
_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)
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;
}
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;
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;
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;
}
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;
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;
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;
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)
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);
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) \
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)
{
}
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) {
{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},
{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},
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;
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];
}
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()
}
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;
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,
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);
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);
{
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;
} 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");
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;
} 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");