scf_3ac_code_t* init_code;
int init_code_bytes;
+ int callee_saved_size;
int local_vars_size;
int code_bytes;
int arm64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
scf_register_t* r2;
- scf_dag_node_t* dn2;
+ scf_dag_node_t* dn2;
int i;
int j;
scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G);
scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_G2E);
scf_x64_OpCode_t* sub = x64_find_OpCode(SCF_X64_SUB, 4,8, SCF_X64_I2E);
+ scf_x64_OpCode_t* ret = x64_find_OpCode(SCF_X64_RET, 8,8, SCF_X64_G);
- scf_register_t* rsp = x64_find_register("rsp");
- scf_register_t* rbp = x64_find_register("rbp");
- scf_register_t* r;
+ scf_register_t* rsp = x64_find_register("rsp");
+ scf_register_t* rbp = x64_find_register("rbp");
+ scf_register_t* r;
scf_instruction_t* inst = NULL;
+ scf_basic_block_t* bb;
+ scf_3ac_code_t* end;
+ scf_list_t* l;
+
+ l = scf_list_tail(&f->basic_block_list_head);
+ bb = scf_list_data(l, scf_basic_block_t, list);
+
+ l = scf_list_tail(&bb->code_list_head);
+ end = scf_list_data(l, scf_3ac_code_t, list);
+
+ int err = x64_pop_callee_regs(end, f);
+ if (err < 0)
+ return err;
+
if (f->bp_used_flag) {
+ inst = x64_make_inst_G2E(mov, rsp, rbp);
+ X64_INST_ADD_CHECK(end->instructions, inst);
+ end->inst_bytes += inst->len;
+ bb ->code_bytes += inst->len;
+
+ inst = x64_make_inst_G(pop, rbp);
+ X64_INST_ADD_CHECK(end->instructions, inst);
+ end->inst_bytes += inst->len;
+ bb ->code_bytes += inst->len;
inst = x64_make_inst_G(push, rbp);
X64_INST_ADD_CHECK(f->init_code->instructions, inst);
f->init_code_bytes += inst->len;
uint32_t local = f->local_vars_size;
- if (!(local & 0xf))
- local += 8;
+
+ if (f->callee_saved_size & 0xf) {
+ if (!(local & 0xf))
+ local += 8;
+ } else {
+ if ((local & 0xf))
+ local += 8;
+ }
+
+ scf_logw("### local: %#x, local_vars_size: %#x, callee_saved_size: %#x\n",
+ local, f->local_vars_size, f->callee_saved_size);
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&local, 4);
- //inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&f->local_vars_size, 4);
X64_INST_ADD_CHECK(f->init_code->instructions, inst);
f->init_code_bytes += inst->len;
- int ret = _x64_save_rabi(f);
- if (ret < 0)
- return ret;
+ int err = _x64_save_rabi(f);
+ if (err < 0)
+ return err;
} else
f->init_code_bytes = 0;
- int i;
- for (i = 0; i < X64_ABI_CALLEE_SAVES_NB; i++) {
-
- r = x64_find_register_type_id_bytes(0, x64_abi_callee_saves[i], 8);
+ err = x64_push_callee_regs(f->init_code, f);
+ if (err < 0)
+ return err;
- inst = x64_make_inst_G(push, r);
- X64_INST_ADD_CHECK(f->init_code->instructions, inst);
-
- f->init_code_bytes += inst->len;
- }
+ inst = x64_make_inst(ret, 8);
+ X64_INST_ADD_CHECK(end->instructions, inst);
+ end->inst_bytes += inst->len;
+ bb ->code_bytes += inst->len;
x64_registers_clear();
return 0;
return -ENOMEM;
}
- scf_register_t* rsp = x64_find_register("rsp");
- scf_register_t* rbp = x64_find_register("rbp");
- scf_register_t* r;
-
- scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G);
- scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
- scf_x64_OpCode_t* ret = x64_find_OpCode(SCF_X64_RET, 8, 8, SCF_X64_G);
- scf_instruction_t* inst = NULL;
-
- int i;
- for (i = X64_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) {
-
- r = x64_find_register_type_id_bytes(0, x64_abi_callee_saves[i], 8);
-
- inst = x64_make_inst_G(pop, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
- }
-
- inst = x64_make_inst_G2E(mov, rsp, rbp);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
- inst = x64_make_inst_G(pop, rbp);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
- inst = x64_make_inst(ret, 8);
- X64_INST_ADD_CHECK(c->instructions, inst);
return 0;
}
return -ENOMEM;
}
- scf_register_t* rax = x64_find_register("rax");
- scf_x64_OpCode_t* push;
+ scf_register_t* rax = x64_find_register("rax");
+ scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
scf_instruction_t* inst;
- push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+ inst = x64_make_inst_G(push, rax);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+
inst = x64_make_inst_G(push, rax);
X64_INST_ADD_CHECK(c->instructions, inst);
return 0;
return -ENOMEM;
}
- scf_register_t* rax = x64_find_register("rax");
- scf_x64_OpCode_t* pop;
+ scf_register_t* rax = x64_find_register("rax");
+ scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G);
scf_instruction_t* inst;
- pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G);
+ inst = x64_make_inst_G(pop, rax);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+
inst = x64_make_inst_G(pop, rax);
X64_INST_ADD_CHECK(c->instructions, inst);
return 0;
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;
}
}
{
int i;
int j;
- scf_register_t* r;
- scf_register_t* r2;
- scf_instruction_t* inst;
- 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 size = 0;
int k = 0;
}
}
+ r->used = 1;
return 0;
}
int x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
scf_register_t* r2;
- scf_dag_node_t* dn2;
+ scf_dag_node_t* dn2;
int i;
int j;
}
}
+ r->used = 1;
return 0;
}
}
}
+ r->used = 1;
return 0;
}
return NULL;
}
-int x64_load_const(scf_register_t* rabi, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
+int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
scf_instruction_t* inst;
scf_x64_OpCode_t* lea;
scf_variable_t* v;
v = dn->var;
+ r->used = 1;
int size = x64_variable_size(v);
int is_float = scf_variable_float(v);
scf_rela_t* rela = NULL;
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
X64_INST_ADD_CHECK(c->instructions, inst);
X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
scf_x64_OpCode_t* xor;
xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
- inst = x64_make_inst_G2E(xor, rabi, rabi);
+ inst = x64_make_inst_G2E(xor, r, r);
X64_INST_ADD_CHECK(c->instructions, inst);
}
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
X64_INST_ADD_CHECK(c->instructions, inst);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
- inst = x64_make_inst_M2G(&rela, lea, rabi, NULL, v);
+ inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
X64_INST_ADD_CHECK(c->instructions, inst);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
} else {
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
- inst = x64_make_inst_I2G(mov, rabi, (uint8_t*)&v->data, size);
+ inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size);
X64_INST_ADD_CHECK(c->instructions, inst);
}
int is_float = scf_variable_float(dn->var);
int var_size = x64_variable_size(dn->var);
+ r->used = 1;
+
if (!is_float) {
if (scf_variable_const(dn->var)) {
} else
dn->loaded = 1;
+ r->used = 1;
*preg = r;
return 0;
}
*p_nfloats = nfloats;
}
+int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
+{
+ scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+
+ scf_instruction_t* inst;
+ scf_register_t* r2;
+ scf_register_t* r;
+
+ int N = sizeof(x64_registers) / sizeof(x64_registers[0]);
+ int i;
+ int j;
+
+ for (i = 0; i < X64_ABI_CALLEE_SAVES_NB; i++) {
+
+ j = x64_abi_callee_saves[i];
+ r = x64_find_register_type_id_bytes(0, j, 8);
+
+ for (j = 0; j < N; j++) {
+ r2 = &(x64_registers[j]);
+
+ if (r2->used && X64_COLOR_CONFLICT(r2->color, r->color))
+ break;
+ }
+
+ if (j < N) {
+ inst = x64_make_inst_G(push, r);
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst);
+
+ f->init_code_bytes += inst->len;
+ }
+ }
+
+ return 0;
+}
+
+int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
+{
+ scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G);
+
+ scf_basic_block_t* bb = c->basic_block;
+
+ scf_instruction_t* inst;
+ scf_register_t* r2;
+ scf_register_t* r;
+
+ int N = sizeof(x64_registers) / sizeof(x64_registers[0]);
+ int i;
+ int j;
+
+ f->callee_saved_size = 0;
+
+ for (i = X64_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) {
+
+ j = x64_abi_callee_saves[i];
+ r = x64_find_register_type_id_bytes(0, j, 8);
+
+ for (j = 0; j < N; j++) {
+ r2 = &(x64_registers[j]);
+
+ if (r2->used && X64_COLOR_CONFLICT(r2->color, r->color))
+ break;
+ }
+
+ if (j < N) {
+ inst = x64_make_inst_G(pop, r);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+
+ bb->code_bytes += inst->len;
+ f->callee_saved_size += 8;
+ }
+ }
+
+ return 0;
+}
+
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_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);
+
int x64_save_reg (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
int x64_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);