feat(ir2mcode): 添加IR到机器码转换功能并修复函数命名
添加了完整的scc_ir2mcode实现,将MIR指令转换为机器码, 同时修复了头文件中的函数命名错误(scc_mir2sccf改为scc_ir2sccf)。 BREAKING CHANGE: 函数名从scc_mir2sccf更改为scc_ir2sccf fix(vec): 修复向量循环和内存释放问题 修改了scc_vec_foreach宏使用+= 1避免潜在的编译器警告, 并添加了空指针检查以防止重复释放内存导致的崩溃。 refactor(hashtable): 优化哈希表接口设计 将scc_hashtable_get参数改为const类型,提供更好的只读访问安全性。 test: 添加break/continue和goto语句测试用例 新增18_break_continue.c和19_goto.c测试用例, 并对齐expect.toml文件格式以便于维护。
This commit is contained in:
@@ -4,6 +4,6 @@
|
|||||||
#include <scc_mir_module.h>
|
#include <scc_mir_module.h>
|
||||||
#include <sccf_builder.h>
|
#include <sccf_builder.h>
|
||||||
|
|
||||||
void scc_mir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module);
|
void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module);
|
||||||
|
|
||||||
#endif /* __SCC_IR2SCCF_H__ */
|
#endif /* __SCC_IR2SCCF_H__ */
|
||||||
|
|||||||
38
libs/ir2mcode/src/scc_ir2mcode.c
Normal file
38
libs/ir2mcode/src/scc_ir2mcode.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include <scc_ir2mcode.h>
|
||||||
|
#include <scc_mcode.h>
|
||||||
|
#include <scc_mir_module.h>
|
||||||
|
|
||||||
|
#include <x86/scc_x86_encode.h>
|
||||||
|
#include <x86/scc_x86_iform.h>
|
||||||
|
#include <x86/scc_x86_reg.h>
|
||||||
|
|
||||||
|
void mir_x86_to_mcode(scc_mcode_t *mcode, const scc_mir_instr_t *ins) {
|
||||||
|
// scc_x86_operand_value_t ops[8] = {0};
|
||||||
|
// for (int i = 0; i < ins->num_operands; i += 1) {
|
||||||
|
// }
|
||||||
|
scc_x86_encode_inst(mcode, ins->opcode, (void *)&ins->operands);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scc_emit_mcode(scc_mcode_t *mcode,
|
||||||
|
const scc_mir_instr_t *mir_instr) {
|
||||||
|
// TODO
|
||||||
|
mir_x86_to_mcode(mcode, mir_instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc_ir2mcode(scc_mcode_t *mcode, const scc_mir_module_t *mir_module) {
|
||||||
|
scc_vec_foreach(mir_module->cfg_module.funcs, i) {
|
||||||
|
if (i == 0)
|
||||||
|
continue;
|
||||||
|
scc_mir_func_t *func = &scc_vec_at(mir_module->cfg_module.funcs, i);
|
||||||
|
scc_vec_foreach(func->bblocks, i) {
|
||||||
|
scc_cfg_bblock_id_t id = scc_vec_at(func->bblocks, i);
|
||||||
|
const scc_cfg_bblock_t *bb =
|
||||||
|
scc_cfg_module_unsafe_get_bblock(&mir_module->cfg_module, id);
|
||||||
|
scc_mir_instr_vec_t *instrs = SCC_MIR_BBLOCK_VALUES(bb);
|
||||||
|
scc_vec_foreach(*instrs, i) {
|
||||||
|
const scc_mir_instr_t *ins = &scc_vec_at(*instrs, i);
|
||||||
|
scc_emit_mcode(mcode, ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ static inline void scc_ir_symbol_to_sect_data(const scc_cfg_symbol_t *symbol,
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void scc_mir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) {
|
void scc_ir2sccf(sccf_builder_t *builder, scc_mir_module_t *mir_module) {
|
||||||
// mir_module->symbol_metas
|
// mir_module->symbol_metas
|
||||||
// mir_module->cfg_module.funcs
|
// mir_module->cfg_module.funcs
|
||||||
sccf_builder_init(builder);
|
sccf_builder_init(builder);
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ typedef size_t usize;
|
|||||||
#define scc_vec_size(vec) ((vec).size)
|
#define scc_vec_size(vec) ((vec).size)
|
||||||
#define scc_vec_cap(vec) ((vec).cap)
|
#define scc_vec_cap(vec) ((vec).cap)
|
||||||
#define scc_vec_foreach(vec, idx) \
|
#define scc_vec_foreach(vec, idx) \
|
||||||
for (usize idx = 0; idx < scc_vec_size(vec); ++idx)
|
for (usize idx = 0; idx < scc_vec_size(vec); idx += 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def scc_vec_push(vec, value)
|
* @def scc_vec_push(vec, value)
|
||||||
@@ -146,6 +146,8 @@ typedef size_t usize;
|
|||||||
*/
|
*/
|
||||||
#define scc_vec_free(vec) \
|
#define scc_vec_free(vec) \
|
||||||
do { \
|
do { \
|
||||||
|
if ((vec).data == nullptr) \
|
||||||
|
break; \
|
||||||
__scc_vec_free((vec).data); \
|
__scc_vec_free((vec).data); \
|
||||||
(vec).data = nullptr; \
|
(vec).data = nullptr; \
|
||||||
(vec).size = (vec).cap = 0; \
|
(vec).size = (vec).cap = 0; \
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value);
|
|||||||
* @param key 查找键指针
|
* @param key 查找键指针
|
||||||
* @return 找到返回值指针,未找到返回nullptr
|
* @return 找到返回值指针,未找到返回nullptr
|
||||||
*/
|
*/
|
||||||
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key);
|
void *scc_hashtable_get(const scc_hashtable_t *ht, const void *key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 删除键值对
|
* @brief 删除键值对
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ void *scc_hashtable_set(scc_hashtable_t *ht, const void *key, void *value) {
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *scc_hashtable_get(scc_hashtable_t *ht, const void *key) {
|
void *scc_hashtable_get(const scc_hashtable_t *ht, const void *key) {
|
||||||
if (ht->entries.cap == 0)
|
if (ht->entries.cap == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,24 @@
|
|||||||
# windows powershell: echo $LASTEXITCODE
|
# windows powershell: echo $LASTEXITCODE
|
||||||
# nushell: echo $env.LAST_EXIT_CODE
|
# nushell: echo $env.LAST_EXIT_CODE
|
||||||
# bash: echo $?
|
# bash: echo $?
|
||||||
"./return_val_cases/01_return.c" = 65536
|
"./return_val_cases/01_return.c" = 65536
|
||||||
"./return_val_cases/02_decl_expr.c" = 1
|
"./return_val_cases/02_decl_expr.c" = 1
|
||||||
"./return_val_cases/03_decl_init.c" = 11
|
"./return_val_cases/03_decl_init.c" = 11
|
||||||
"./return_val_cases/04_if.c" = 1
|
"./return_val_cases/04_if.c" = 1
|
||||||
"./return_val_cases/05_else.c" = 2
|
"./return_val_cases/05_else.c" = 2
|
||||||
"./return_val_cases/06_fcall.c" = 3
|
"./return_val_cases/06_fcall.c" = 3
|
||||||
"./return_val_cases/07_while.c" = 10
|
"./return_val_cases/07_while.c" = 10
|
||||||
"./return_val_cases/08_do_while.c" = 128
|
"./return_val_cases/08_do_while.c" = 128
|
||||||
"./return_val_cases/09_for.c" = 10
|
"./return_val_cases/09_for.c" = 10
|
||||||
"./return_val_cases/10_main.c" = 3
|
"./return_val_cases/10_main.c" = 3
|
||||||
"./return_val_cases/11_recursive.c" = 120
|
"./return_val_cases/11_recursive.c" = 120
|
||||||
"./return_val_cases/12_logic.c" = 10
|
"./return_val_cases/12_logic.c" = 10
|
||||||
"./return_val_cases/13_array.c" = 1198
|
"./return_val_cases/13_array.c" = 1198
|
||||||
"./return_val_cases/14_pointer.c" = 2
|
"./return_val_cases/14_pointer.c" = 2
|
||||||
"./return_val_cases/15_array_subscript.c" = 1198
|
"./return_val_cases/15_array_subscript.c" = 1198
|
||||||
"./return_val_cases/16_enum.c" = 5
|
"./return_val_cases/16_enum.c" = 5
|
||||||
"./return_val_cases/17_more_arg.c" = 45
|
"./return_val_cases/17_more_arg.c" = 45
|
||||||
|
"./return_val_cases/18_break_continue.c" = 676
|
||||||
|
"./return_val_cases/19_goto.c" = 676
|
||||||
[stdout_val_cases]
|
[stdout_val_cases]
|
||||||
"./stdout_val_cases/01_include.c" = "Hello World!\n"
|
"./stdout_val_cases/01_include.c" = "Hello World!\n"
|
||||||
|
|||||||
13
tests/simple/return_val_cases/18_break_continue.c
Normal file
13
tests/simple/return_val_cases/18_break_continue.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char buff[] = "hello buffer";
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; buff[i] != 0; i += 1) {
|
||||||
|
if (i < 2)
|
||||||
|
continue;
|
||||||
|
if (i > 8)
|
||||||
|
break;
|
||||||
|
res += buff[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
14
tests/simple/return_val_cases/19_goto.c
Normal file
14
tests/simple/return_val_cases/19_goto.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
int main(void) {
|
||||||
|
char buff[] = "hello buffer";
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; buff[i] != 0; i += 1) {
|
||||||
|
if (i < 2)
|
||||||
|
goto the_continue;
|
||||||
|
if (i > 8)
|
||||||
|
goto the_break;
|
||||||
|
res += buff[i];
|
||||||
|
the_continue:;
|
||||||
|
}
|
||||||
|
the_break:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user