v->local_flag = 0;
v->tmp_flag = 0;
- int ret = arm64_make_inst_M2G(c, f, rabi, NULL, v);
- if (ret < 0)
- return -EINVAL;
+ return arm64_make_inst_M2G(c, f, rabi, NULL, v);
+
} else {
-#if 0
- scf_arm64_OpCode_t* xor;
+ uint32_t opcode;
- xor = arm64_find_OpCode(SCF_ARM64_XOR, size, size, SCF_ARM64_G2E);
- inst = arm64_make_inst_G2E(xor, rabi, rabi);
+ opcode = (0xcb << 24) | (rabi->id << 16) | (rabi->id << 5) | rabi->id;
+ inst = arm64_make_inst(c, opcode);
ARM64_INST_ADD_CHECK(c->instructions, inst);
-#endif
+
+ scf_loge("\n");
return -EINVAL;
}
} else if (scf_variable_const_string(v)) {
- int ret = arm64_make_inst_ISTR2G(c, f, rabi, v);
- if (ret < 0)
- return -EINVAL;
+ return arm64_make_inst_ISTR2G(c, f, rabi, v);
} else if (v->nb_dimentions > 0) {
assert(v->const_literal_flag);
-#if 0
- scf_rela_t* rela = NULL;
-
- lea = arm64_find_OpCode(SCF_ARM64_LEA, size, size, SCF_ARM64_E2G);
- inst = arm64_make_inst_M2G(&rela, lea, rabi, NULL, v);
- 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)
- return -EINVAL;
+ return arm64_make_inst_ADR2G(c, f, rabi, v);
}
- return 0;
+ return arm64_make_inst_I2G(c, rabi, v->data.u64, size);
}
static int _arm64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
scf_arm64_OpCode_t* lea;
scf_arm64_OpCode_t* mov;
scf_arm64_OpCode_t* movx;
- scf_instruction_t* inst;
+ scf_instruction_t* inst;
uint32_t opcode;
int is_float = scf_variable_float(v);
if (!rabi) {
- if (!is_float)
- rabi = arm64_find_register_type_id_bytes(0, SCF_ARM64_REG_X0, size);
- else
- rabi = arm64_find_register_type_id_bytes(1, SCF_ARM64_REG_X0, size);
+ rabi = arm64_find_register_type_id_bytes(is_float, SCF_ARM64_REG_X0, size);
- ret = arm64_overflow_reg(rabi, c, f);
+ ret = arm64_overflow_reg(rabi, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
} else {
nb_floats++;
-#if 0
+
if (0 == src->dag_node->color) {
src->dag_node->color = -1;
v->global_flag = 1;
if (src->dag_node->color < 0)
src->dag_node->color = rabi->color;
-#endif
- scf_loge("\n");
- return -EINVAL;
}
if (!rs) {
else
return -EINVAL;
- } else {
+ } else if (SCF_ARM64_MOVZX == movx->type) {
+
if (1 == size)
opcode = (0x53 << 24) | (0x7 << 10) | (rs->id << 5) | rs->id;
else if (2 == size)
opcode = (0x53 << 24) | (0xf << 10) | (rs->id << 5) | rs->id;
else
return -EINVAL;
+
+ } else {
+ assert(SCF_ARM64_CVTSS2SD == movx->type);
+
+ opcode = (0x1e << 24) | (0x1 << 21) | (0x1 << 17) | (0x3 << 14) | (rs->id << 5) | rs->id;
}
inst = arm64_make_inst(c, opcode);
if (!ARM64_COLOR_CONFLICT(rd->color, rs->color)) {
rd = arm64_find_register_color_bytes(rd->color, rs->bytes);
- opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id;
+ if (is_float)
+ opcode = (0xaa << 24) | (rs->id << 16) | (0x1f << 5) | rd->id;
+ else
+ opcode = (0x1e << 24) | (0x3 << 21) | (0x1 << 14) | (rs->id << 5) | rd->id;
+
inst = arm64_make_inst(c, opcode);
ARM64_INST_ADD_CHECK(c->instructions, inst);
}
+
+ ret = arm64_rcg_make(c, c->rcg, NULL, rd);
+ if (ret < 0)
+ return ret;
}
return nb_floats;
scf_arm64_OpCode_t* mov;
scf_instruction_t* inst;
- int var_size = arm64_variable_size(v);
+ int size = arm64_variable_size(v);
int is_float = scf_variable_float(v);
- assert(var_size == r->bytes);
+ assert(size == r->bytes);
- if (v->const_literal_flag) {
+ if (scf_variable_const(v)) {
scf_logw("const literal var: v_%s_%d_%d not save\n", v->w->text->data, v->w->line, v->w->pos);
goto end;
}
// if temp var in register, alloc it in stack
if (0 == v->bp_offset && !v->global_flag && !v->local_flag) {
- int local_vars_size = f->local_vars_size;
- local_vars_size += var_size;
+ int tmp = f->local_vars_size;
+ tmp += size;
- if (local_vars_size & 0x7)
- local_vars_size = (local_vars_size + 7) >> 3 << 3;
+ if (tmp & 0x7)
+ tmp = (tmp + 7) >> 3 << 3;
- v->bp_offset = -local_vars_size;
+ v->bp_offset = -tmp;
v->tmp_flag = 1;
- f->local_vars_size = local_vars_size;
-
- scf_logw("r: %s, temp var, ", r->name);
- if (v->w)
- printf("v_%d_%d/%s, bp_offset: %d\n", v->w->line, v->w->pos, v->w->text->data, v->bp_offset);
- else
- printf("v_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v, v->bp_offset);
+ f->local_vars_size = tmp;
+ }
- } else {
#if 1
- if (v->w)
- scf_logw("save var: v_%d_%d/%s, ", v->w->line, v->w->pos, v->w->text->data);
- else
- scf_logw("save var: v_%#lx, ", 0xffff & (uintptr_t)v);
- printf("size: %d, bp_offset: %d, r: %s\n", var_size, v->bp_offset, r->name);
+ if (v->w)
+ scf_logw("save var: v_%d_%d/%s, ", v->w->line, v->w->pos, v->w->text->data);
+ else
+ scf_logw("save var: v_%#lx, ", 0xffff & (uintptr_t)v);
+ printf("size: %d, bp_offset: %d, r: %s\n", size, v->bp_offset, r->name);
#endif
- }
-
- if (is_float) {
- scf_loge("\n");
- return -EINVAL;
- }
-
- scf_loge("v->size: %d\n", v->size);
int ret = arm64_make_inst_G2M(c, f, r, NULL, v);
- if (ret < 0) {
- scf_loge("\n");
+ if (ret < 0)
return ret;
- }
end:
// if this var is function argment, it become a normal local var
static uint32_t arm64_abi_float_regs[] =
{
+ SCF_ARM64_REG_D0,
+ SCF_ARM64_REG_D1,
+ SCF_ARM64_REG_D2,
+ SCF_ARM64_REG_D3,
+ SCF_ARM64_REG_D4,
+ SCF_ARM64_REG_D5,
+ SCF_ARM64_REG_D6,
+ SCF_ARM64_REG_D7,
};
#define ARM64_ABI_NB (sizeof(arm64_abi_regs) / sizeof(arm64_abi_regs[0]))
{
scf_instruction_t* inst;
+ uint64_t invert = ~imm;
uint32_t opcode;
+ if (0 == (invert >> 32)) {
+
+ // movn rd, invert[15:0]
+ opcode = (0x92 << 24) | (0x1 << 23) | ((invert & 0xffff) << 5) | rd->id;
+ inst = arm64_make_inst(c, opcode);
+ ARM64_INST_ADD_CHECK(c->instructions, inst);
+
+ if (invert >> 16) {
+ // movk rd, imm[31:16]
+ opcode = (0xf2 << 24) | (0x1 << 23) | (0x1 << 21) | (((imm >> 16) & 0xffff) << 5) | rd->id;
+ inst = arm64_make_inst(c, opcode);
+ ARM64_INST_ADD_CHECK(c->instructions, inst);
+ }
+
+ return 0;
+ }
+
// mov rd, imm[15:0]
opcode = (0xd2 << 24) | (0x1 << 23) | ((imm & 0xffff) << 5) | rd->id;
inst = arm64_make_inst(c, opcode);
return -EINVAL;
}
- opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
-
- if (offset >> 16) {
- opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
- }
+ ret = arm64_make_inst_I2G(c, ri, offset, 4);
+ if (ret < 0)
+ return ret;
opcode = (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10);
}
return -EINVAL;
}
- opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
-
- if (offset >> 16) {
- opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
- }
+ ret = arm64_make_inst_I2G(c, ri, offset, 4);
+ if (ret < 0)
+ return ret;
opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id;
}
return -EINVAL;
}
- opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
-
- if (offset >> 16) {
- opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
- }
+ ret = arm64_make_inst_I2G(c, ri, offset, 4);
+ if (ret < 0)
+ return ret;
opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rs->id;
}
return -EINVAL;
}
- opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
-
- if (offset >> 16) {
- opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ri->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
- }
+ ret = arm64_make_inst_I2G(c, ri, offset, 4);
+ if (ret < 0)
+ return ret;
opcode = (SIZE << 30) | (0x38 << 24) | (0x1 << 22) | (0x1 << 21) | (ri->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10) | (rb->id << 5) | rd->id;
}
if (ret < 0)
return ret;
- opcode = (0x52 << 24) | (0x1 << 23) | ((offset & 0xffff) << 5) | ro->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
-
- if (offset >> 16) {
- opcode = (0x72 << 24) | (0x1 << 23) | (((offset >> 16) & 0xffff) << 5) | ro->id;
- inst = arm64_make_inst(c, opcode);
- ARM64_INST_ADD_CHECK(c->instructions, inst);
- }
+ ret = arm64_make_inst_I2G(c, ro, offset, 4);
+ if (ret < 0)
+ return ret;
opcode = (0x3c << 24) | (0x1 << 22) | (0x1 << 21) | (ro->id << 16) | (0x3 << 13) | (S << 12) | (0x2 << 10);
}
enum scf_x64_REGs {
SCF_ARM64_REG_W0 = 0,
SCF_ARM64_REG_X0 = 0,
+ SCF_ARM64_REG_S0 = 0,
+ SCF_ARM64_REG_D0 = 0,
SCF_ARM64_REG_W1 = 1,
SCF_ARM64_REG_X1 = 1,
+ SCF_ARM64_REG_S1 = 1,
+ SCF_ARM64_REG_D1 = 1,
SCF_ARM64_REG_W2 = 2,
SCF_ARM64_REG_X2 = 2,
+ SCF_ARM64_REG_S2 = 2,
+ SCF_ARM64_REG_D2 = 2,
SCF_ARM64_REG_W3 = 3,
SCF_ARM64_REG_X3 = 3,
+ SCF_ARM64_REG_S3 = 3,
+ SCF_ARM64_REG_D3 = 3,
SCF_ARM64_REG_W4 = 4,
SCF_ARM64_REG_X4 = 4,
+ SCF_ARM64_REG_S4 = 4,
+ SCF_ARM64_REG_D4 = 4,
SCF_ARM64_REG_W5 = 5,
SCF_ARM64_REG_X5 = 5,
+ SCF_ARM64_REG_S5 = 5,
+ SCF_ARM64_REG_D5 = 5,
SCF_ARM64_REG_W6 = 6,
SCF_ARM64_REG_X6 = 6,
+ SCF_ARM64_REG_S6 = 6,
+ SCF_ARM64_REG_D6 = 6,
SCF_ARM64_REG_W7 = 7,
SCF_ARM64_REG_X7 = 7,
+ SCF_ARM64_REG_S7 = 7,
+ SCF_ARM64_REG_D7 = 7,
SCF_ARM64_REG_W8 = 8,
SCF_ARM64_REG_X8 = 8,
assert(var_size == r->bytes);
- if (v->const_literal_flag) {
+ if (scf_variable_const(v)) {
scf_logw("const literal var: v_%s_%d_%d not save\n", v->w->text->data, v->w->line, v->w->pos);
goto end;
}