return -EINVAL; \
}
+
static int _arm64_inst_call_stack_size(scf_3ac_code_t* c)
{
int stack_size = 0;
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)
}
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;
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);
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;
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;
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)
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)
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;
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);
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);
ARM64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
#endif
- return 0;
+ return -1;
}
static int _arm64_inst_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
-// return arm64_inst_pointer(ctx, c, 0);
- return -1;
-}
+ if (!c->dsts || c->dsts->size != 1)
+ return -EINVAL;
-static int _arm64_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)
-{
- if (!c->srcs || c->srcs->size != 4)
+ if (!c->srcs || c->srcs->size != 2)
return -EINVAL;
- scf_arm64_context_t* arm64 = ctx->priv;
- scf_function_t* f = arm64->f;
+ scf_arm64_context_t* arm64 = ctx->priv;
+ scf_function_t* f = arm64->f;
+ scf_3ac_operand_t* dst = c->dsts->data[0];
scf_3ac_operand_t* base = c->srcs->data[0];
- scf_3ac_operand_t* index = c->srcs->data[1];
- scf_3ac_operand_t* scale = c->srcs->data[2];
- scf_3ac_operand_t* src = c->srcs->data[3];
+ scf_3ac_operand_t* member = c->srcs->data[1];
+ scf_instruction_t* inst;
if (!base || !base->dag_node)
return -EINVAL;
- if (!index || !index->dag_node)
- return -EINVAL;
-
- if (!scale || !scale->dag_node)
- return -EINVAL;
-
- if (!src || !src->dag_node)
+ if (!member || !member->dag_node)
return -EINVAL;
if (!c->instructions) {
return -ENOMEM;
}
- scf_variable_t* vscale = scale->dag_node->var;
- scf_variable_t* vb = base->dag_node->var;
- scf_variable_t* vs = src ->dag_node->var;
-
- scf_register_arm64_t* rs = NULL;
- arm64_sib_t sib = {0};
-
- scf_instruction_t* inst;
-
- int is_float = scf_variable_float(vs);
- int size = arm64_variable_size (vs);
+ scf_variable_t* vd = dst ->dag_node->var;
+ scf_variable_t* vb = base ->dag_node->var;
+ scf_variable_t* vm = member->dag_node->var;
- if (size > vscale->data.i)
- size = vscale->data.i;
+ scf_register_arm64_t* rd = NULL;
+ arm64_sib_t sib = {0};
- int ret = arm64_array_index_reg(&sib, base->dag_node, index->dag_node, scale->dag_node, c, f);
- if (ret < 0) {
- scf_loge("\n");
+ int ret = arm64_select_reg(&rd, dst->dag_node, c, f, 0);
+ if (ret < 0)
return ret;
- }
-
- if (vb->nb_dimentions > 1) {
-
- } else {
- if (is_float) {
-
- if (0 == src->dag_node->color) {
- src->dag_node->color = -1;
- vs->global_flag = 1;
- }
- scf_loge("\n");
- return -EINVAL;
-
- }
-
- if (0 == src->dag_node->color)
- src->dag_node->color = -1;
- }
-
- ret = arm64_select_reg(&rs, src->dag_node, c, f, 1);
- if (ret < 0) {
- scf_loge("\n");
+ ret = arm64_pointer_reg(&sib, base->dag_node, member->dag_node, c, f);
+ if (ret < 0)
return ret;
- }
- rs = arm64_find_register_color_bytes(rs->color, size);
+ if (scf_variable_is_struct(vm) || scf_variable_is_array(vm))
- if (sib.index)
- ret = arm64_make_inst_G2SIB(c, f, rs, &sib);
- else
- ret = arm64_make_inst_G2P(c, f, rs, sib.base, sib.disp, size);
+ return arm64_make_inst_ADRP2G(c, f, rd, sib.base, sib.disp);
- if (ret < 0) {
- scf_loge("\n");
- return ret;
- }
+ if (sib.index)
+ return arm64_make_inst_SIB2G(c, f, rd, &sib);
- return 0;
+ return arm64_make_inst_P2G(c, f, rd, sib.base, sib.disp, sib.size);
}
-static int _arm64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_flag)
+static int _arm64_inst_binary_assign_pointer(scf_native_t* ctx, scf_3ac_code_t* c, uint32_t op)
{
- if (!c->dsts || c->dsts->size != 1)
- return -EINVAL;
-
if (!c->srcs || c->srcs->size != 3)
return -EINVAL;
- scf_arm64_context_t* arm64 = ctx->priv;
- scf_function_t* f = arm64->f;
+ scf_arm64_context_t* arm64 = ctx->priv;
+ scf_function_t* f = arm64->f;
- scf_3ac_operand_t* dst = c->dsts->data[0];
scf_3ac_operand_t* base = c->srcs->data[0];
- scf_3ac_operand_t* index = c->srcs->data[1];
- scf_3ac_operand_t* scale = c->srcs->data[2];
+ scf_3ac_operand_t* member = c->srcs->data[1];
+ scf_3ac_operand_t* src = c->srcs->data[2];
+ scf_instruction_t* inst;
if (!base || !base->dag_node)
return -EINVAL;
- if (!index || !index->dag_node)
+ if (!member || !member->dag_node)
return -EINVAL;
- if (!scale || !scale->dag_node)
+ if (!src || !src->dag_node)
return -EINVAL;
if (!c->instructions) {
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();
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();
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();
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();
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) {
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) {
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();
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();
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);
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;
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) {
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();
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();
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[] = {
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)
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) {
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;
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;
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;
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;
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;
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;
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;
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);
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)
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;
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;
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;
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;
{
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)
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)
{
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)
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)
{
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) \
{ \
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)
{
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)
{
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)
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;
} 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;
}
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;
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)
#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)
#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)
{ \
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)
{
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)
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[] = {
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)
r->dag_nodes = scf_vector_alloc();
if (!r->dag_nodes)
return -ENOMEM;
+
+ r->used = 0;
}
return 0;
scf_vector_free(r->dag_nodes);
r->dag_nodes = NULL;
}
+
+ r->used = 0;
}
}
}
}
+ r->used = 1;
return 0;
}
}
}
+ r->used = 1;
return 0;
}
}
}
+ r->used = 1;
return 0;
}
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;
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;
scf_variable_t* v = dn->var;
+ r->used = 1;
+
int size = arm64_variable_size(v);
if (SCF_FUNCTION_PTR == v->type) {
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)) {
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;
}
#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;
} 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;
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;
}
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;
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)
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;