return scf_ast_find_global_type_type(pt, ast, type);
}
+int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w)
+{
+ scf_variable_t* v;
+ scf_lex_word_t* w2;
+ scf_type_t* t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR);
+ scf_node_t* node;
+
+ w2 = scf_lex_word_clone(w);
+ if (!w2)
+ return -ENOMEM;
+
+ int ret = scf_string_cat_cstr(w2->text, "__cstr");
+ if (ret < 0) {
+ scf_lex_word_free(w2);
+ return ret;
+ }
+
+ v = SCF_VAR_ALLOC_BY_TYPE(w2, t, 1, 1, NULL);
+ scf_lex_word_free(w2);
+ w2 = NULL;
+ if (!v)
+ return -ENOMEM;
+ v->const_literal_flag = 1;
+
+ scf_logi("w->text: %s\n", w->text->data);
+ v->data.s = scf_string_clone(w->text);
+ if (!v->data.s) {
+ scf_variable_free(v);
+ return -ENOMEM;
+ }
+
+ node = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!node)
+ return -ENOMEM;
+
+ ret = scf_node_add_child(parent, node);
+ if (ret < 0) {
+ scf_node_free(node);
+ return ret;
+ }
+
+ return 0;
+}
+
+int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64)
+{
+ scf_variable_t* v;
+ scf_type_t* t = scf_block_find_type_type(ast->current_block, type);
+ scf_node_t* node;
+
+ v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
+ if (!v)
+ return -ENOMEM;
+ v->data.u64 = u64;
+ v->const_literal_flag = 1;
+
+ node = scf_node_alloc(NULL, v->type, v);
+ scf_variable_free(v);
+ v = NULL;
+ if (!node)
+ return -ENOMEM;
+
+ int ret = scf_node_add_child(parent, node);
+ if (ret < 0) {
+ scf_node_free(node);
+ return ret;
+ }
+
+ return 0;
+}
+
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f)
+{
+ scf_string_t* s;
+ scf_type_t* t = (scf_type_t*)f->node.parent;
+
+ int ret;
+ int i;
+
+ s = scf_string_alloc();
+ if (!s)
+ return -ENOMEM;
+
+ if (t->node.type >= SCF_STRUCT) {
+ assert(t->node.class_flag);
+
+ ret = scf_string_cat(s, t->name);
+ if (ret < 0)
+ goto error;
+
+ ret = scf_string_cat_cstr(s, "_");
+ if (ret < 0)
+ goto error;
+ }
+
+ if (f->op_type >= 0) {
+ scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
+
+ if (!op->signature)
+ goto error;
+
+ ret = scf_string_cat_cstr(s, op->signature);
+ } else
+ ret = scf_string_cat(s, f->node.w->text);
+
+ if (ret < 0)
+ goto error;
+ scf_logd("f signature: %s\n", s->data);
+
+ if (t->node.type < SCF_STRUCT) {
+ if (f->signature)
+ scf_string_free(f->signature);
+
+ f->signature = s;
+ return 0;
+ }
+
+ if (f->argv) {
+ for (i = 0; i < f->argv->size; i++) {
+ scf_variable_t* v = f->argv->data[i];
+ scf_type_t* t_v = NULL;
+
+ t_v = scf_block_find_type_type((scf_block_t*)t, v->type);
+ if (!t_v) {
+ ret = scf_ast_find_global_type_type(&t_v, ast, v->type);
+ if (ret < 0)
+ goto error;
+ }
+
+ ret = scf_string_cat_cstr(s, "_");
+ if (ret < 0)
+ goto error;
+
+ scf_logd("t_v: %p, v->type: %d, v->w->text->data: %s\n", t_v, v->type, v->w->text->data);
+
+ const char* abbrev = scf_type_find_abbrev(t_v->name->data);
+ if (abbrev)
+ ret = scf_string_cat_cstr(s, abbrev);
+ else
+ ret = scf_string_cat(s, t_v->name);
+ if (ret < 0)
+ goto error;
+
+ if (v->nb_pointers > 0) {
+ char buf[64];
+ snprintf(buf, sizeof(buf) - 1, "%d", v->nb_pointers);
+
+ ret = scf_string_cat_cstr(s, buf);
+ if (ret < 0)
+ goto error;
+ }
+ }
+ }
+
+ scf_logd("f signature: %s\n", s->data);
+
+ if (f->signature)
+ scf_string_free(f->signature);
+ f->signature = s;
+ return 0;
+
+error:
+ scf_string_free(s);
+ return -1;
+}
int scf_ast_add_file_block(scf_ast_t* ast, const char* path);
-#endif
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f);
+
+int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w);
+int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64);
+#endif
return scf_function_same_argv(f0->argv, f1->argv);
}
-
-int scf_function_signature(scf_function_t* f)
-{
- scf_string_t* s;
- scf_type_t* t = (scf_type_t*)f->node.parent;
-
- int ret;
- int i;
-
- s = scf_string_alloc();
- if (!s)
- return -ENOMEM;
-
- if (t->node.type >= SCF_STRUCT) {
- assert(t->node.class_flag);
-
- ret = scf_string_cat(s, t->name);
- if (ret < 0)
- goto error;
-
- ret = scf_string_cat_cstr(s, "_");
- if (ret < 0)
- goto error;
- }
-
- if (f->op_type >= 0) {
- scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
-
- if (!op->signature)
- goto error;
-
- ret = scf_string_cat_cstr(s, op->signature);
- } else
- ret = scf_string_cat(s, f->node.w->text);
-
- if (ret < 0)
- goto error;
- scf_logd("f signature: %s\n", s->data);
-
- if (t->node.type < SCF_STRUCT) {
- if (f->signature)
- scf_string_free(f->signature);
-
- f->signature = s;
- return 0;
- }
-
- if (f->argv) {
- for (i = 0; i < f->argv->size; i++) {
- scf_variable_t* v = f->argv->data[i];
- scf_type_t* t_v = scf_block_find_type_type((scf_block_t*)t, v->type);
-
- ret = scf_string_cat_cstr(s, "_");
- if (ret < 0)
- goto error;
-
- const char* abbrev = scf_type_find_abbrev(t_v->name->data);
- if (abbrev)
- ret = scf_string_cat_cstr(s, abbrev);
- else
- ret = scf_string_cat(s, t_v->name);
- if (ret < 0)
- goto error;
-
- if (v->nb_pointers > 0) {
- char buf[64];
- snprintf(buf, sizeof(buf) - 1, "%d", v->nb_pointers);
-
- ret = scf_string_cat_cstr(s, buf);
- if (ret < 0)
- goto error;
- }
- }
- }
-
- scf_logd("f signature: %s\n", s->data);
-
- if (f->signature)
- scf_string_free(f->signature);
- f->signature = s;
- return 0;
-
-error:
- scf_string_free(s);
- return -1;
-}
int scf_function_same_argv(scf_vector_t* argv0, scf_vector_t* argv1);
int scf_function_like_argv(scf_vector_t* argv0, scf_vector_t* argv1);
-int scf_function_signature(scf_function_t* f);
-
#endif
}
}
-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_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs)
{
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_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+ scf_x64_OpCode_t* movsd = x64_find_OpCode(SCF_X64_MOVSD, 8,8, SCF_X64_G2E);
+ scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_G2E);
+ scf_x64_OpCode_t* sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E);
+ scf_register_t* rsp = x64_find_register("rsp");
scf_register_t* r;
scf_register_t* r2;
+ uint32_t imm = 8;
int i;
int j;
int k;
int n = 0;
for (j = 0; j < nb_regs; j++) {
- r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
+ r2 = x64_find_register(regs[j]);
for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
r = &(x64_registers[i]);
if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
continue;
- if (stack_size > 0)
- inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
- else
- inst = x64_make_inst_G(push, r2);
+ if (X64_COLOR_TYPE(r2->color)) {
+ if (stack_size > 0)
+ inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
+ else {
+ inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+
+ inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
+ }
+ } else {
+ 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(c->instructions, inst);
saved_regs[n++] = r2;
if (size & 0xf) {
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);
+ if (X64_COLOR_TYPE(r2->color)) {
+ if (stack_size > 0)
+ inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
+ else {
+ inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
+ X64_INST_ADD_CHECK(c->instructions, inst);
+
+ inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
+ }
+ } else {
+ 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(c->instructions, inst);
saved_regs[n++] = r2;
return size;
}
-int x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs)
-{
- int i;
- int j;
- scf_register_t* r;
- scf_register_t* r2;
- scf_instruction_t* inst;
- scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
-
- for (j = 0; j < nb_regs; j++) {
- r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
-
- for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
- r = &(x64_registers[i]);
-
- if (!X64_COLOR_TYPE(r->color) && (SCF_X64_REG_RSP == r->id || SCF_X64_REG_RBP == r->id))
- continue;
-
- if (0 == r->dag_nodes->size)
- continue;
-
- if (X64_COLOR_CONFLICT(r2->color, r->color))
- break;
- }
-
- if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
- continue;
-
- inst = x64_make_inst_G(push, r2);
- X64_INST_ADD_CHECK(instructions, inst);
- }
- 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 i;
- int j;
-
- 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_register_t* r;
+ scf_register_t* r2;
scf_instruction_t* inst;
- scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G);
- scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E);
+ scf_x64_OpCode_t* movsd = x64_find_OpCode(SCF_X64_MOVSD, 8, 8, SCF_X64_E2G);
+ scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G);
+ scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E);
uint32_t imm = 8;
+ int i;
+ int j;
for (j = nb_regs - 1; j >= 0; j--) {
r2 = regs[j];
}
if (i == nb_updated) {
- inst = x64_make_inst_G(pop, r2);
+ if (X64_COLOR_TYPE(r2->color)) {
+ inst = x64_make_inst_P2G(movsd, r2, rsp, 0);
+ X64_INST_ADD_CHECK(instructions, inst);
+
+ inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
+ } else
+ inst = x64_make_inst_G(pop, r2);
X64_INST_ADD_CHECK(instructions, inst);
} else {
inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn)
{
scf_register_t* r2;
- scf_dag_node_t* dn2;
+ scf_dag_node_t* dn2;
int i;
int j;
continue;
for (j = 0; j < r2->dag_nodes->size; j++) {
- dn2 = r2->dag_nodes->data[j];
+ dn2 = r2->dag_nodes->data[j];
if (dn2 != dn)
return 1;
int i;
int j;
+ scf_logd("bytes: %d\n", bytes);
+
assert(c->rcg);
ret = x64_rcg_find_node(&gn, c->rcg, dn, NULL);
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);
+ r = x64_find_register(x64_abi_callee_saves[i]);
for (j = 0; j < N; j++) {
r2 = &(x64_registers[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);
+ r = x64_find_register(x64_abi_callee_saves[i]);
for (j = 0; j < N; j++) {
r2 = &(x64_registers[j]);
};
#define X64_ABI_RET_NB (sizeof(x64_abi_ret_regs) / sizeof(x64_abi_ret_regs[0]))
-static uint32_t x64_abi_caller_saves[] =
+static const char* x64_abi_caller_saves[] =
{
- SCF_X64_REG_RAX,
- SCF_X64_REG_RCX,
- SCF_X64_REG_RDX,
- SCF_X64_REG_RSI,
- SCF_X64_REG_RDI,
- SCF_X64_REG_R8,
- SCF_X64_REG_R9,
- SCF_X64_REG_R10,
- SCF_X64_REG_R11,
+ "rax",
+ "rcx",
+ "rdx",
+ "rsi",
+ "rdi",
+ "r8",
+ "r9",
+ "r10",
+ "r11",
+
+ "xmm0",
+ "xmm1",
+ "xmm2",
+ "xmm3",
+ "xmm4",
+ "xmm5",
+ "xmm6",
+ "xmm7",
};
#define X64_ABI_CALLER_SAVES_NB (sizeof(x64_abi_caller_saves) / sizeof(x64_abi_caller_saves[0]))
-static uint32_t x64_abi_callee_saves[] =
+static const char* x64_abi_callee_saves[] =
{
- SCF_X64_REG_RBX,
- SCF_X64_REG_R12,
- SCF_X64_REG_R13,
- SCF_X64_REG_R14,
- SCF_X64_REG_R15,
+ "rbx",
+ "r12",
+ "r13",
+ "r14",
+ "r15",
};
#define X64_ABI_CALLEE_SAVES_NB (sizeof(x64_abi_callee_saves) / sizeof(x64_abi_callee_saves[0]))
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_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
+int x64_caller_save_regs(scf_3ac_code_t* c, const char* 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);
return SCF_DFA_ERROR;
}
- if (scf_function_signature(f) < 0)
+ if (scf_function_signature(parse->ast, f) < 0)
return SCF_DFA_ERROR;
w->text->data[2] = '\0';
for (j = 0; j < f->text_relas->size; j++) {
r = f->text_relas->data[j];
- if (scf_function_signature(r->func) < 0) {
+ if (scf_function_signature(parse->ast, r->func) < 0) {
scf_loge("\n");
goto error;
}
return ret;
}
- if (scf_function_signature(f) < 0)
+ if (scf_function_signature(parse->ast, f) < 0)
return -ENOMEM;
int ret = _fill_function_inst(code, f, offset, parse);