v = dn->var;
if (v && v->w)
- printf("entry active: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+ printf("entry active: v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
}
}
v = dn->var;
if (v && v->w)
- printf("exit active: v_%d_%d/%s, dn: %#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
+ printf("exit active: v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
}
}
v = dn->var;
if (v && v->w)
- printf("updated: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+ printf("updated: v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
}
}
dn = ds->dag_node;
- if (scf_variable_const(dn->var))
- continue;
-
if (active == ds->active && scf_dn_through_bb(dn)) {
int ret = scf_vector_add_unique(dn_vec, dn);
static int scf_dn_through_bb(scf_dag_node_t* dn)
{
- return (dn->var->global_flag || dn->var->local_flag || dn->var->tmp_flag)
- && !scf_variable_const(dn->var);
+ scf_variable_t* v = dn->var;
+
+ return (v->global_flag || v->local_flag || v->tmp_flag)
+ && !(v->const_flag && 0 == v->nb_pointers + v->nb_dimentions);
}
static int scf_dn_status_cmp(const void* p0, const void* p1)
printf("%d(%s, %s, %d), ", inst->src.disp, inst->src.base->name,
inst->src.index->name, inst->src.scale);
- else if (inst->src.base)
- printf("%d(%s), ", inst->src.disp, inst->src.base->name);
- else
+ else if (inst->src.base) {
+ if (inst->src.disp < 0)
+ printf("-%#x(%s), ", -inst->src.disp, inst->src.base->name);
+ else
+ printf("%#x(%s), ", inst->src.disp, inst->src.base->name);
+ } else
printf("%d(rip), ", inst->dst.disp);
} else if (inst->src.base)
printf("%d(%s, %s, %d), ", inst->dst.disp, inst->dst.base->name,
inst->dst.index->name, inst->dst.scale);
- else if (inst->dst.base)
- printf("%d(%s), ", inst->dst.disp, inst->dst.base->name);
- else
+ else if (inst->dst.base) {
+ if (inst->dst.disp < 0)
+ printf("-%#x(%s), ", -inst->dst.disp, inst->dst.base->name);
+ else
+ printf("%#x(%s), ", inst->dst.disp, inst->dst.base->name);
+ } else
printf("%d(rip), ", inst->dst.disp);
} else if (inst->dst.base)
if (is_float) {
- if (f->args_float < X64_ABI_NB) {
+ if (f->args_float < X64_ABI_FLOAT_NB) {
v->rabi = x64_find_register_type_id_bytes(is_float, x64_abi_float_regs[f->args_float], size);
v->bp_offset = bp_floats;
_x64_argv_rabi(f);
- int local_vars_size = 8 + X64_ABI_NB * 8 * 2;
+ int local_vars_size = 8 + (X64_ABI_NB + X64_ABI_FLOAT_NB) * 8;
for (i = 0; i < local_vars->size; i++) {
v = local_vars->data[i];
scf_x64_OpCode_t* mov;
scf_x64_OpCode_t* movx;
scf_instruction_t* inst;
+ scf_instruction_t* inst_movx[X64_ABI_NB + X64_ABI_FLOAT_NB] = {NULL};
+ int nb_movx = 0;
int nb_floats = 0;
int ret;
int i;
+
for (i = c->srcs->size - 1; i >= 1; i--) {
scf_3ac_operand_t* src = c->srcs->data[i];
scf_variable_t* v = src->dag_node->var;
rs = x64_find_register_color_bytes(rs->color, 8);
}
- if (movx) {
- inst = x64_make_inst_E2G(movx, rs, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
- }
-
if (!rd) {
+ if (movx) {
+ inst = x64_make_inst_E2G(movx, rs, rs);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+ }
+
inst = x64_make_inst_G2P(mov, rsp, v->sp_offset, rs);
X64_INST_ADD_CHECK(c->instructions, inst);
continue;
}
if (!X64_COLOR_CONFLICT(rd->color, rs->color)) {
+ if (movx) {
+ inst = x64_make_inst_E2G(movx, rs, rs);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+ }
+
rd = x64_find_register_color_bytes(rd->color, rs->bytes);
inst = x64_make_inst_G2E(mov, rd, rs);
X64_INST_ADD_CHECK(c->instructions, inst);
+
+ } else if (movx) {
+ inst = x64_make_inst_E2G(movx, rs, rs);
+ if (!inst) {
+ scf_loge("\n");
+ return -ENOMEM;
+ }
+
+ inst_movx[nb_movx++] = inst;
}
}
+ for (i = 0; i < nb_movx; i++) {
+ X64_INST_ADD_CHECK(c->instructions, inst_movx[i]);
+ }
+
return nb_floats;
}
scf_register_t* rsp = x64_find_register("rsp");
scf_register_t* rax = x64_find_register("rax");
+ scf_register_t* eax = x64_find_register("eax");
// scf_x64_OpCode_t* xor;
scf_x64_OpCode_t* mov;
scf_x64_OpCode_t* sub;
scf_loge("\n");
return ret;
}
- uint64_t imm = ret > 0;
+ uint32_t imm = ret > 0;
- mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_I2G);
- inst = x64_make_inst_I2G(mov, rax, (uint8_t*)&imm, sizeof(imm));
+ mov = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_I2G);
+ inst = x64_make_inst_I2G(mov, eax, (uint8_t*)&imm, sizeof(imm));
X64_INST_ADD_CHECK(c->instructions, inst);
scf_register_t* saved_regs[X64_ABI_CALLER_SAVES_NB];
- int save_size = x64_caller_save_regs(c->instructions, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
+ int save_size = x64_caller_save_regs(c, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
if (save_size < 0) {
scf_loge("\n");
return save_size;
int size = x64_variable_size(v);
uint32_t nints = X64_ABI_NB;
- uint32_t nfloats = X64_ABI_NB;
+ uint32_t nfloats = X64_ABI_FLOAT_NB;
uint32_t offset = 0;
uint32_t incptr = 8;
}
}
-int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
+int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
{
- int i;
- int j;
+ scf_basic_block_t* bb = c->basic_block;
+ scf_dag_node_t* dn;
+
+ scf_instruction_t* inst;
+ scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+ scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E);
+ scf_register_t* rsp = x64_find_register("rsp");
scf_register_t* r;
scf_register_t* r2;
- scf_register_t* rsp = x64_find_register("rsp");
- scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E);
- scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
- scf_instruction_t* inst;
+ int i;
+ int j;
+ int k;
int size = 0;
- int k = 0;
+ int n = 0;
for (j = 0; j < nb_regs; j++) {
r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
if (0 == r->dag_nodes->size)
continue;
- if (X64_COLOR_CONFLICT(r2->color, r->color))
- break;
+ if (X64_COLOR_CONFLICT(r2->color, r->color)) {
+
+ for (k = 0; k < r->dag_nodes->size; k++) {
+ dn = r->dag_nodes->data[k];
+
+ if (scf_vector_find(bb->exit_dn_actives, dn)
+ || scf_vector_find(bb->dn_saves, dn)
+ || scf_vector_find(bb->dn_resaves, dn)) {
+
+ scf_variable_t* v = dn->var;
+ if (v && v->w)
+ scf_logw("dn: %#lx, v_%d/%s/%#lx\n", 0xffff & (uintptr_t)dn, v->w->line, v->w->text->data, 0xffff & (uintptr_t)v);
+ else
+ scf_logw("dn: %#lx, v_%#lx\n", 0xffff & (uintptr_t)dn, 0xffff & (uintptr_t)v);
+ break;
+ }
+ }
+
+ if (k < r->dag_nodes->size)
+ break;
+ }
}
if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
else
inst = x64_make_inst_G(push, r2);
- X64_INST_ADD_CHECK(instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst);
- saved_regs[k++] = r2;
+ saved_regs[n++] = r2;
size += 8;
}
if (size & 0xf) {
- r2 = saved_regs[k - 1];
+ r2 = saved_regs[n - 1];
if (stack_size > 0)
inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
else
inst = x64_make_inst_G(push, r2);
- X64_INST_ADD_CHECK(instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst);
- saved_regs[k++] = r2;
+ saved_regs[n++] = r2;
size += 8;
}
if (stack_size > 0) {
- for (j = 0; j < k / 2; j++) {
+ for (j = 0; j < n / 2; j++) {
- i = k - 1 - j;
+ i = n - 1 - j;
SCF_XCHG(saved_regs[i], saved_regs[j]);
}
}
int size = x64_variable_size (dn->var);
if (is_float) {
- if (nfloats < X64_ABI_NB)
+ if (nfloats < X64_ABI_FLOAT_NB)
dn->rabi2 = x64_find_register_type_id_bytes(is_float, x64_abi_float_regs[nfloats++], size);
else
dn->rabi2 = NULL;
SCF_X64_REG_R8,
SCF_X64_REG_R9,
};
+#define X64_ABI_NB (sizeof(x64_abi_regs) / sizeof(x64_abi_regs[0]))
static uint32_t x64_abi_float_regs[] =
{
SCF_X64_REG_XMM1,
SCF_X64_REG_XMM2,
SCF_X64_REG_XMM3,
+ SCF_X64_REG_XMM4,
+ SCF_X64_REG_XMM5,
+ SCF_X64_REG_XMM6,
+ SCF_X64_REG_XMM7,
};
-#define X64_ABI_NB (sizeof(x64_abi_regs) / sizeof(x64_abi_regs[0]))
+#define X64_ABI_FLOAT_NB (sizeof(x64_abi_float_regs) / sizeof(x64_abi_float_regs[0]))
static uint32_t x64_abi_ret_regs[] =
{
int x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs);
int x64_pop_regs (scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated);
-int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
+
+int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f);
int x64_pop_callee_regs (scf_3ac_code_t* c, scf_function_t* f);