fix: x64 xmm registers, update function signature
authoryu.dongliang <18588496441@163.com>
Tue, 19 Aug 2025 08:10:38 +0000 (16:10 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 19 Aug 2025 08:10:38 +0000 (16:10 +0800)
core/scf_ast.c
core/scf_ast.h
core/scf_function.c
core/scf_function.h
native/x64/scf_x64_reg.c
native/x64/scf_x64_reg.h
parse/scf_dfa_expr.c
parse/scf_parse.c

index a85bc7f272efbcecfaff6bc4c863837c96b5b487..e3fd536811067bc618cb717e3a624320dec3c8ca 100644 (file)
@@ -410,3 +410,170 @@ int scf_ast_find_type_type(scf_type_t** pt, scf_ast_t* ast, int type)
        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;
+}
index 404c778b6b5a2ecb8edeecabe091639e1a54e71d..dbd9169bb77ea0ed2fd1dc941c39d7b7d1275472 100644 (file)
@@ -101,5 +101,9 @@ int scf_ast_add_base_type(scf_ast_t* ast, scf_base_type_t* base_type);
 
 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
index 1b537a45a15a1df6a000766420fb14dff6f64148..4fe5befe569a735b3fa13d8d9407617ca1cf2257 100644 (file)
@@ -215,89 +215,3 @@ int scf_function_same_type(scf_function_t* f0, scf_function_t* f1)
 
        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;
-}
index 9765f2a410285fa13bcbdbc5145222bc3a8d47c8..4ca3b64f9aeff876f28264ad03cb12f04c69f264 100644 (file)
@@ -74,6 +74,4 @@ int             scf_function_same_type(scf_function_t* f0, scf_function_t* f1);
 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
index 331d25d99b885677cff09110932616930a7a61a8..765e4ed464cbfbe42934eae44c83bf2941c91dde 100644 (file)
@@ -207,18 +207,21 @@ void x64_registers_print()
        }
 }
 
-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;
@@ -226,7 +229,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        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]);
@@ -263,10 +266,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
                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;
@@ -276,10 +290,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        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;
@@ -297,53 +322,19 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        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];
@@ -373,7 +364,13 @@ int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs,
                }
 
                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);
@@ -679,7 +676,7 @@ int x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c,
 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;
@@ -695,7 +692,7 @@ int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn)
                        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;
@@ -745,6 +742,8 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
        int i;
        int j;
 
+       scf_logd("bytes: %d\n", bytes);
+
        assert(c->rcg);
 
        ret = x64_rcg_find_node(&gn, c->rcg, dn, NULL);
@@ -1358,9 +1357,7 @@ int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
        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]);
@@ -1397,9 +1394,7 @@ int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
        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]);
index 790ce54961d727bb4a82b9d6dda9af948f00ebee..40c5967771b5a90a2e3178d900559814df91a874 100644 (file)
@@ -65,27 +65,36 @@ static uint32_t x64_abi_ret_regs[] =
 };
 #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]))
 
@@ -138,7 +147,7 @@ int                 x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac
 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);
index 39575f0172c906a91ecd6bf327ce1b09b31f2af9..e8e431e510e9f51470a99ca0b94b239bdda10bc9 100644 (file)
@@ -197,7 +197,7 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                        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';
index 966557a7b92d0e5e6510f4f9f63a344dcbce6f59..040a42e8057f99a65a47d09c346829608d1de188 100644 (file)
@@ -1937,7 +1937,7 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf,
                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;
                        }
@@ -2234,7 +2234,7 @@ int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_ve
                                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);