diff --git a/cbuild.toml b/cbuild.toml index 8a8e5dc..3267a41 100644 --- a/cbuild.toml +++ b/cbuild.toml @@ -10,7 +10,7 @@ dependencies = [ { name = "ast", path = "./libs/ast" }, { name = "ast2ir", path = "./libs/ast2ir" }, { name = "hir", path = "./libs/ir/hir" }, - # { name = "lir", path = "./libs/ir/lir" }, + { name = "lir", path = "./libs/ir/lir" }, # { name = "ir2mcode", path = "./libs/ir2mcode" }, # { name = "sccf2target", path = "./libs/target/sccf2target" }, diff --git a/libs/ast/include/scc_ast.h b/libs/ast/include/scc_ast.h index ddba964..bd41afd 100644 --- a/libs/ast/include/scc_ast.h +++ b/libs/ast/include/scc_ast.h @@ -1,8 +1,7 @@ #ifndef __SCC_AST_H__ #define __SCC_AST_H__ -#include "ast_def.h" -#include "ast_dump.h" +#include "scc_ast_def.h" // decls can be nullptr but maybe warning static inline void diff --git a/libs/ast/include/ast_def.h b/libs/ast/include/scc_ast_def.h similarity index 100% rename from libs/ast/include/ast_def.h rename to libs/ast/include/scc_ast_def.h diff --git a/libs/ast/include/ast_dump.h b/libs/ast/include/scc_ast_dump.h similarity index 94% rename from libs/ast/include/ast_dump.h rename to libs/ast/include/scc_ast_dump.h index a72a56b..90fb228 100644 --- a/libs/ast/include/ast_dump.h +++ b/libs/ast/include/scc_ast_dump.h @@ -6,7 +6,7 @@ #ifndef __SCC_AST_DUMP_H__ #define __SCC_AST_DUMP_H__ -#include "ast_def.h" +#include "scc_ast_def.h" #include /** diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index d0fb64a..1afdbad 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -3,7 +3,7 @@ * @brief AST dump 实现 */ -#include +#include #include static const char *node_type_names[] = { diff --git a/libs/ast2ir/include/scc_ast2ir.h b/libs/ast2ir/include/scc_ast2ir.h index 051c9c8..2a65d3f 100644 --- a/libs/ast2ir/include/scc_ast2ir.h +++ b/libs/ast2ir/include/scc_ast2ir.h @@ -1,8 +1,8 @@ #ifndef __SCC_AST2IR_H__ #define __SCC_AST2IR_H__ -#include #include +#include #include typedef struct { diff --git a/libs/ast2ir/src/scc_ast2ir.c b/libs/ast2ir/src/scc_ast2ir.c index 75ce536..c93d655 100644 --- a/libs/ast2ir/src/scc_ast2ir.c +++ b/libs/ast2ir/src/scc_ast2ir.c @@ -1,7 +1,7 @@ -#include -#include -#include #include +#include +#include +#include static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx, const scc_ast_type_t *ast_type) { diff --git a/libs/ir/cfg/include/scc_cfg.h b/libs/ir/cfg/include/scc_cfg.h index 505d005..524a7cc 100644 --- a/libs/ir/cfg/include/scc_cfg.h +++ b/libs/ir/cfg/include/scc_cfg.h @@ -8,6 +8,7 @@ typedef usize scc_cfg_id_t; typedef scc_cfg_id_t scc_cfg_bblock_id_t; typedef scc_cfg_id_t scc_cfg_func_id_t; +typedef scc_cfg_id_t scc_cfg_symbol_id_t; typedef SCC_VEC(scc_cfg_bblock_id_t) scc_cfg_bblock_id_vec_t; typedef SCC_VEC(void *) scc_cfg_value_vec_t; @@ -22,7 +23,7 @@ struct scc_cfg_bblock { scc_cfg_bblock_id_vec_t preds; // 前驱 scc_cfg_bblock_id_vec_t succs; // 后继 scc_cfg_value_vec_t values; // using cast - void *attribute; + void *meta; }; struct scc_cfg_func { @@ -33,7 +34,7 @@ struct scc_cfg_func { scc_hashtable_t bblock_map; // id -> index scc_cfg_bblock_id_t entry_bblock_id; // maybe it will always 0 - void *attribute; + void *meta; }; typedef enum { @@ -42,10 +43,16 @@ typedef enum { SCC_CFG_SYMBOL_KIND_EXTERN, } scc_cfg_symbol_kind_t; +typedef enum { + SCC_CFG_SYMBOL_LINK_GLOABL, + SCC_CFG_SYMBOL_LINK_LOCAL, +} scc_cfg_symbol_linkage_t; + struct scc_cfg_symbol { const char *name; scc_cfg_symbol_kind_t kind; - void *attribute; + scc_cfg_symbol_linkage_t linkage; + void *meta; }; typedef SCC_VEC(scc_cfg_bblock_t) scc_cfg_bblock_vec_t; @@ -74,10 +81,12 @@ scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, const scc_cfg_bblock_t *bblock); scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, scc_cfg_bblock_id_t id); -void scc_cfg_module_add_symbol(scc_cfg_module_t *module, - const scc_cfg_symbol_t *symbol); -scc_cfg_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, - const char *name); +scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module, + const scc_cfg_symbol_t *symbol); +scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, + scc_cfg_symbol_id_t id); +scc_cfg_symbol_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, + const char *name); static inline const scc_cfg_symbol_t * scc_cfg_module_unsafe_lookup_symbol(const scc_cfg_module_t *module, diff --git a/libs/ir/cfg/src/scc_cfg.c b/libs/ir/cfg/src/scc_cfg.c index 8c43a9d..077f260 100644 --- a/libs/ir/cfg/src/scc_cfg.c +++ b/libs/ir/cfg/src/scc_cfg.c @@ -40,8 +40,10 @@ scc_cfg_func_t *scc_cfg_module_unsafe_get_func(scc_cfg_module_t *module, scc_cfg_bblock_id_t scc_cfg_module_add_bblock(scc_cfg_module_t *module, const scc_cfg_bblock_t *bblock) { - scc_cfg_func_id_t id = scc_vec_size(module->bblocks); - scc_vec_push(module->bblocks, *bblock); + scc_cfg_bblock_id_t id = scc_vec_size(module->bblocks); + scc_cfg_bblock_t bblock_ = *bblock; + bblock_.id = id; + scc_vec_push(module->bblocks, bblock_); Assert(id != SCC_CFG_ID_nullptr); return id; } @@ -57,11 +59,30 @@ scc_cfg_bblock_t *scc_cfg_module_unsafe_get_bblock(scc_cfg_module_t *module, return &scc_vec_at(module->bblocks, id); } -void scc_cfg_module_add_symbol(scc_cfg_module_t *module, - const scc_cfg_symbol_t *symbol) {} -scc_cfg_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, - const char *name) { - return 0; +scc_cfg_symbol_id_t scc_cfg_module_add_symbol(scc_cfg_module_t *module, + const scc_cfg_symbol_t *symbol) { + scc_cfg_func_id_t id = scc_vec_size(module->symbols); + scc_vec_push(module->symbols, *symbol); + Assert(id != SCC_CFG_ID_nullptr); + scc_hashtable_set(&module->symbol_map, symbol->name, (void *)(usize)id); + return id; +} + +scc_cfg_symbol_t *scc_cfg_module_unsafe_get_symbol(scc_cfg_module_t *module, + scc_cfg_symbol_id_t id) { + if (id == SCC_CFG_ID_nullptr) { + Panic("nullptr symbol id"); + } + if (id >= scc_vec_size(module->bblocks)) { + Panic("invalid symbol id"); + } + return &scc_vec_at(module->symbols, id); +} + +scc_cfg_symbol_id_t scc_cfg_module_lookup_symbol(const scc_cfg_module_t *module, + const char *name) { + return (scc_cfg_symbol_id_t)(usize)scc_hashtable_get(&module->symbol_map, + name); } void scc_cfg_bblock_add_pred(scc_cfg_bblock_t *bb, diff --git a/libs/ir/hir/include/scc_hir.h b/libs/ir/hir/include/scc_hir.h index 361d824..188d060 100644 --- a/libs/ir/hir/include/scc_hir.h +++ b/libs/ir/hir/include/scc_hir.h @@ -1,8 +1,8 @@ #ifndef __SCC_HIR_H__ #define __SCC_HIR_H__ -#include "hir_def.h" -#include "hir_prog.h" +#include "scc_hir_def.h" +#include "scc_hir_prog.h" void scc_hir_type_init(scc_hir_type_t *in, scc_hir_type_tag_t tag); void scc_hir_bblock_init(scc_hir_bblock_t *in, const char *label); diff --git a/libs/ir/hir/include/hir_builder.h b/libs/ir/hir/include/scc_hir_builder.h similarity index 99% rename from libs/ir/hir/include/hir_builder.h rename to libs/ir/hir/include/scc_hir_builder.h index 6bb6e80..076f14c 100644 --- a/libs/ir/hir/include/hir_builder.h +++ b/libs/ir/hir/include/scc_hir_builder.h @@ -1,8 +1,8 @@ #ifndef __SCC_HIR_BUILDER_H__ #define __SCC_HIR_BUILDER_H__ -#include "hir_prog.h" #include "scc_hir.h" +#include "scc_hir_prog.h" typedef struct scc_hir_builder scc_hir_builder_t; diff --git a/libs/ir/hir/include/hir_def.h b/libs/ir/hir/include/scc_hir_def.h similarity index 96% rename from libs/ir/hir/include/hir_def.h rename to libs/ir/hir/include/scc_hir_def.h index 3d419ed..4613a4e 100644 --- a/libs/ir/hir/include/hir_def.h +++ b/libs/ir/hir/include/scc_hir_def.h @@ -246,10 +246,9 @@ typedef struct scc_hir_func_meta { } scc_hir_func_meta_t; #define SCC_HIR_BBLOCK_VALUES(bblock) \ - (*(scc_hir_value_ref_vec_t *)&((bblock).values)) + ((scc_hir_value_ref_vec_t *)&((bblock)->values)) -#define SCC_HIR_BBLOCK_META(bblock) \ - ((scc_hir_bblock_meta_t *)((bblock).attribute)) -#define SCC_HIR_FUNC_META(func) ((scc_hir_func_meta_t *)((func).attribute)) +#define SCC_HIR_BBLOCK_META(bblock) ((scc_hir_bblock_meta_t *)((bblock)->meta)) +#define SCC_HIR_FUNC_META(func) ((scc_hir_func_meta_t *)((func)->meta)) #endif /* __SCC_HIR_DEF_H__ */ diff --git a/libs/ir/hir/include/hir_dump.h b/libs/ir/hir/include/scc_hir_dump.h similarity index 80% rename from libs/ir/hir/include/hir_dump.h rename to libs/ir/hir/include/scc_hir_dump.h index 187f24c..eb142a8 100644 --- a/libs/ir/hir/include/hir_dump.h +++ b/libs/ir/hir/include/scc_hir_dump.h @@ -1,7 +1,7 @@ #ifndef __SCC_HIR_DUMP_H__ #define __SCC_HIR_DUMP_H__ -#include "hir_prog.h" +#include "scc_hir_prog.h" #include typedef struct { @@ -9,8 +9,8 @@ typedef struct { scc_tree_dump_t *dump_ctx; } scc_hir_dump_t; -void scc_hir_dump_ctx_init(scc_hir_dump_t *ctx, scc_tree_dump_t *tree_dump, - scc_hir_cprog_t *cprog); +void scc_hir_dump_init(scc_hir_dump_t *ctx, scc_tree_dump_t *tree_dump, + scc_hir_cprog_t *cprog); void scc_hir_dump_value(scc_hir_dump_t *ctx, scc_hir_value_ref_t node_ref); void scc_hir_dump_type(scc_hir_dump_t *ctx, scc_hir_type_ref_t type_ref); void scc_hir_dump_bblock(scc_hir_dump_t *ctx, scc_hir_bblock_ref_t bblock_ref); diff --git a/libs/ir/hir/include/hir_module.h b/libs/ir/hir/include/scc_hir_module.h similarity index 98% rename from libs/ir/hir/include/hir_module.h rename to libs/ir/hir/include/scc_hir_module.h index 7353fb7..7ca3cf0 100644 --- a/libs/ir/hir/include/hir_module.h +++ b/libs/ir/hir/include/scc_hir_module.h @@ -1,7 +1,7 @@ #ifndef __SCC_HIR_MODULE_H__ #define __SCC_HIR_MODULE_H__ -#include "hir_def.h" +#include "scc_hir_def.h" #include #include diff --git a/libs/ir/hir/include/hir_prog.h b/libs/ir/hir/include/scc_hir_prog.h similarity index 89% rename from libs/ir/hir/include/hir_prog.h rename to libs/ir/hir/include/scc_hir_prog.h index 9edfebf..95fbeb2 100644 --- a/libs/ir/hir/include/hir_prog.h +++ b/libs/ir/hir/include/scc_hir_prog.h @@ -1,8 +1,8 @@ #ifndef __SCC_HIR_PROG_H__ #define __SCC_HIR_PROG_H__ -#include "hir_def.h" -#include "hir_module.h" +#include "scc_hir_def.h" +#include "scc_hir_module.h" typedef struct scc_hir_cprog { scc_hir_module_t module; diff --git a/libs/ir/hir/src/scc_hir.c b/libs/ir/hir/src/scc_hir.c index 591f925..dae53e5 100644 --- a/libs/ir/hir/src/scc_hir.c +++ b/libs/ir/hir/src/scc_hir.c @@ -54,7 +54,7 @@ void scc_hir_func_init(scc_hir_func_t *in, const char *name) { Assert(in != nullptr); Assert(name != nullptr); in->name = name; - scc_hir_func_meta_t *meta = SCC_HIR_FUNC_META(*in); + scc_hir_func_meta_t *meta = SCC_HIR_FUNC_META(in); meta->type = SCC_HIR_REF_nullptr; scc_vec_init(in->bblocks); scc_vec_init(meta->params); diff --git a/libs/ir/hir/src/hir_builder.c b/libs/ir/hir/src/scc_hir_builder.c similarity index 98% rename from libs/ir/hir/src/hir_builder.c rename to libs/ir/hir/src/scc_hir_builder.c index eba1ef1..ed58dec 100644 --- a/libs/ir/hir/src/hir_builder.c +++ b/libs/ir/hir/src/scc_hir_builder.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #define GET_MODULE(builder) (&(builder->cprog->module)) @@ -175,7 +175,7 @@ scc_hir_func_ref_t scc_hir_builder_func(scc_hir_builder_t *builder, scc_hir_func_t func; scc_hir_func_meta_t *meta = scc_malloc(sizeof(scc_hir_func_meta_t)); Assert(meta != nullptr); - func.attribute = meta; + func.meta = meta; scc_hir_func_init(&func, name); meta->type = type_ref; @@ -197,8 +197,8 @@ scc_hir_bblock_ref_t scc_hir_builder_bblock(scc_hir_builder_t *builder, } // scc_hir_bblock_meta_t bblock_meta = {0}; // FIXME 当前没有bblock meta - bblock.attribute = nullptr; - scc_vec_init(SCC_HIR_BBLOCK_VALUES(bblock)); + bblock.meta = nullptr; + scc_vec_init(*SCC_HIR_BBLOCK_VALUES(&bblock)); scc_hir_bblock_ref_t bblock_ref = scc_hir_module_add_bblock(GET_MODULE(builder), &bblock); @@ -298,7 +298,7 @@ void scc_hir_builder_begin_func(scc_hir_builder_t *builder, SCC_HIR_BUILDER_BEGIN_BORROW( builder, func_type, scc_hir_module_get_type(GET_MODULE(builder), - SCC_HIR_FUNC_META(*func_ptr)->type)); + SCC_HIR_FUNC_META(func_ptr)->type)); if (func_type == nullptr || func_type->tag != SCC_HIR_TYPE_FUNC) { LOG_ERROR("Invalid function type"); @@ -313,7 +313,7 @@ void scc_hir_builder_begin_func(scc_hir_builder_t *builder, return; } if (scc_vec_size(func_ptr->bblocks) != 0 || - scc_vec_size(SCC_HIR_FUNC_META(*func_ptr)->params) != 0) { + scc_vec_size(SCC_HIR_FUNC_META(func_ptr)->params) != 0) { LOG_FATAL("Multiple function definitions"); SCC_HIR_BUILDER_END_BORROW(builder); // func_type SCC_HIR_BUILDER_END_BORROW(builder); // func_ptr @@ -381,7 +381,7 @@ void scc_hir_builder_add_instr(scc_hir_builder_t *builder, scc_hir_module_get_bblock(GET_MODULE(builder), builder->current_bblock)); if (current_bblock) { - scc_vec_push(SCC_HIR_BBLOCK_VALUES(*current_bblock), instr); + scc_vec_push(*SCC_HIR_BBLOCK_VALUES(current_bblock), instr); } else { LOG_ERROR("Current basic block is not set"); } @@ -628,7 +628,7 @@ scc_hir_value_ref_t scc_hir_builder_call(scc_hir_builder_t *builder, SCC_HIR_BUILDER_BEGIN_BORROW( builder, func_type, scc_hir_module_get_type(GET_MODULE(builder), - SCC_HIR_FUNC_META(*callee_func)->type)); + SCC_HIR_FUNC_META(callee_func)->type)); if (func_type && func_type->tag == SCC_HIR_TYPE_FUNC) { call_node.type = func_type->data.function.ret_type; } diff --git a/libs/ir/hir/src/hir_dump.c b/libs/ir/hir/src/scc_hir_dump.c similarity index 95% rename from libs/ir/hir/src/hir_dump.c rename to libs/ir/hir/src/scc_hir_dump.c index 18c7cf5..fdda5f4 100644 --- a/libs/ir/hir/src/hir_dump.c +++ b/libs/ir/hir/src/scc_hir_dump.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #define GET_MODULE(ctx) (&(ctx->cprog->module)) @@ -192,10 +192,10 @@ static void dump_ret_node(scc_hir_dump_t *ctx, const scc_hir_value_t *value) { dump_child_node_ref(ctx, value->data.ret.ret_val, true); } -void scc_hir_dump_ctx_init(scc_hir_dump_t *ctx, scc_tree_dump_t *td, - scc_hir_cprog_t *cprog) { - ctx->cprog = cprog; +void scc_hir_dump_init(scc_hir_dump_t *ctx, scc_tree_dump_t *td, + scc_hir_cprog_t *cprog) { ctx->dump_ctx = td; + ctx->cprog = cprog; } void scc_hir_dump_value(scc_hir_dump_t *ctx, scc_hir_value_ref_t value_ref) { @@ -327,10 +327,11 @@ void scc_hir_dump_bblock(scc_hir_dump_t *ctx, scc_hir_bblock_ref_t bblock_ref) { bblock->name ? bblock->name : ""); scc_tree_dump_append(ctx->dump_ctx, "\n"); - for (usize i = 0; i < scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock)); i++) { - cbool is_last = (i + 1 == scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock))); + scc_hir_value_ref_vec_t *values = SCC_HIR_BBLOCK_VALUES(bblock); + scc_vec_foreach(*values, i) { + cbool is_last = (i + 1 == scc_vec_size(*values)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_hir_dump_value(ctx, scc_vec_at(SCC_HIR_BBLOCK_VALUES(*bblock), i)); + scc_hir_dump_value(ctx, scc_vec_at(*values, i)); scc_tree_dump_pop(ctx->dump_ctx); } } @@ -347,17 +348,16 @@ void scc_hir_dump_func(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref) { func->name ? func->name : ""); scc_tree_dump_append(ctx->dump_ctx, "\n"); - if (SCC_HIR_FUNC_META(*func)->type) { + if (SCC_HIR_FUNC_META(func)->type) { scc_tree_dump_push(ctx->dump_ctx, false); - scc_hir_dump_type(ctx, SCC_HIR_FUNC_META(*func)->type); + scc_hir_dump_type(ctx, SCC_HIR_FUNC_META(func)->type); scc_tree_dump_pop(ctx->dump_ctx); } - for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(*func)->params); i++) { + for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(func)->params); i++) { cbool is_last = - (i + 1 == scc_vec_size(SCC_HIR_FUNC_META(*func)->params)); + (i + 1 == scc_vec_size(SCC_HIR_FUNC_META(func)->params)); scc_tree_dump_push(ctx->dump_ctx, is_last); - scc_hir_dump_value(ctx, - scc_vec_at(SCC_HIR_FUNC_META(*func)->params, i)); + scc_hir_dump_value(ctx, scc_vec_at(SCC_HIR_FUNC_META(func)->params, i)); scc_tree_dump_pop(ctx->dump_ctx); } for (usize i = 0; i < scc_vec_size(func->bblocks); i++) { @@ -630,11 +630,11 @@ void scc_hir_dump_bblock_linear(scc_hir_dump_t *ctx, else scc_tree_dump_append_fmt(ctx->dump_ctx, "%%L%d :", bblock_ref); - for (usize i = 0; i < scc_vec_size(SCC_HIR_BBLOCK_VALUES(*bblock)); i++) { + scc_hir_value_ref_vec_t *values = SCC_HIR_BBLOCK_VALUES(bblock); + for (usize i = 0; i < scc_vec_size(*values); i++) { scc_tree_dump_begin_line(ctx->dump_ctx); scc_tree_dump_append(ctx->dump_ctx, " "); - scc_hir_dump_value_linear( - ctx, scc_vec_at(SCC_HIR_BBLOCK_VALUES(*bblock), i)); + scc_hir_dump_value_linear(ctx, scc_vec_at(*values, i)); } } @@ -650,14 +650,14 @@ void scc_hir_dump_func_linear(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref, (func->name && func->name[0]) ? func->name : ""); - if (scc_vec_size(SCC_HIR_FUNC_META(*func)->params) > 0) { + if (scc_vec_size(SCC_HIR_FUNC_META(func)->params) > 0) { scc_tree_dump_append(ctx->dump_ctx, "("); - for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(*func)->params); + for (usize i = 0; i < scc_vec_size(SCC_HIR_FUNC_META(func)->params); i++) { if (i > 0) scc_tree_dump_append(ctx->dump_ctx, ", "); scc_hir_value_ref_t param_ref = - scc_vec_at(SCC_HIR_FUNC_META(*func)->params, i); + scc_vec_at(SCC_HIR_FUNC_META(func)->params, i); scc_hir_value_t *param_node = scc_hir_module_get_value(GET_MODULE(ctx), param_ref); scc_tree_dump_append(ctx->dump_ctx, "%"); @@ -673,7 +673,7 @@ void scc_hir_dump_func_linear(scc_hir_dump_t *ctx, scc_hir_func_ref_t func_ref, } scc_tree_dump_append(ctx->dump_ctx, ": "); - scc_hir_dump_type_linear(ctx, SCC_HIR_FUNC_META(*func)->type); + scc_hir_dump_type_linear(ctx, SCC_HIR_FUNC_META(func)->type); if (is_decl) { scc_tree_dump_append(ctx->dump_ctx, ";"); diff --git a/libs/ir/hir/src/hir_module.c b/libs/ir/hir/src/scc_hir_module.c similarity index 98% rename from libs/ir/hir/src/hir_module.c rename to libs/ir/hir/src/scc_hir_module.c index 034296f..32854a2 100644 --- a/libs/ir/hir/src/hir_module.c +++ b/libs/ir/hir/src/scc_hir_module.c @@ -1,4 +1,4 @@ -#include +#include void scc_hir_module_init(scc_hir_module_t *ctx) { scc_cfg_module_init(&ctx->cfg_module); @@ -89,7 +89,7 @@ scc_hir_bblock_ref_t scc_hir_module_add_bblock(scc_hir_module_t *ctx, scc_hir_func_ref_t scc_hir_module_add_func(scc_hir_module_t *ctx, const scc_hir_func_t *func) { scc_hir_func_ref_t ref = scc_cfg_module_add_func(&ctx->cfg_module, func); - scc_vec_push(ctx->funcs_meta, func->attribute); + scc_vec_push(ctx->funcs_meta, func->meta); return ref; } diff --git a/libs/ir/hir/src/hir_prog.c b/libs/ir/hir/src/scc_hir_prog.c similarity index 93% rename from libs/ir/hir/src/hir_prog.c rename to libs/ir/hir/src/scc_hir_prog.c index 8c2d529..3d1273b 100644 --- a/libs/ir/hir/src/hir_prog.c +++ b/libs/ir/hir/src/scc_hir_prog.c @@ -1,4 +1,4 @@ -#include +#include void scc_hir_cprog_init(scc_hir_cprog_t *in) { scc_vec_init(in->func_decls); diff --git a/libs/ir/lir/cbuild.toml b/libs/ir/lir/cbuild.toml new file mode 100644 index 0000000..0a38ac9 --- /dev/null +++ b/libs/ir/lir/cbuild.toml @@ -0,0 +1,14 @@ +[package] +name = "scc_lir" +version = "0.1.0" +authors = [] +description = "" + +dependencies = [ + { name = "scc_cfg", path = "../cfg" }, + { name = "scc_hir", path = "../hir" }, + { name = "scc_utils", path = "../../../runtime/scc_utils" }, + { name = "tree_dump", path = "../../tree_dump" }, +] +# features = {} +# default_features = [] diff --git a/libs/ir/lir/include/scc_hir2lir.h b/libs/ir/lir/include/scc_hir2lir.h new file mode 100644 index 0000000..2c3f6a0 --- /dev/null +++ b/libs/ir/lir/include/scc_hir2lir.h @@ -0,0 +1,10 @@ +#ifndef __SCC_IR2LIR_H__ +#define __SCC_IR2LIR_H__ + +#include "scc_lir.h" +#include "scc_lir_module.h" +#include + +void scc_hir2lir(scc_lir_module_t *module, const scc_hir_cprog_t *cprog); + +#endif /* __SCC_IR2LIR_H__ */ diff --git a/libs/ir/lir/include/scc_lir.h b/libs/ir/lir/include/scc_lir.h new file mode 100644 index 0000000..f3bdc84 --- /dev/null +++ b/libs/ir/lir/include/scc_lir.h @@ -0,0 +1,275 @@ +/** + * @file scc_lir.h + * @brief 低层中间表示 (Low-Level IR) - 实用精简版 + * + * 设计原则: + * - 依赖 scc_core.h 和 scc_utils.h (仅使用哈希表) + * - 保留所有核心功能:复杂地址、并行复制、VA 支持、符号引用 + * - 基本块使用稳定 ID,通过哈希表快速查找 + * - 预留属性位掩码 (attr),未来可扩展 align、packed、weak 等 + * - 无字符串池、无类型缓存,保持简单 + */ + +#ifndef __SCC_LIR_H__ +#define __SCC_LIR_H__ + +#include +#include +#include +#include +#include + +typedef enum scc_lir_attr { + SCC_LIR_ATTR_NONE = 0, + SCC_LIR_ATTR_STATIC = 1 << 0, // 内部链接 + SCC_LIR_ATTR_WEAK = 1 << 1, // 弱符号 + SCC_LIR_ATTR_VIS_HIDDEN = 1 << 2, // 符号可见性 hidden + SCC_LIR_ATTR_NOINLINE = 1 << 3, + SCC_LIR_ATTR_ALWAYSINLINE = 1 << 4, + // 对齐值可编码在 attr 的高位,例如: + // #define SCC_LIR_ATTR_ALIGN(n) (((n) << 8) | SCC_LIR_ATTR_ALIGN_FLAG) +} scc_lir_attr_t; + +typedef enum { + SCC_LIR_INSTR_KIND_NONE, // 无操作数 + SCC_LIR_INSTR_KIND_VREG, // 虚拟寄存器 + SCC_LIR_INSTR_KIND_PREG, // 物理寄存器 (后端定义编号) + SCC_LIR_INSTR_KIND_IMM, // 整数立即数 + SCC_LIR_INSTR_KIND_FIMM, // 浮点立即数 + SCC_LIR_INSTR_KIND_SYMBOL, // 全局符号 (函数名、全局变量、字符串常量) + SCC_LIR_INSTR_KIND_ADDR // 复杂地址表达式 (base + index*scale + offset) +} scc_lir_instr_kind_t; + +/** + * @brief 复杂地址表达式 + * base + index * scale + offset + */ +typedef struct scc_lir_addr { + int base; // 基址寄存器,-1 表示无 + int index; // 索引寄存器,-1 表示无 + int scale; // 比例因子 (1, 2, 4, 8) + i64 offset; // 常量偏移 +} scc_lir_addr_t; + +typedef struct scc_lir_instr { + scc_lir_instr_kind_t kind; + union { + unsigned int reg; // VREG 或 PREG 索引 + scc_ap_t imm; // 整型立即数 + f64 fimm; // 浮点立即数 + const char *symbol; // 符号名 (生命周期由前端管理) + scc_lir_addr_t addr; // 复杂地址 + } data; +} scc_lir_val_t; + +/* 构造宏 */ +#define SCC_LIR_NONE() ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_NONE}) +#define SCC_LIR_VREG(n) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_VREG, .data.reg = (n)}) +#define SCC_LIR_PREG(r) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_PREG, .data.reg = (r)}) +#define SCC_LIR_IMM(v) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_IMM, .data.imm = (v)}) +#define SCC_LIR_FIMM(v) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_FIMM, .data.fimm = (v)}) +#define SCC_LIR_SYMBOL(s) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_SYMBOL, .data.symbol = (s)}) +#define SCC_LIR_ADDR(b, i, s, o) \ + ((scc_lir_val_t){.kind = SCC_LIR_INSTR_KIND_ADDR, \ + .data.addr = {b, i, s, o}}) + +#define SCC_LIR_SIZE_8 1 +#define SCC_LIR_SIZE_16 2 +#define SCC_LIR_SIZE_32 4 +#define SCC_LIR_SIZE_64 8 + +typedef enum { + SCC_LIR_EXT_NONE, + SCC_LIR_EXT_SEXT, + SCC_LIR_EXT_ZEXT, + SCC_LIR_EXT_FLOAT +} scc_lir_ext_t; + +typedef enum { + /* 数据移动 */ + SCC_LIR_MOV, + SCC_LIR_LOAD, + SCC_LIR_LOAD_ADDR, + SCC_LIR_STORE, + SCC_LIR_STORE_ADDR, + SCC_LIR_LEA, + + /* 整数算术 */ + SCC_LIR_ADD, + SCC_LIR_SUB, + SCC_LIR_MUL, + SCC_LIR_DIV_S, + SCC_LIR_DIV_U, + SCC_LIR_REM_S, + SCC_LIR_REM_U, + SCC_LIR_AND, + SCC_LIR_OR, + SCC_LIR_XOR, + SCC_LIR_SHL, + SCC_LIR_SHR, + SCC_LIR_SAR, + SCC_LIR_NEG, + SCC_LIR_NOT, + + /* 浮点算术 */ + SCC_LIR_FADD, + SCC_LIR_FSUB, + SCC_LIR_FMUL, + SCC_LIR_FDIV, + SCC_LIR_FNEG, + SCC_LIR_FCVT, + + /* 比较 */ + SCC_LIR_CMP, + + /* 控制流 */ + SCC_LIR_BR, + SCC_LIR_JMP, + SCC_LIR_JMP_INDIRECT, + SCC_LIR_CALL, + SCC_LIR_CALL_INDIRECT, + SCC_LIR_RET, + + /* 并行复制 */ + SCC_LIR_PARALLEL_COPY, + + /* 可变参数 */ + SCC_LIR_VA_START, + SCC_LIR_VA_ARG, + SCC_LIR_VA_END, + SCC_LIR_VA_COPY, + + /* 栈管理 */ + SCC_LIR_ALLOCA, + + SCC_LIR_NOP +} scc_lir_op_t; + +typedef enum { + SCC_LIR_COND_EQ, + SCC_LIR_COND_NE, + SCC_LIR_COND_SLT, + SCC_LIR_COND_SLE, + SCC_LIR_COND_SGT, + SCC_LIR_COND_SGE, + SCC_LIR_COND_ULT, + SCC_LIR_COND_ULE, + SCC_LIR_COND_UGT, + SCC_LIR_COND_UGE, + SCC_LIR_COND_FEQ, + SCC_LIR_COND_FNE, + SCC_LIR_COND_FLT, + SCC_LIR_COND_FLE, + SCC_LIR_COND_FGT, + SCC_LIR_COND_FGE +} scc_lir_cond_t; + +typedef scc_cfg_bblock_id_t scc_lir_bblock_id_t; +typedef struct scc_lir_ins { + scc_lir_op_t op; + u8 size; + scc_lir_ext_t ext; + scc_lir_val_t to; + scc_lir_val_t arg0; + scc_lir_val_t arg1; + /// @brief debug 信息 + scc_pos_t src_loc; + + union { + scc_lir_cond_t cond; + + struct scc_lir_br { + scc_lir_bblock_id_t true_target; + scc_lir_bblock_id_t false_target; + } br; + + scc_lir_bblock_id_t jmp_target; + + struct scc_lir_call { + const char *callee; + scc_lir_val_t *args; + int arg_count; + scc_lir_val_t ret_vreg; + u64 clobber_mask; + } call; + + struct scc_lir_call_indirect { + scc_lir_val_t target; + scc_lir_val_t *args; + int arg_count; + scc_lir_val_t ret_vreg; + u64 clobber_mask; + } call_indirect; + + scc_lir_val_t ret_val; + + struct scc_lir_parallel_copy { + scc_lir_val_t *dests; + scc_lir_val_t *srcs; + int num_copies; + } parallel_copy; + + struct scc_lir_alloca { + int size_bytes; + int align_bytes; + } alloca; + + struct { + scc_lir_val_t ap; + scc_lir_val_t last; + } va_start; + + struct { + scc_lir_val_t ap; + int type_size; + int type_align; + char is_float; + scc_lir_val_t to; + } va_arg; + + struct { + scc_lir_val_t ap; + } va_end; + + struct { + scc_lir_val_t dest; + scc_lir_val_t src; + } va_copy; + } metadata; +} scc_lir_instr_t; + +typedef SCC_VEC(scc_lir_instr_t) scc_lir_instr_vec_t; +typedef scc_cfg_bblock_t scc_lir_bblock_t; +#define SCC_LIR_BBLOCK_VALUES(bblock) \ + ((scc_lir_instr_vec_t *)&((bblock)->values)) + +typedef scc_cfg_func_t scc_lir_func_t; +typedef struct scc_lir_func_meta { + int vregs_count; + int frame_size; + scc_lir_attr_t attr; +} scc_lir_func_meta_t; +#define SCC_LIR_FUNC_META(func) ((scc_lir_func_meta_t *)(func)->meta) + +typedef scc_cfg_symbol_id_t scc_lir_symbol_id_t; +typedef scc_cfg_symbol_t scc_lir_symbol_t; +typedef struct scc_lir_symbol_meta { + union { + struct { + scc_lir_func_t *func; // 指向函数体(若为定义) + } func; + struct { + u8 *init_data; // 初始化数据(若为 NULL 则零初始化) + usize size; // 数据大小(字节) + int align; // 对齐要求 + } data; + }; +} scc_lir_symbol_meta_t; +#define SCC_LIR_SYMBOL_META(symbol) ((scc_lir_symbol_meta_t *)(symbol)->meta) + +#endif /* __SCC_LIR_H__ */ diff --git a/libs/ir/lir/include/scc_lir_dump.h b/libs/ir/lir/include/scc_lir_dump.h new file mode 100644 index 0000000..f8e14b6 --- /dev/null +++ b/libs/ir/lir/include/scc_lir_dump.h @@ -0,0 +1,25 @@ +#ifndef __SCC_LIR_DUMP_H__ +#define __SCC_LIR_DUMP_H__ + +#include "scc_lir.h" +#include "scc_lir_module.h" +#include + +typedef struct { + scc_tree_dump_t *dump_ctx; + scc_lir_module_t *module; +} scc_lir_dump_ctx_t; + +static inline void scc_lir_dump_init(scc_lir_dump_ctx_t *ctx, + scc_tree_dump_t *dump_ctx, + scc_lir_module_t *module) { + Assert(ctx != nullptr && dump_ctx != nullptr && module != nullptr); + ctx->dump_ctx = dump_ctx; + ctx->module = module; +} +void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins); +void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb); +void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func); +void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx); + +#endif /* __SCC_LIR_DUMP_H__ */ diff --git a/libs/ir/lir/include/scc_lir_module.h b/libs/ir/lir/include/scc_lir_module.h new file mode 100644 index 0000000..8835cb3 --- /dev/null +++ b/libs/ir/lir/include/scc_lir_module.h @@ -0,0 +1,59 @@ +/** + * @file scc_lir_module.h + * @brief LIR 模块:管理函数定义、全局符号和声明 + */ + +#ifndef __SCC_LIR_MODULE_H__ +#define __SCC_LIR_MODULE_H__ + +#include "scc_lir.h" +#include +#include +#include + +typedef SCC_VEC(scc_lir_func_meta_t *) scc_lir_func_meta_vec_t; +typedef SCC_VEC(scc_lir_symbol_meta_t *) scc_lir_symbol_meta_vec_t; +typedef struct scc_lir_module { + scc_cfg_module_t cfg_module; + scc_lir_func_meta_vec_t func_metas; + scc_lir_symbol_meta_vec_t symbol_metas; +} scc_lir_module_t; + +/** + * @brief 初始化 LIR 模块 + */ +void scc_lir_module_init(scc_lir_module_t *module); + +/** + * @brief 销毁 LIR 模块,释放所有函数和符号资源 + */ +void scc_lir_module_drop(scc_lir_module_t *module); + +/** + * @brief 添加一个函数声明(外部或未定义) + * @param mod 模块 + * @param name 函数名 + * @param attr 属性 + * @return 符号指针 + */ +scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module, + const char *name); + +/** + * @brief 添加一个全局数据符号(定义或外部) + * @param mod 模块 + * @param name 符号名 + * @param kind 种类 (DATA 或 EXTERN) + * @param init_data 初始化数据 (若为 DATA 定义;若为 NULL 则零初始化) + * @param size 数据大小 (若为 EXTERN 可为 0) + * @param align 对齐要求 + * @param attr 属性 + * @return 符号指针 + */ +scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *module, + const char *name, + scc_cfg_symbol_kind_t kind, + const u8 *init_data, usize size, + u32 align); + +#endif /* __SCC_LIR_MODULE_H__ */ diff --git a/libs/ir/lir/src/scc_hir2lir.c b/libs/ir/lir/src/scc_hir2lir.c new file mode 100644 index 0000000..9dfa788 --- /dev/null +++ b/libs/ir/lir/src/scc_hir2lir.c @@ -0,0 +1,544 @@ +/** + * @file scc_hir2lir.c + * @brief 将高级 IR (scc_ir) 降级为低层 LIR (scc_lir) + */ + +#include +#include + +/* ---------- 转换上下文 ---------- */ +typedef struct { + scc_hir_module_t *hir_module; + scc_lir_module_t *lir_module; + + scc_lir_func_t *current_func; + scc_lir_instr_vec_t instrs; + + scc_hashtable_t bb_map; // ir_bblock_ref_t -> scc_lir_bblock_id_t + scc_hashtable_t value_to_vreg; // ir_value_ref_t -> unsigned int vreg + scc_hashtable_t func_decl_map; // ir_func_ref_t -> const char* (用于调用) +} ir2lir_ctx_t; + +static void ir2lir_ctx_init(ir2lir_ctx_t *ctx, scc_lir_module_t *lir_module, + scc_hir_module_t *hir_module) { + ctx->hir_module = hir_module; + ctx->lir_module = lir_module; + scc_hashtable_usize_init(&ctx->bb_map); + scc_hashtable_usize_init(&ctx->value_to_vreg); + scc_hashtable_usize_init(&ctx->func_decl_map); +} + +static void ir2lir_ctx_drop(ir2lir_ctx_t *ctx) { + scc_hashtable_drop(&ctx->bb_map); + scc_hashtable_drop(&ctx->value_to_vreg); + scc_hashtable_drop(&ctx->func_decl_map); +} + +static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, + scc_hir_value_ref_t val_ref); +static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value, + scc_hir_value_ref_t value_ref); + +static void ir_type_to_lir_size_ext(scc_hir_type_t *type, u8 *out_size, + scc_lir_ext_t *out_ext) { + switch (type->tag) { + case SCC_HIR_TYPE_i8: + *out_size = SCC_LIR_SIZE_8; + *out_ext = SCC_LIR_EXT_SEXT; + break; + case SCC_HIR_TYPE_u8: + *out_size = SCC_LIR_SIZE_8; + *out_ext = SCC_LIR_EXT_ZEXT; + break; + case SCC_HIR_TYPE_i16: + *out_size = SCC_LIR_SIZE_16; + *out_ext = SCC_LIR_EXT_SEXT; + break; + case SCC_HIR_TYPE_u16: + *out_size = SCC_LIR_SIZE_16; + *out_ext = SCC_LIR_EXT_ZEXT; + break; + case SCC_HIR_TYPE_i32: + *out_size = SCC_LIR_SIZE_32; + *out_ext = SCC_LIR_EXT_SEXT; + break; + case SCC_HIR_TYPE_u32: + *out_size = SCC_LIR_SIZE_32; + *out_ext = SCC_LIR_EXT_ZEXT; + break; + case SCC_HIR_TYPE_i64: + *out_size = SCC_LIR_SIZE_64; + *out_ext = SCC_LIR_EXT_SEXT; + break; + case SCC_HIR_TYPE_u64: + *out_size = SCC_LIR_SIZE_64; + *out_ext = SCC_LIR_EXT_ZEXT; + break; + case SCC_HIR_TYPE_f32: + *out_size = SCC_LIR_SIZE_32; + *out_ext = SCC_LIR_EXT_FLOAT; + break; + case SCC_HIR_TYPE_f64: + *out_size = SCC_LIR_SIZE_64; + *out_ext = SCC_LIR_EXT_FLOAT; + break; + case SCC_HIR_TYPE_PTR: + *out_size = SCC_LIR_SIZE_64; + *out_ext = SCC_LIR_EXT_NONE; + break; + case SCC_HIR_TYPE_void: + *out_size = 0; + *out_ext = SCC_LIR_EXT_NONE; + break; + default: + Panic("unsupported IR type in lowering"); + } +} + +static inline void scc_lir_builder_add_instr(ir2lir_ctx_t *ctx, + scc_lir_instr_t *instr) { + scc_vec_push(ctx->instrs, *instr); +} + +// 获取或创建 IR 值对应的虚拟寄存器 +static int get_vreg_for_value(ir2lir_ctx_t *ctx, scc_hir_value_ref_t val_ref) { + void *found = + scc_hashtable_get(&ctx->value_to_vreg, (void *)(usize)val_ref); + if (found) + return (int)(usize)found; + + int vreg = SCC_LIR_FUNC_META(ctx->current_func)->vregs_count++; + scc_hashtable_set(&ctx->value_to_vreg, (void *)(usize)val_ref, + (void *)(usize)vreg); + return vreg; +} + +// 获取 LIR 操作数:若为常量/全局符号则直接构造,否则返回对应 vreg +static scc_lir_val_t ir_value_to_lir_operand(ir2lir_ctx_t *ctx, + scc_hir_value_ref_t val_ref) { + scc_hir_value_t *val = scc_hir_module_get_value(ctx->hir_module, val_ref); + Assert(val != nullptr); + + switch (val->tag) { + case SCC_HIR_VALUE_TAG_INTEGER: { + return SCC_LIR_IMM(val->data.integer); + } + case SCC_HIR_VALUE_TAG_DECIMAL: { + TODO(); + } + case SCC_HIR_VALUE_TAG_GLOBAL_ALLOC: { + // 全局变量地址作为符号 + scc_hir_value_t *global_val = scc_hir_module_get_value( + ctx->hir_module, val->data.global_alloc.value); + return SCC_LIR_SYMBOL(global_val->name); + } + case SCC_HIR_VALUE_TAG_FUNC_ARG_REF: { + // 函数参数:预先已分配 vreg + unsigned int vreg = get_vreg_for_value(ctx, val_ref); + return SCC_LIR_VREG(vreg); + } + case SCC_HIR_VALUE_TAG_NULLPTR: { + return SCC_LIR_IMM(0); + } + default: { + // 其他所有产生值的指令:确保其指令已生成,然后返回 vreg + // 注意:这里可能会递归调用 translate_ir_value,因此需要先检查是否已翻译 + void *found = + scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)val_ref); + if (!found) { + translate_hir_value(ctx, val, val_ref); + } + unsigned int vreg = (unsigned int)(uintptr_t)scc_hashtable_get( + &ctx->value_to_vreg, (void *)(uintptr_t)val_ref); + return SCC_LIR_VREG(vreg); + } + } +} + +static scc_lir_cond_t map_cmp_cond(scc_hir_op_type_t op, cbool is_float) { + if (is_float) { + switch (op) { + case SCC_HIR_OP_EQ: + return SCC_LIR_COND_FEQ; + case SCC_HIR_OP_NEQ: + return SCC_LIR_COND_FNE; + case SCC_HIR_OP_LT: + return SCC_LIR_COND_FLT; + case SCC_HIR_OP_LE: + return SCC_LIR_COND_FLE; + case SCC_HIR_OP_GT: + return SCC_LIR_COND_FGT; + case SCC_HIR_OP_GE: + return SCC_LIR_COND_FGE; + default: + Panic("invalid float cmp"); + } + } else { + // 默认为有符号比较 (无符号需额外处理类型) + switch (op) { + case SCC_HIR_OP_EQ: + return SCC_LIR_COND_EQ; + case SCC_HIR_OP_NEQ: + return SCC_LIR_COND_NE; + case SCC_HIR_OP_LT: + return SCC_LIR_COND_SLT; + case SCC_HIR_OP_LE: + return SCC_LIR_COND_SLE; + case SCC_HIR_OP_GT: + return SCC_LIR_COND_SGT; + case SCC_HIR_OP_GE: + return SCC_LIR_COND_SGE; + default: + Panic("invalid int cmp"); + } + } + return SCC_LIR_COND_EQ; +} + +static scc_lir_op_t map_binop(scc_hir_op_type_t op, cbool is_float) { + if (is_float) { + switch (op) { + case SCC_HIR_OP_ADD: + return SCC_LIR_FADD; + case SCC_HIR_OP_SUB: + return SCC_LIR_FSUB; + case SCC_HIR_OP_MUL: + return SCC_LIR_FMUL; + case SCC_HIR_OP_DIV: + return SCC_LIR_FDIV; + default: + Panic("unsupported float binop"); + } + } else { + switch (op) { + case SCC_HIR_OP_ADD: + return SCC_LIR_ADD; + case SCC_HIR_OP_SUB: + return SCC_LIR_SUB; + case SCC_HIR_OP_MUL: + return SCC_LIR_MUL; + case SCC_HIR_OP_DIV: + return SCC_LIR_DIV_S; + case SCC_HIR_OP_MOD: + return SCC_LIR_REM_S; + case SCC_HIR_OP_AND: + return SCC_LIR_AND; + case SCC_HIR_OP_OR: + return SCC_LIR_OR; + case SCC_HIR_OP_XOR: + return SCC_LIR_XOR; + case SCC_HIR_OP_SHL: + return SCC_LIR_SHL; + case SCC_HIR_OP_SHR: + return SCC_LIR_SHR; + case SCC_HIR_OP_SAR: + return SCC_LIR_SAR; + default: + return map_cmp_cond(op, is_float); + } + } + return SCC_LIR_NOP; +} + +static void translate_hir_value(ir2lir_ctx_t *ctx, scc_hir_value_t *value, + scc_hir_value_ref_t value_ref) { + // 防止重复翻译 + if (scc_hashtable_get(&ctx->value_to_vreg, (void *)(uintptr_t)value_ref)) + return; + + scc_hir_type_t *ty = scc_hir_module_get_type(ctx->hir_module, value->type); + u8 size = 0; + scc_lir_ext_t ext = SCC_LIR_EXT_NONE; + if (ty != nullptr) { + ir_type_to_lir_size_ext(ty, &size, &ext); + } + bool is_float = (ext == SCC_LIR_EXT_FLOAT); + + // 为当前指令分配目标虚拟寄存器 + unsigned int dst_vreg = get_vreg_for_value(ctx, value_ref); + + switch (value->tag) { + case SCC_HIR_VALUE_TAG_OP: { + scc_lir_val_t lhs = ir_value_to_lir_operand(ctx, value->data.op.lhs); + scc_lir_val_t rhs = ir_value_to_lir_operand(ctx, value->data.op.rhs); + scc_lir_op_t op = map_binop(value->data.op.op, is_float); + + scc_lir_instr_t instr = {.op = op, + .size = size, + .ext = ext, + .to = SCC_LIR_VREG(dst_vreg), + .arg0 = lhs, + .arg1 = rhs}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_LOAD: { + scc_lir_val_t addr = + ir_value_to_lir_operand(ctx, value->data.load.target); + scc_lir_instr_t instr = {.op = SCC_LIR_LOAD, + .size = size, + .ext = ext, + .to = SCC_LIR_VREG(dst_vreg), + .arg0 = addr}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_STORE: { + scc_lir_val_t data = + ir_value_to_lir_operand(ctx, value->data.store.value); + scc_lir_val_t addr = + ir_value_to_lir_operand(ctx, value->data.store.target); + scc_lir_instr_t instr = { + .op = SCC_LIR_STORE, .size = size, .arg0 = data, .arg1 = addr}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_GET_ELEM_PTR: { + // 将指针运算转换为 LEA + scc_lir_val_t base = + ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.src_addr); + scc_lir_val_t index = SCC_LIR_IMM(0); + if (value->data.get_elem_ptr.index) + ir_value_to_lir_operand(ctx, value->data.get_elem_ptr.index); + + // 计算元素大小 + scc_hir_type_t *ptr_ty = scc_hir_module_get_type_by_value( + ctx->hir_module, value->data.get_elem_ptr.src_addr); + scc_hir_type_t *elem_ty = nullptr; + if (ptr_ty->tag == SCC_HIR_TYPE_PTR) { + elem_ty = scc_hir_module_get_type(ctx->hir_module, + ptr_ty->data.pointer.base); + } else if (ptr_ty->tag == SCC_HIR_TYPE_ARRAY) { + elem_ty = scc_hir_module_get_type(ctx->hir_module, + ptr_ty->data.array.base); + } + Assert(elem_ty != nullptr); + int elem_size = 0; + // 简化:仅处理基本类型 + if (elem_ty->tag == SCC_HIR_TYPE_i32 || + elem_ty->tag == SCC_HIR_TYPE_u32) + elem_size = 4; + else if (elem_ty->tag == SCC_HIR_TYPE_i64 || + elem_ty->tag == SCC_HIR_TYPE_u64) + elem_size = 8; + else if (elem_ty->tag == SCC_HIR_TYPE_i8 || + elem_ty->tag == SCC_HIR_TYPE_u8) + elem_size = 1; + else if (elem_ty->tag == SCC_HIR_TYPE_ARRAY) + elem_size = 8; // FIXME ptr size + else + Panic("unsupported element type for getelemptr"); + + // 构造地址表达式:base + index * elem_size + scc_lir_val_t addr = + SCC_LIR_ADDR(dst_vreg, -1, index.data.reg, elem_size); + // 更简单的做法:使用 LEA 指令,参数为 base 和 index,由后端展开 + scc_lir_instr_t instr = {.op = SCC_LIR_LEA, + .size = SCC_LIR_SIZE_64, + .to = SCC_LIR_VREG(dst_vreg), + .arg0 = base, + .arg1 = index}; + // 实际需要将 index * elem_size 的信息编码,这里简化,假设后端处理 + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_ALLOC: { + // alloca 指令:分配栈空间 + scc_hir_type_t *alloc_ty = + scc_hir_module_get_type(ctx->hir_module, ty->data.pointer.base); + // 计算大小和对齐(简化) + int alloc_size = 8; // 默认 + if (alloc_ty->tag == SCC_HIR_TYPE_i32) + alloc_size = 4; + scc_lir_instr_t instr = {.op = SCC_LIR_ALLOCA, + .size = SCC_LIR_SIZE_64, + .to = SCC_LIR_VREG(dst_vreg), + .metadata.alloca = {alloc_size, alloc_size}}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_CALL: { + scc_hir_func_t *callee = + scc_hir_module_get_func(ctx->hir_module, value->data.call.callee); + int arg_count = scc_vec_size(value->data.call.args); + scc_lir_val_t *lir_args = scc_malloc(sizeof(scc_lir_val_t) * arg_count); + for (int i = 0; i < arg_count; i++) { + scc_hir_value_ref_t arg_ref = scc_vec_at(value->data.call.args, i); + lir_args[i] = ir_value_to_lir_operand(ctx, arg_ref); + } + + scc_lir_instr_t instr = { + .op = SCC_LIR_CALL, + .size = size, + .to = SCC_LIR_VREG(dst_vreg), + .metadata.call = {.callee = callee->name, + .args = lir_args, + .arg_count = arg_count, + .ret_vreg = SCC_LIR_VREG(dst_vreg), + .clobber_mask = 0}}; + scc_lir_builder_add_instr(ctx, &instr); + // 注意:lir_args 内存将随指令结构体复制到基本块向量中,但 + // metadata.call.args 指针仍指向 malloc 内存, + // 这会导致内存泄漏。实际实现中应使用 arena + // 分配或随函数释放。此处为示例简化。 + break; + } + case SCC_HIR_VALUE_TAG_BRANCH: { + scc_lir_val_t cond = + ir_value_to_lir_operand(ctx, value->data.branch.cond); + scc_lir_bblock_id_t true_bb = + (scc_lir_bblock_id_t)(uintptr_t)scc_hashtable_get( + &ctx->bb_map, + (void *)(uintptr_t)value->data.branch.true_bblock); + scc_lir_bblock_id_t false_bb = + (scc_lir_bblock_id_t)(uintptr_t)scc_hashtable_get( + &ctx->bb_map, + (void *)(uintptr_t)value->data.branch.false_bblock); + scc_lir_instr_t instr = { + .op = SCC_LIR_BR, .arg0 = cond, .metadata.br = {true_bb, false_bb}}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_JUMP: { + scc_lir_bblock_id_t target = + (scc_lir_bblock_id_t)(usize)scc_hashtable_get( + &ctx->bb_map, (void *)(usize)value->data.jump.target_bblock); + scc_lir_instr_t instr = {.op = SCC_LIR_JMP, + .metadata.jmp_target = target}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_RET: { + scc_lir_val_t ret_val; + if (value->data.ret.ret_val != SCC_HIR_REF_nullptr) { + ret_val = ir_value_to_lir_operand(ctx, value->data.ret.ret_val); + } else { + ret_val = SCC_LIR_NONE(); + } + scc_lir_instr_t instr = {.op = SCC_LIR_RET, + .metadata.ret_val = ret_val}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + case SCC_HIR_VALUE_TAG_CONV: { + // 类型转换:使用 MOV 指令配合扩展/截断 + scc_lir_val_t src = + ir_value_to_lir_operand(ctx, value->data.conv.operand); + scc_lir_ext_t conv_ext = SCC_LIR_EXT_NONE; + if (value->data.conv.conv_type == CONV_SEXT) + conv_ext = SCC_LIR_EXT_SEXT; + else if (value->data.conv.conv_type == CONV_ZEXT) + conv_ext = SCC_LIR_EXT_ZEXT; + // TRUNC 用 NONE 即可(MOV 截断) + scc_lir_instr_t instr = {.op = SCC_LIR_MOV, + .size = size, + .ext = conv_ext, + .to = SCC_LIR_VREG(dst_vreg), + .arg0 = src}; + scc_lir_builder_add_instr(ctx, &instr); + break; + } + default: + // 不生成指令的节点(如 CONST_INT, FUNC_ARG_REF)不会调用本函数 + break; + } +} + +static void translate_func(ir2lir_ctx_t *ctx, scc_hir_func_t *ir_func) { + scc_hir_func_meta_t *func_meta = SCC_HIR_FUNC_META(ir_func); + + scc_lir_func_meta_t *lir_func_meta = + scc_malloc(sizeof(scc_lir_func_meta_t)); + Assert(lir_func_meta != nullptr); + *lir_func_meta = (scc_lir_func_meta_t){ + .attr = SCC_LIR_ATTR_NONE, + .frame_size = 0, + .vregs_count = 0, + }; + scc_vec_push(ctx->lir_module->func_metas, lir_func_meta); + ctx->current_func = ir_func; + ir_func->meta = lir_func_meta; + + // 预先为所有参数分配虚拟寄存器 + scc_vec_foreach(func_meta->params, i) { + scc_hir_value_ref_t param_ref = scc_vec_at(func_meta->params, i); + get_vreg_for_value(ctx, param_ref); + } + + scc_vec_foreach(ir_func->bblocks, i) { + scc_hir_bblock_ref_t bb_ref = scc_vec_at(ir_func->bblocks, i); + scc_hir_bblock_t *bb = + scc_hir_module_get_bblock(ctx->hir_module, bb_ref); + + scc_vec_init(ctx->instrs); + + // 翻译指令 + scc_vec_foreach(bb->values, j) { + scc_hir_value_ref_t val_ref = + scc_vec_at(*SCC_HIR_BBLOCK_VALUES(bb), j); + scc_hir_value_t *val = + scc_hir_module_get_value(ctx->hir_module, val_ref); + translate_hir_value(ctx, val, val_ref); + } + + bb->values = *(scc_cfg_value_vec_t *)&ctx->instrs; + // MOVE + scc_vec_init(ctx->instrs); + } + + // 清理本次函数翻译的临时映射 + scc_hashtable_drop(&ctx->bb_map); + scc_hashtable_drop(&ctx->value_to_vreg); +} + +void scc_hir2lir(scc_lir_module_t *module, const scc_hir_cprog_t *cprog) { + Assert(module != nullptr && cprog != nullptr); + + // FIXME + module->cfg_module = cprog->module.cfg_module; + + ir2lir_ctx_t ctx; + ir2lir_ctx_init(&ctx, module, &cprog->module); + + // 1. 处理全局变量 + for (usize i = 0; i < scc_vec_size(cprog->global_vals); i++) { + scc_hir_value_ref_t gv_ref = scc_vec_at(cprog->global_vals, i); + scc_hir_value_t *galloc = + scc_hir_module_get_value(&cprog->module, gv_ref); + Assert(galloc->tag == SCC_HIR_VALUE_TAG_GLOBAL_ALLOC); + scc_hir_value_t *val = scc_hir_module_get_value( + &cprog->module, galloc->data.global_alloc.value); + scc_hir_buffer_t *data = &val->data.const_array.fields; + scc_lir_symbol_id_t id = scc_lir_module_add_data( + module, galloc->name, SCC_CFG_SYMBOL_KIND_DATA, + scc_vec_unsafe_get_data(*data), scc_vec_size(*data), 0); + Assert(id != SCC_CFG_ID_nullptr); + } + + // 2. 处理函数声明 (外部函数) + for (usize i = 0; i < scc_vec_size(cprog->func_decls); i++) { + scc_hir_func_ref_t func_ref = scc_vec_at(cprog->func_decls, i); + scc_hir_func_t *func = + scc_hir_module_get_func(&cprog->module, func_ref); + if (!func) + continue; + scc_lir_symbol_id_t id = + scc_lir_module_add_func_decl(module, func->name); + Assert(id != SCC_CFG_ID_nullptr); + // 记录映射,供调用时使用 + scc_hashtable_set(&ctx.func_decl_map, (void *)(uintptr_t)func_ref, + (void *)func->name); + } + + // 3. 处理函数定义 + for (usize i = 0; i < scc_vec_size(cprog->func_defs); i++) { + scc_hir_func_ref_t func_ref = scc_vec_at(cprog->func_defs, i); + scc_hir_func_t *func = + scc_hir_module_get_func(&cprog->module, func_ref); + if (!func) + continue; + translate_func(&ctx, func); + } + + ir2lir_ctx_drop(&ctx); +} diff --git a/libs/ir/lir/src/scc_lir_dump.c b/libs/ir/lir/src/scc_lir_dump.c new file mode 100644 index 0000000..263c316 --- /dev/null +++ b/libs/ir/lir/src/scc_lir_dump.c @@ -0,0 +1,459 @@ +/** + * @file scc_lir_dump.c + * @brief LIR 文本 dump 实现 + */ + +#include "scc_lir_dump.h" +#include + +static const char *op_to_string(scc_lir_op_t op) { + switch (op) { + case SCC_LIR_MOV: + return "mov"; + case SCC_LIR_LOAD: + return "load"; + case SCC_LIR_LOAD_ADDR: + return "load.addr"; + case SCC_LIR_STORE: + return "store"; + case SCC_LIR_STORE_ADDR: + return "store.addr"; + case SCC_LIR_LEA: + return "lea"; + case SCC_LIR_ADD: + return "add"; + case SCC_LIR_SUB: + return "sub"; + case SCC_LIR_MUL: + return "mul"; + case SCC_LIR_DIV_S: + return "div.s"; + case SCC_LIR_DIV_U: + return "div.u"; + case SCC_LIR_REM_S: + return "rem.s"; + case SCC_LIR_REM_U: + return "rem.u"; + case SCC_LIR_AND: + return "and"; + case SCC_LIR_OR: + return "or"; + case SCC_LIR_XOR: + return "xor"; + case SCC_LIR_SHL: + return "shl"; + case SCC_LIR_SHR: + return "shr"; + case SCC_LIR_SAR: + return "sar"; + case SCC_LIR_NEG: + return "neg"; + case SCC_LIR_NOT: + return "not"; + case SCC_LIR_FADD: + return "fadd"; + case SCC_LIR_FSUB: + return "fsub"; + case SCC_LIR_FMUL: + return "fmul"; + case SCC_LIR_FDIV: + return "fdiv"; + case SCC_LIR_FNEG: + return "fneg"; + case SCC_LIR_FCVT: + return "fcvt"; + case SCC_LIR_CMP: + return "cmp"; + case SCC_LIR_BR: + return "br"; + case SCC_LIR_JMP: + return "jmp"; + case SCC_LIR_JMP_INDIRECT: + return "jmp.indirect"; + case SCC_LIR_CALL: + return "call"; + case SCC_LIR_CALL_INDIRECT: + return "call.indirect"; + case SCC_LIR_RET: + return "ret"; + case SCC_LIR_PARALLEL_COPY: + return "parallel_copy"; + case SCC_LIR_VA_START: + return "va_start"; + case SCC_LIR_VA_ARG: + return "va_arg"; + case SCC_LIR_VA_END: + return "va_end"; + case SCC_LIR_VA_COPY: + return "va_copy"; + case SCC_LIR_ALLOCA: + return "alloca"; + case SCC_LIR_NOP: + return "nop"; + default: + return "???"; + } +} + +static const char *cond_to_string(scc_lir_cond_t cond) { + switch (cond) { + case SCC_LIR_COND_EQ: + return "eq"; + case SCC_LIR_COND_NE: + return "ne"; + case SCC_LIR_COND_SLT: + return "slt"; + case SCC_LIR_COND_SLE: + return "sle"; + case SCC_LIR_COND_SGT: + return "sgt"; + case SCC_LIR_COND_SGE: + return "sge"; + case SCC_LIR_COND_ULT: + return "ult"; + case SCC_LIR_COND_ULE: + return "ule"; + case SCC_LIR_COND_UGT: + return "ugt"; + case SCC_LIR_COND_UGE: + return "uge"; + case SCC_LIR_COND_FEQ: + return "feq"; + case SCC_LIR_COND_FNE: + return "fne"; + case SCC_LIR_COND_FLT: + return "flt"; + case SCC_LIR_COND_FLE: + return "fle"; + case SCC_LIR_COND_FGT: + return "fgt"; + case SCC_LIR_COND_FGE: + return "fge"; + default: + return "???"; + } +} + +static void dump_operand(scc_lir_dump_ctx_t *ctx, const scc_lir_val_t *op) { + scc_tree_dump_t *td = ctx->dump_ctx; + + switch (op->kind) { + case SCC_LIR_INSTR_KIND_NONE: + scc_tree_dump_append(td, "_"); + break; + case SCC_LIR_INSTR_KIND_VREG: + scc_tree_dump_append_fmt(td, "%%%u", op->data.reg); + break; + case SCC_LIR_INSTR_KIND_PREG: + scc_tree_dump_append_fmt(td, "Phy%u", op->data.reg); + break; + case SCC_LIR_INSTR_KIND_IMM: + // TODO hack ap + scc_tree_dump_append_fmt(td, "%lld", op->data.imm.data.digit); + break; + case SCC_LIR_INSTR_KIND_FIMM: + TODO(); + scc_tree_dump_append_fmt(td, "%lf", op->data.fimm); + break; + case SCC_LIR_INSTR_KIND_SYMBOL: + scc_tree_dump_append_fmt(td, "@%s", + op->data.symbol ? op->data.symbol : ""); + break; + case SCC_LIR_INSTR_KIND_ADDR: { + const scc_lir_addr_t *addr = &op->data.addr; + scc_tree_dump_append(td, "["); + if (addr->base != -1) { + scc_tree_dump_append_fmt(td, "%%%d", addr->base); + } + if (addr->index != -1) { + scc_tree_dump_append_fmt(td, " + %%%d * %d", addr->index, + addr->scale); + } + if (addr->offset != 0) { + if (addr->offset > 0) + scc_tree_dump_append_fmt(td, " + %lld", + (long long)addr->offset); + else + scc_tree_dump_append_fmt(td, " - %lld", + -(long long)addr->offset); + } + if (addr->base == -1 && addr->index == -1 && addr->offset == 0) + scc_tree_dump_append(td, "0"); + scc_tree_dump_append(td, "]"); + break; + } + default: + scc_tree_dump_append(td, ""); + } +} + +static void dump_size_ext(scc_lir_dump_ctx_t *ctx, u8 size, scc_lir_ext_t ext) { + scc_tree_dump_t *td = ctx->dump_ctx; + const char *size_str = ""; + if (size == SCC_LIR_SIZE_8) + size_str = "8"; + else if (size == SCC_LIR_SIZE_16) + size_str = "16"; + else if (size == SCC_LIR_SIZE_32) + size_str = "32"; + else if (size == SCC_LIR_SIZE_64) + size_str = "64"; + + const char *ext_str = ""; + if (ext == SCC_LIR_EXT_SEXT) + ext_str = ".s"; + else if (ext == SCC_LIR_EXT_ZEXT) + ext_str = ".u"; + else if (ext == SCC_LIR_EXT_FLOAT) + ext_str = ".f"; + + if (size_str[0] || ext_str[0]) { + scc_tree_dump_append_fmt(td, ".%s%s", size_str, ext_str); + } +} + +void scc_lir_dump_ins(scc_lir_dump_ctx_t *ctx, const scc_lir_instr_t *ins) { + Assert(ctx != nullptr && ins != nullptr); + scc_tree_dump_t *td = ctx->dump_ctx; + + scc_tree_dump_begin_line(td); + scc_tree_dump_append(td, " "); + // 输出操作码(带节点颜色) + scc_tree_dump_node(td, "%s", op_to_string(ins->op)); + + // 输出宽度和扩展标志 + dump_size_ext(ctx, ins->size, ins->ext); + scc_tree_dump_append(td, " "); + + switch (ins->op) { + case SCC_LIR_MOV: + case SCC_LIR_LOAD: + case SCC_LIR_LOAD_ADDR: + dump_operand(ctx, &ins->to); + scc_tree_dump_append(td, " <- "); + dump_operand(ctx, &ins->arg0); + break; + case SCC_LIR_LEA: + case SCC_LIR_NEG: + case SCC_LIR_NOT: + case SCC_LIR_FNEG: + case SCC_LIR_FCVT: + case SCC_LIR_ALLOCA: + dump_operand(ctx, &ins->to); + if (ins->op != SCC_LIR_ALLOCA) { + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->arg0); + // alloca 额外信息在 metadata 中,但通常只关注 to + } + break; + + case SCC_LIR_STORE: + case SCC_LIR_STORE_ADDR: + dump_operand(ctx, &ins->arg0); + scc_tree_dump_append(td, " -> "); + dump_operand(ctx, &ins->arg1); + break; + + case SCC_LIR_ADD: + case SCC_LIR_SUB: + case SCC_LIR_MUL: + case SCC_LIR_DIV_S: + case SCC_LIR_DIV_U: + case SCC_LIR_REM_S: + case SCC_LIR_REM_U: + case SCC_LIR_AND: + case SCC_LIR_OR: + case SCC_LIR_XOR: + case SCC_LIR_SHL: + case SCC_LIR_SHR: + case SCC_LIR_SAR: + case SCC_LIR_FADD: + case SCC_LIR_FSUB: + case SCC_LIR_FMUL: + case SCC_LIR_FDIV: + dump_operand(ctx, &ins->to); + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->arg0); + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->arg1); + break; + + case SCC_LIR_CMP: + dump_operand(ctx, &ins->to); + scc_tree_dump_append_fmt(td, ", %s, ", + cond_to_string(ins->metadata.cond)); + dump_operand(ctx, &ins->arg0); + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->arg1); + break; + + case SCC_LIR_BR: + dump_operand(ctx, &ins->arg0); + scc_tree_dump_append_fmt(td, ", BB#%zu, BB#%zu", + ins->metadata.br.true_target, + ins->metadata.br.false_target); + break; + + case SCC_LIR_JMP: + scc_tree_dump_append_fmt(td, "BB#%zu", ins->metadata.jmp_target); + break; + + case SCC_LIR_JMP_INDIRECT: + dump_operand(ctx, &ins->arg0); + break; + + case SCC_LIR_CALL: { + const struct scc_lir_call *c = &ins->metadata.call; + if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) { + dump_operand(ctx, &c->ret_vreg); + scc_tree_dump_append(td, " = "); + } + scc_tree_dump_append_fmt(td, "call @%s(", + c->callee ? c->callee : ""); + for (u8 i = 0; i < c->arg_count; i++) { + if (i > 0) + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &c->args[i]); + } + scc_tree_dump_append_fmt(td, ") clobber=0x%llx", + (unsigned long long)c->clobber_mask); + break; + } + + case SCC_LIR_CALL_INDIRECT: { + const struct scc_lir_call_indirect *c = &ins->metadata.call_indirect; + if (c->ret_vreg.kind != SCC_LIR_INSTR_KIND_NONE) { + dump_operand(ctx, &c->ret_vreg); + scc_tree_dump_append(td, " = "); + } + scc_tree_dump_append(td, "call "); + dump_operand(ctx, &c->target); + scc_tree_dump_append(td, "("); + for (u8 i = 0; i < c->arg_count; i++) { + if (i > 0) + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &c->args[i]); + } + scc_tree_dump_append_fmt(td, ") clobber=0x%llx", + (unsigned long long)c->clobber_mask); + break; + } + + case SCC_LIR_RET: + if (ins->metadata.ret_val.kind != SCC_LIR_INSTR_KIND_NONE) { + dump_operand(ctx, &ins->metadata.ret_val); + } + break; + + case SCC_LIR_PARALLEL_COPY: { + const struct scc_lir_parallel_copy *pc = &ins->metadata.parallel_copy; + scc_tree_dump_append(td, "["); + for (u8 i = 0; i < pc->num_copies; i++) { + if (i > 0) + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &pc->dests[i]); + scc_tree_dump_append(td, " <- "); + dump_operand(ctx, &pc->srcs[i]); + } + scc_tree_dump_append(td, "]"); + break; + } + + case SCC_LIR_VA_START: + dump_operand(ctx, &ins->metadata.va_start.ap); + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->metadata.va_start.last); + break; + + case SCC_LIR_VA_ARG: + dump_operand(ctx, &ins->metadata.va_arg.to); + scc_tree_dump_append(td, " = va_arg "); + dump_operand(ctx, &ins->metadata.va_arg.ap); + scc_tree_dump_append_fmt( + td, ", size=%u, align=%u, float=%d", ins->metadata.va_arg.type_size, + ins->metadata.va_arg.type_align, ins->metadata.va_arg.is_float); + break; + + case SCC_LIR_VA_END: + dump_operand(ctx, &ins->metadata.va_end.ap); + break; + + case SCC_LIR_VA_COPY: + dump_operand(ctx, &ins->metadata.va_copy.dest); + scc_tree_dump_append(td, ", "); + dump_operand(ctx, &ins->metadata.va_copy.src); + break; + + case SCC_LIR_NOP: + break; + } +} + +void scc_lir_dump_bblock(scc_lir_dump_ctx_t *ctx, const scc_lir_bblock_t *bb) { + Assert(ctx != nullptr && bb != nullptr); + scc_tree_dump_t *td = ctx->dump_ctx; + + // 基本块头部 + scc_tree_dump_begin_line(td); + scc_tree_dump_node(td, "BB%zu", bb->id); + if (bb->name) { + scc_tree_dump_append_fmt(td, " (%s)", bb->name); + } + scc_tree_dump_append(td, ":"); + + // 输出每条指令 + scc_lir_instr_vec_t *instrs = SCC_LIR_BBLOCK_VALUES(bb); + scc_vec_foreach(*instrs, i) { + const scc_lir_instr_t *ins = &scc_vec_at(*instrs, i); + scc_lir_dump_ins(ctx, ins); + } +} + +void scc_lir_dump_func(scc_lir_dump_ctx_t *ctx, const scc_lir_func_t *func) { + Assert(ctx != nullptr && func != nullptr); + scc_tree_dump_t *td = ctx->dump_ctx; + + scc_lir_func_meta_t *meta = SCC_LIR_FUNC_META(func); + // 函数头部 + scc_tree_dump_begin_line(td); + scc_tree_dump_node(td, "func @%s", func->name ? func->name : ""); + scc_tree_dump_append_fmt(td, " (vregs: %u, frame: %d)", meta->vregs_count, + meta->frame_size); + if (meta->attr != SCC_LIR_ATTR_NONE) { + scc_tree_dump_append(td, " [attr:"); + if (meta->attr & SCC_LIR_ATTR_STATIC) + scc_tree_dump_append(td, " static"); + if (meta->attr & SCC_LIR_ATTR_WEAK) + scc_tree_dump_append(td, " weak"); + scc_tree_dump_append(td, " ]"); + } + scc_tree_dump_append(td, " {"); + + // 输出所有基本块 + for (usize i = 0; i < scc_vec_size(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(&ctx->module->cfg_module, id); + scc_lir_dump_bblock(ctx, bb); + } + + scc_tree_dump_begin_line(td); + scc_tree_dump_append(td, "}"); +} + +void scc_lir_dump_module(scc_lir_dump_ctx_t *ctx) { + scc_vec_foreach(ctx->module->cfg_module.symbols, i) { + // FIXME 0 is null + if (i == 0) + continue; + scc_lir_symbol_t *sym = &scc_vec_at(ctx->module->cfg_module.symbols, i); + scc_tree_dump_begin_line(ctx->dump_ctx); + scc_tree_dump_node(ctx->dump_ctx, "symbol"); + scc_tree_dump_append_fmt(ctx->dump_ctx, " %s", sym->name); + } + scc_vec_foreach(ctx->module->cfg_module.funcs, i) { + if (i == 0) + continue; + scc_lir_dump_func(ctx, &scc_vec_at(ctx->module->cfg_module.funcs, i)); + } +} diff --git a/libs/ir/lir/src/scc_lir_module.c b/libs/ir/lir/src/scc_lir_module.c new file mode 100644 index 0000000..187f886 --- /dev/null +++ b/libs/ir/lir/src/scc_lir_module.c @@ -0,0 +1,79 @@ +#include + +void scc_lir_module_init(scc_lir_module_t *module) { + // FIXME + // module->module + + scc_vec_init(module->func_metas); + scc_vec_init(module->symbol_metas); +} + +void scc_lir_module_drop(scc_lir_module_t *module) { + scc_vec_free(module->func_metas); + scc_vec_free(module->symbol_metas); +} + +scc_lir_symbol_id_t scc_lir_module_add_func_decl(scc_lir_module_t *module, + const char *name) { + if (!module || !name) + return SCC_CFG_ID_nullptr; + + scc_lir_symbol_meta_t *meta = scc_malloc(sizeof(scc_lir_symbol_meta_t)); + Assert(meta != nullptr); + scc_lir_symbol_t sym = {.name = name, + .kind = SCC_CFG_SYMBOL_KIND_FUNC, + .linkage = SCC_CFG_SYMBOL_LINK_GLOABL, + .meta = meta}; + meta->func.func = nullptr; + + scc_vec_push(module->symbol_metas, meta); + scc_cfg_symbol_id_t id = + scc_cfg_module_add_symbol(&module->cfg_module, &sym); + if (id == SCC_CFG_ID_nullptr) { + Panic("scc_lir: add func decl '%s' failed", name); + } + return id; +} + +scc_lir_symbol_id_t scc_lir_module_add_data(scc_lir_module_t *module, + const char *name, + scc_cfg_symbol_kind_t kind, + const u8 *init_data, usize size, + u32 align) { + if (!module || !name) + return SCC_CFG_ID_nullptr; + if (kind != SCC_CFG_SYMBOL_KIND_DATA && kind != SCC_CFG_SYMBOL_KIND_EXTERN) + return SCC_CFG_ID_nullptr; + + scc_lir_symbol_meta_t *meta = scc_malloc(sizeof(scc_lir_symbol_meta_t)); + Assert(meta != nullptr); + scc_lir_symbol_t sym = {.name = name, .kind = kind, .meta = meta}; + *meta = (scc_lir_symbol_meta_t){ + .data = {.init_data = nullptr, .size = size, .align = align}, + }; + + /* 对于数据定义,复制初始化数据(若有) */ + if (kind == SCC_CFG_SYMBOL_KIND_DATA && init_data && size > 0) { + meta->data.init_data = scc_malloc(size); + if (!meta->data.init_data) { + LOG_FATAL("out of memory for data symbol '%s'", name); + } + scc_memcpy(meta->data.init_data, init_data, size); + } else if (kind == SCC_CFG_SYMBOL_KIND_DATA && !init_data) { + /* 零初始化:分配并清零 */ + meta->data.init_data = scc_calloc(1, size); + if (!meta->data.init_data) { + LOG_FATAL("out of memory for data symbol '%s'", name); + } + } + + scc_vec_push(module->symbol_metas, meta); + scc_cfg_symbol_id_t id = + scc_cfg_module_add_symbol(&module->cfg_module, &sym); + if (id = SCC_CFG_ID_nullptr) { + /* 冲突时释放已分配的数据 */ + scc_free(meta->data.init_data); + return SCC_CFG_ID_nullptr; + } + return id; +} diff --git a/libs/mcode/include/amd64/scc_amd64.h b/libs/mcode/include/amd64/scc_amd64.h deleted file mode 100644 index f43ccf5..0000000 --- a/libs/mcode/include/amd64/scc_amd64.h +++ /dev/null @@ -1,2530 +0,0 @@ -/** - * @file scc_mcode_amd64.h - * @author your name (you@domain.com) - * @brief - * @version 0.1 - * @date 2026-03-13 - * - * @copyright Copyright (c) 2026 - * - */ -#ifndef __SCC_MCODE_AMD64_H__ -#define __SCC_MCODE_AMD64_H__ - -///< @warning WRITE BY AI - -#include // 提供 u8, u32, u64 等 -#include // 提供 scc_mcode_t 和写入函数 - -// ==================== 寄存器编号 ==================== -#define SCC_AMD64_RAX 0 -#define SCC_AMD64_RCX 1 -#define SCC_AMD64_RDX 2 -#define SCC_AMD64_RBX 3 -#define SCC_AMD64_RSP 4 -#define SCC_AMD64_RBP 5 -#define SCC_AMD64_RSI 6 -#define SCC_AMD64_RDI 7 -#define SCC_AMD64_R8 8 -#define SCC_AMD64_R9 9 -#define SCC_AMD64_R10 10 -#define SCC_AMD64_R11 11 -#define SCC_AMD64_R12 12 -#define SCC_AMD64_R13 13 -#define SCC_AMD64_R14 14 -#define SCC_AMD64_R15 15 - -// ==================== 条件码(用于 Jcc 等) ==================== -#define SCC_AMD64_COND_O 0 // overflow -#define SCC_AMD64_COND_NO 1 // not overflow -#define SCC_AMD64_COND_B 2 // below (unsigned) -#define SCC_AMD64_COND_AE 3 // above or equal (unsigned) -#define SCC_AMD64_COND_E 4 // equal -#define SCC_AMD64_COND_NE 5 // not equal -#define SCC_AMD64_COND_BE 6 // below or equal (unsigned) -#define SCC_AMD64_COND_A 7 // above (unsigned) -#define SCC_AMD64_COND_S 8 // sign (negative) -#define SCC_AMD64_COND_NS 9 // not sign -#define SCC_AMD64_COND_P 10 // parity even -#define SCC_AMD64_COND_NP 11 // parity odd -#define SCC_AMD64_COND_L 12 // less (signed) -#define SCC_AMD64_COND_GE 13 // greater or equal (signed) -#define SCC_AMD64_COND_LE 14 // less or equal (signed) -#define SCC_AMD64_COND_G 15 // greater (signed) - -#define SCC_MCODE_FUNC [[maybe_unused]] static inline - -// ==================== REX 前缀辅助 ==================== -/** - * @brief 生成 REX 前缀(若不为 0x40 则写入) - * - * @param mcode 机器码缓冲区 - * @param w REX.W 位 - * @param r REX.R 位 - * @param x REX.X 位 - * @param b REX.B 位 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_rex(scc_mcode_t *mcode, u8 w, u8 r, u8 x, - u8 b) { - u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | b; - if (rex != 0x40) - scc_mcode_add_u8(mcode, rex); -} - -// ==================== 内部辅助函数 ==================== - -/** - * @brief 根据目标寄存器和源寄存器生成 REX 位掩码(用于 reg 和 r/m 字段) - * - * @param dst_reg 目标寄存器编号 - * @param src_reg 源寄存器编号 - * @param use_w 是否设置 REX.W - * @param p_rex 输出 REX 值 - * @param p_dst_low 输出 dst 的低 3 位 - * @param p_src_low 输出 src 的低 3 位 - * @return 是否需要写入 REX 前缀(0 表示不需要) - */ -SCC_MCODE_FUNC int scc_mcode_amd64_prepare_rex(int dst_reg, int src_reg, - int use_w, u8 *p_rex, - u8 *p_dst_low, u8 *p_src_low) { - u8 rex = 0x40; - if (use_w) - rex |= 0x08; - if (dst_reg >= 8) - rex |= 0x01; // REX.B - if (src_reg >= 8) - rex |= 0x04; // REX.R - *p_dst_low = dst_reg & 7; - *p_src_low = src_reg & 7; - *p_rex = rex; - return (rex != 0x40); -} - -/** - * @brief 根据操作数宽度添加必要前缀(16 位添加 0x66,32 位无前缀,64 位需配合 - * REX.W) - * - * @param mcode 机器码缓冲区 - * @param width 宽度(1=8位,2=16位,4=32位,8=64位) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_emit_width_prefix(scc_mcode_t *mcode, - int width) { - if (width == 2) { - scc_mcode_add_u8(mcode, 0x66); - } - // 32 位无前缀,64 位通过 REX.W 处理(由调用者设置) -} - -// ==================== 栈操作 ==================== - -/** - * @brief 压入 64 位寄存器 - * - * @param mcode 机器码缓冲区 - * @param reg 寄存器编号 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_push_r64(scc_mcode_t *mcode, int reg) { - if (reg < 8) { - scc_mcode_add_u8(mcode, 0x50 + reg); - } else { - scc_mcode_amd64_rex(mcode, 0, 0, 0, 1); // REX.B - scc_mcode_add_u8(mcode, 0x50 + (reg - 8)); - } -} - -/** - * @brief 弹出到 64 位寄存器 - * - * @param mcode 机器码缓冲区 - * @param reg 寄存器编号 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_pop_r64(scc_mcode_t *mcode, int reg) { - if (reg < 8) { - scc_mcode_add_u8(mcode, 0x58 + reg); - } else { - scc_mcode_amd64_rex(mcode, 0, 0, 0, 1); // REX.B - scc_mcode_add_u8(mcode, 0x58 + (reg - 8)); - } -} - -/** - * @brief 压入 32 位立即数(符号扩展至 64 位) - * - * @param mcode 机器码缓冲区 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_push_imm32(scc_mcode_t *mcode, u32 imm) { - scc_mcode_add_u8(mcode, 0x68); - scc_mcode_add_u32(mcode, imm); -} - -// ==================== 数据传送 ==================== - -// ---------- 64 位 ---------- - -/** - * @brief 将 64 位立即数移动到 64 位寄存器 (mov r64, imm64) - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - * @param imm 64 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_imm64(scc_mcode_t *mcode, int reg, - u64 imm) { - u8 rex = 0x48; // REX.W - if (reg >= 8) { - rex |= 0x01; // REX.B - reg -= 8; - } - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xB8 + reg); - scc_mcode_add_u64(mcode, imm); -} - -/** - * @brief 将 32 位立即数移动到 64 位寄存器(高 32 位清零)(mov r64, imm32) - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_imm32(scc_mcode_t *mcode, int reg, - u32 imm) { - u8 rex = 0x40; // REX.W=0 - if (reg >= 8) { - rex |= 0x01; // REX.B - reg -= 8; - } - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xB8 + reg); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 64 位寄存器之间传送 (mov r64, r64) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; // REX.W - if (src >= 8) - rex |= 0x04; // REX.R - if (dst >= 8) - rex |= 0x01; // REX.B - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); // MOV r/m, r - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 存储 64 位寄存器到 [base] (mov [base], r64) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_r64(scc_mcode_t *mcode, int base, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从 [base] 加载到 64 位寄存器 (mov r64, [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8B); - u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 存储 64 位寄存器到 [base + disp32] (mov [base+disp32], r64) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - * @param disp 32 位偏移 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_disp32_r64(scc_mcode_t *mcode, - int base, u32 disp, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = 0x80 | (base & 7) | ((src & 7) << 3); // mod=10 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } - scc_mcode_add_u32(mcode, disp); -} - -/** - * @brief 从 [base + disp32] 加载到 64 位寄存器 (mov r64, [base+disp32]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - * @param disp 32 位偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_disp32(scc_mcode_t *mcode, - int dst, int base, - u32 disp) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8B); - u8 modrm = 0x80 | (base & 7) | ((dst & 7) << 3); // mod=10 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } - scc_mcode_add_u32(mcode, disp); -} - -/** - * @brief 加载 RIP 相对地址到 64 位寄存器 (lea r64, [rip+disp32]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 (0-15) - * @param disp 32 位相对偏移量 (有符号) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_rip_rel32(scc_mcode_t *mcode, - int dst, u32 disp) { - // REX.W = 1, 无额外扩展位(RIP 不是通用寄存器,不涉及 REX.B/R/X) - u8 rex = 0x48; - if (dst >= 8) { - rex |= 0x04; // REX.R 位,因为 dst 放在 reg 字段 - dst -= 8; - } - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8D); // LEA opcode - - // ModRM: mod=00 (无位移), reg=dst, r/m=101 (RIP 相对寻址) - u8 modrm = 0x05 | ((dst & 7) << 3); - scc_mcode_add_u8(mcode, modrm); - - // disp32 (有符号) - scc_mcode_add_u32(mcode, (u32)disp); -} - -/** - * @brief 加载有效地址到 64 位寄存器 (lea r64, [base+disp32]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - * @param disp 32 位偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_m64_disp32(scc_mcode_t *mcode, - int dst, int base, - u32 disp) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8D); - u8 modrm = 0x80 | (base & 7) | ((dst & 7) << 3); // mod=10 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } - scc_mcode_add_u32(mcode, disp); -} - -// ---------- 32 位 ---------- - -/** - * @brief 32 位寄存器之间传送 (mov r32, r32) 高 32 位清零 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器(低 32 位) - * @param src 源寄存器(低 32 位) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_r32(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; // REX.W=0 - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 将 32 位立即数移动到 32 位寄存器(高 32 位清零)(mov r32, imm32) - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_imm32(scc_mcode_t *mcode, int reg, - u32 imm) { - scc_mcode_amd64_mov_r64_imm32(mcode, reg, imm); // 与 64 位 imm32 版本相同 -} - -/** - * @brief 存储 32 位寄存器到 [base] (mov [base], r32) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m32_r32(scc_mcode_t *mcode, int base, - int src) { - u8 rex = 0x40; // REX.W=0 - if (src >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从 [base] 加载到 32 位寄存器 (mov r32, [base]) 高 32 位清零 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_m32(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x40; // REX.W=0 - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8B); - u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -// ---------- 16 位 ---------- - -/** - * @brief 16 位寄存器之间传送 (mov r16, r16) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器(低 16 位) - * @param src 源寄存器(低 16 位) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_r16(scc_mcode_t *mcode, int dst, - int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; // REX.W=0 - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 将 16 位立即数移动到 16 位寄存器 (mov r16, imm16) - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - * @param imm 16 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_imm16(scc_mcode_t *mcode, int reg, - u16 imm) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; // REX.W=0 - if (reg >= 8) { - rex |= 0x01; - reg -= 8; - } - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xB8 + reg); - scc_mcode_add_u16(mcode, imm); -} - -/** - * @brief 存储 16 位寄存器到 [base] (mov [base], r16) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m16_r16(scc_mcode_t *mcode, int base, - int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从 [base] 加载到 16 位寄存器 (mov r16, [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_m16(scc_mcode_t *mcode, int dst, - int base) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8B); - u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -// ---------- 8 位 ---------- - -/** - * @brief 检查 8 位寄存器是否需要 REX 前缀 - * - * 若寄存器编号为 4-7(SPL、BPL、SIL、DIL),必须使用 REX 前缀 - * - * @param reg 寄存器编号 - * @return 是否需要 REX 前缀 - */ -SCC_MCODE_FUNC int scc_mcode_amd64_is_byte_reg_needs_rex(int reg) { - return (reg >= 4 && reg <= 7) || reg >= 8; -} - -/** - * @brief 8 位寄存器之间传送 (mov r8, r8) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器(低 8 位) - * @param src 源寄存器(低 8 位) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || - scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x88); // MOV r/m8, r8 - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 将 8 位立即数移动到 8 位寄存器 (mov r8, imm8) - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - * @param imm 8 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_imm8(scc_mcode_t *mcode, int reg, - u8 imm) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(reg); - if (reg >= 8) { - rex |= 0x01; - reg -= 8; - } - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xB0 + reg); - scc_mcode_add_u8(mcode, imm); -} - -/** - * @brief 存储 8 位寄存器到 [base] (mov [base], r8) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m8_r8(scc_mcode_t *mcode, int base, - int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src) || - scc_mcode_amd64_is_byte_reg_needs_rex(base); - if (src >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x88); - u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从 [base] 加载到 8 位寄存器 (mov r8, [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_m8(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || - scc_mcode_amd64_is_byte_reg_needs_rex(base); - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x8A); - u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -// ---------- 符号/零扩展传送 ---------- - -/** - * @brief 符号扩展传送 (movsx r64, r/m8) - * - * @param mcode 机器码缓冲区 - * @param dst 64 位目标寄存器 - * @param src 8 位源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; // REX.W - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xBE); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 符号扩展传送 (movsx r64, r/m16) - * - * @param mcode 机器码缓冲区 - * @param dst 64 位目标寄存器 - * @param src 16 位源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r16(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xBF); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 符号扩展传送 (movsx r64, r/m32) - * - * @param mcode 机器码缓冲区 - * @param dst 64 位目标寄存器 - * @param src 32 位源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r32(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x63); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 零扩展传送 (movzx r64, r/m8) - * - * @param mcode 机器码缓冲区 - * @param dst 64 位目标寄存器 - * @param src 8 位源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xB6); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 零扩展传送 (movzx r64, r/m16) - * - * @param mcode 机器码缓冲区 - * @param dst 64 位目标寄存器 - * @param src 16 位源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_r16(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xB7); - u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); - scc_mcode_add_u8(mcode, modrm); -} - -// ==================== 符号/零扩展加载(内存操作数) ==================== - -/** - * @brief 从内存加载字节并符号扩展到 64 位 (movsx r64, byte ptr [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标 64 位寄存器 - * @param base 基址寄存器(存储地址) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m8(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; // REX.W = 1 - if (dst >= 8) - rex |= 0x04; // REX.R - if (base >= 8) - rex |= 0x01; // REX.B - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xBE); // MOVSX r64, r/m8 - u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7); - if ((base & 7) == 4) { - // 需要 SIB 字节 (base == RSP 或 R12) - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, 0x24); // SIB: [base] 无索引,base=4 - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从内存加载字节并零扩展到 64 位 (movzx r64, byte ptr [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标 64 位寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m8(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xB6); // MOVZX r64, r/m8 - u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7); - if ((base & 7) == 4) { - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, 0x24); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从内存加载16位并符号扩展到 64 位 (movsx r64, word ptr [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标 64 位寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m16(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xBF); // MOVSX r64, r/m16 - u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7); - if ((base & 7) == 4) { - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, 0x24); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从内存加载16位并零扩展到 64 位 (movzx r64, word ptr [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标 64 位寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m16(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xB7); // MOVZX r64, r/m16 - u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7); - if ((base & 7) == 4) { - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, 0x24); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 从内存加载32位并符号扩展到 64 位 (movsxd r64, dword ptr [base]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标 64 位寄存器 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m32(scc_mcode_t *mcode, int dst, - int base) { - u8 rex = 0x48; // REX.W = 1, 对应 MOVSXD - if (dst >= 8) - rex |= 0x04; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x63); // MOVSXD r64, r/m32 - u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7); - if ((base & 7) == 4) { - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, 0x24); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -// ==================== 算术运算 ==================== - -// ---------- 64 位 ---------- - -/** - * @brief 64 位加法 ADD r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x01); // ADD r/m, r - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位加法 ADD r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (0 << 3); // reg/opcode = 0 for ADD - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 64 位减法 SUB r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x29); // SUB r/m, r - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位减法 SUB r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (5 << 3); // reg/opcode = 5 for SUB - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 调整 RSP 专用减法 (sub rsp, imm32) - * - * @param mcode 机器码缓冲区 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_rsp_imm32(scc_mcode_t *mcode, u32 imm) { - scc_mcode_amd64_sub_r64_imm32(mcode, SCC_AMD64_RSP, imm); -} - -/** - * @brief 调整 RSP 专用加法 (add rsp, imm32) - * - * @param mcode 机器码缓冲区 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_rsp_imm32(scc_mcode_t *mcode, u32 imm) { - scc_mcode_amd64_add_r64_imm32(mcode, SCC_AMD64_RSP, imm); -} - -/** - * @brief 64 位比较 CMP r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 左操作数寄存器 - * @param src 右操作数寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x39); // CMP r/m, r - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位比较 CMP r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (7 << 3); // reg/opcode = 7 for CMP - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 两操作数有符号乘法 IMUL r64, r64 (r64 = r64 * r64) - * - * @param mcode 机器码缓冲区 - * @param dst 目标/左操作数寄存器 - * @param src 右操作数寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; // dst in reg field - if (src >= 8) - rex |= 0x01; // src in r/m field - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0xAF); - u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 三操作数有符号乘法 IMUL r64, r/m64, imm32 (r64 = r/m64 * imm32) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器或内存(此处为寄存器版本) - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64_imm32(scc_mcode_t *mcode, - int dst, int src, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x69); - u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 三操作数有符号乘法 IMUL r64, r/m64, imm8 (符号扩展) (r64 = r/m64 * - * imm8) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器或内存(此处为寄存器版本) - * @param imm 8 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64_imm8(scc_mcode_t *mcode, - int dst, int src, - u8 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x6B); - u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, imm); -} - -// ---------- 32 位 ---------- - -/** - * @brief 32 位加法 ADD r32, r32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r32_r32(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; // REX.W=0 - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x01); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 32 位加法 ADD r32, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r32_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x40; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (0 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 32 位减法 SUB r32, r32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_r32_r32(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x29); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 32 位比较 CMP r32, r32 - * - * @param mcode 机器码缓冲区 - * @param dst 左操作数寄存器 - * @param src 右操作数寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r32_r32(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x39); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ---------- 16 位 ---------- - -/** - * @brief 16 位加法 ADD r16, r16 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r16_r16(scc_mcode_t *mcode, int dst, - int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x01); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 16 位加法 ADD r16, imm16 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 16 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r16_imm16(scc_mcode_t *mcode, int dst, - u16 imm) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (0 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u16(mcode, imm); -} - -/** - * @brief 16 位减法 SUB r16, r16 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_r16_r16(scc_mcode_t *mcode, int dst, - int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x29); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 16 位比较 CMP r16, r16 - * - * @param mcode 机器码缓冲区 - * @param dst 左操作数寄存器 - * @param src 右操作数寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r16_r16(scc_mcode_t *mcode, int dst, - int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x39); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ---------- 8 位 ---------- - -/** - * @brief 8 位加法 ADD r8, r8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r8_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || - scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x00); // ADD r/m8, r8 - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 8 位加法 ADD r8, imm8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 8 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_add_r8_imm8(scc_mcode_t *mcode, int dst, - u8 imm) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst); - if (dst >= 8) { - rex |= 0x01; - dst -= 8; - } - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x80); // ADD r/m8, imm8 - u8 modrm = 0xC0 | (dst & 7) | (0 << 3); // reg/opcode = 0 for ADD - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, imm); -} - -/** - * @brief 8 位减法 SUB r8, r8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sub_r8_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || - scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x28); // SUB r/m8, r8 - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 8 位比较 CMP r8, r8 - * - * @param mcode 机器码缓冲区 - * @param dst 左操作数寄存器 - * @param src 右操作数寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r8_r8(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || - scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x38); // CMP r/m8, r8 - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ==================== 单操作数乘除 ==================== - -// ---------- 无符号乘法 MUL ---------- - -/** - * @brief 无符号乘法 MUL r/m64 (RDX:RAX = RAX * r/m64) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mul_r64(scc_mcode_t *mcode, int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (4 << 3); // reg/opcode = 4 for MUL - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号乘法 MUL r/m32 (EDX:EAX = EAX * r/m32) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mul_r32(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号乘法 MUL r/m16 (DX:AX = AX * r/m16) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mul_r16(scc_mcode_t *mcode, int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号乘法 MUL r/m8 (AX = AL * r/m8) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mul_r8(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xF6); - u8 modrm = 0xC0 | (src & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ---------- 有符号乘法 IMUL (单操作数) ---------- - -/** - * @brief 有符号乘法 IMUL r/m64 (RDX:RAX = RAX * r/m64) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_1op(scc_mcode_t *mcode, int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (5 << 3); // reg/opcode = 5 for IMUL - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号乘法 IMUL r/m32 (EDX:EAX = EAX * r/m32) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r32_1op(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (5 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号乘法 IMUL r/m16 (DX:AX = AX * r/m16) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r16_1op(scc_mcode_t *mcode, int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (5 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号乘法 IMUL r/m8 (AX = AL * r/m8) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_imul_r8_1op(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xF6); - u8 modrm = 0xC0 | (src & 7) | (5 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ---------- 无符号除法 DIV ---------- - -/** - * @brief 无符号除法 DIV r/m64 (RDX:RAX / r/m64, 商 RAX, 余 RDX) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_div_r64(scc_mcode_t *mcode, int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (6 << 3); // reg/opcode = 6 for DIV - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号除法 DIV r/m32 (EDX:EAX / r/m32, 商 EAX, 余 EDX) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_div_r32(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (6 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号除法 DIV r/m16 (DX:AX / r/m16, 商 AX, 余 DX) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_div_r16(scc_mcode_t *mcode, int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (6 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 无符号除法 DIV r/m8 (AX / r/m8, 商 AL, 余 AH) - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_div_r8(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xF6); - u8 modrm = 0xC0 | (src & 7) | (6 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ---------- 有符号除法 IDIV ---------- - -/** - * @brief 有符号除法 IDIV r/m64 - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r64(scc_mcode_t *mcode, int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (7 << 3); // reg/opcode = 7 for IDIV - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号除法 IDIV r/m32 - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r32(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (7 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号除法 IDIV r/m16 - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r16(scc_mcode_t *mcode, int src) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (src >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (src & 7) | (7 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 有符号除法 IDIV r/m8 - * - * @param mcode 机器码缓冲区 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r8(scc_mcode_t *mcode, int src) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); - if (src >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xF6); - u8 modrm = 0xC0 | (src & 7) | (7 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -// ==================== 按位逻辑 ==================== - -// 仅提供 64 位和 32 位示例,其他宽度可仿照上述模式自行扩展 - -/** - * @brief 64 位与 AND r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_and_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x21); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位与 AND r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_and_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 64 位或 OR r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_or_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x09); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位或 OR r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_or_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (1 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 64 位异或 XOR r64, r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_xor_r64_r64(scc_mcode_t *mcode, int dst, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x31); - u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位异或 XOR r64, imm32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 32 位立即数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_xor_r64_imm32(scc_mcode_t *mcode, int dst, - u32 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x81); - u8 modrm = 0xC0 | (dst & 7) | (6 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u32(mcode, imm); -} - -/** - * @brief 64 位按位取反 NOT r64 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_not_r64(scc_mcode_t *mcode, int dst) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 32 位按位取反 NOT r32 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_not_r32(scc_mcode_t *mcode, int dst) { - u8 rex = 0x40; // REX.W=0 - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 16 位按位取反 NOT r16 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_not_r16(scc_mcode_t *mcode, int dst) { - scc_mcode_amd64_emit_width_prefix(mcode, 2); - u8 rex = 0x40; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xF7); - u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 8 位按位取反 NOT r8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_not_r8(scc_mcode_t *mcode, int dst) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst); - if (dst >= 8) - rex |= 0x01; - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0xF6); // 8位版本使用0xF6 - u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT - scc_mcode_add_u8(mcode, modrm); -} - -// ==================== 移位 ==================== - -// 提供 64 位示例,其他宽度可类似添加 - -/** - * @brief 64 位左移 SHL r64, 1 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_shl_r64_1(scc_mcode_t *mcode, int dst) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xD1); - u8 modrm = 0xC0 | (dst & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位左移 SHL r64, imm8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 移位次数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_shl_r64_imm8(scc_mcode_t *mcode, int dst, - u8 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xC1); - u8 modrm = 0xC0 | (dst & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, imm); -} - -/** - * @brief 64 位右移 SHR r64, 1 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_shr_r64_1(scc_mcode_t *mcode, int dst) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xD1); - u8 modrm = 0xC0 | (dst & 7) | (5 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位右移 SHR r64, imm8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 移位次数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_shr_r64_imm8(scc_mcode_t *mcode, int dst, - u8 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xC1); - u8 modrm = 0xC0 | (dst & 7) | (5 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, imm); -} - -/** - * @brief 64 位算术右移 SAR r64, 1 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sar_r64_1(scc_mcode_t *mcode, int dst) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xD1); - u8 modrm = 0xC0 | (dst & 7) | (7 << 3); - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 64 位算术右移 SAR r64, imm8 - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param imm 移位次数 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_sar_r64_imm8(scc_mcode_t *mcode, int dst, - u8 imm) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xC1); - u8 modrm = 0xC0 | (dst & 7) | (7 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, imm); -} - -// ==================== 条件设置 ==================== - -/** - * @brief 根据条件码设置字节寄存器 (setcc r8) - * - * @param mcode 机器码缓冲区 - * @param cond 条件码(0-15) - * @param reg 目标 8 位寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_setcc_r8(scc_mcode_t *mcode, int cond, - int reg) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(reg); - if (reg >= 8) { - rex |= 0x01; - reg -= 8; - } - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0x90 + cond); - u8 modrm = 0xC0 | (reg & 7); // reg/opcode 字段未使用 - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 根据条件码设置内存字节 (setcc [base]) - * - * @param mcode 机器码缓冲区 - * @param cond 条件码 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_setcc_m8(scc_mcode_t *mcode, int cond, - int base) { - u8 rex = 0x40; - int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(base); - if (base >= 8) { - rex |= 0x01; - base -= 8; - } - if (need_rex) { - scc_mcode_add_u8(mcode, rex); - } - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0x90 + cond); - u8 modrm = 0x00 | (base & 7); // mod=00, reg 字段未使用(置0) - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -// ==================== 控制转移 ==================== - -/** - * @brief 相对跳转 JMP rel32 - * - * @param mcode 机器码缓冲区 - * @param rel32 32 位相对偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_jmp_rel32(scc_mcode_t *mcode, u32 rel32) { - scc_mcode_add_u8(mcode, 0xE9); - scc_mcode_add_u32(mcode, rel32); -} - -/** - * @brief 条件跳转 Jcc rel32 - * - * @param mcode 机器码缓冲区 - * @param cond 条件码 - * @param rel32 32 位相对偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_jcc_rel32(scc_mcode_t *mcode, int cond, - u32 rel32) { - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0x80 + cond); - scc_mcode_add_u32(mcode, rel32); -} - -/** - * @brief 相对调用 CALL rel32 - * - * @param mcode 机器码缓冲区 - * @param rel32 32 位相对偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_call_rel32(scc_mcode_t *mcode, u32 rel32) { - scc_mcode_add_u8(mcode, 0xE8); - scc_mcode_add_u32(mcode, rel32); -} - -/** - * @brief 通过内存地址调用 (call [rip+disp32]) - 通常用于导入表调用 - * - * @param mcode 机器码缓冲区 - * @param disp 32 位相对偏移 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_call_mem_rip_rel32(scc_mcode_t *mcode, - u32 disp) { - scc_mcode_add_u8(mcode, 0xFF); - scc_mcode_add_u8(mcode, 0x15); // reg=010 (CALL), r/m=101 (RIP+disp32) - scc_mcode_add_u32(mcode, disp); -} - -/** - * @brief 间接跳转 JMP r64 - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器(存储跳转地址) - */ -SCC_MCODE_FUNC void scc_mcode_amd64_jmp_r64(scc_mcode_t *mcode, int reg) { - u8 rex = 0x40; - if (reg >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xFF); - u8 modrm = 0xC0 | (reg & 7) | (4 << 3); // reg/opcode = 4 for JMP r/m64 - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 间接跳转 JMP [base] (简单基址) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_jmp_m64(scc_mcode_t *mcode, int base) { - u8 rex = 0x48; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xFF); - u8 modrm = (base & 7) | (4 << 3); // mod=00, reg/opcode=4 - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 间接调用 CALL r64 - * - * @param mcode 机器码缓冲区 - * @param reg 目标寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_call_r64(scc_mcode_t *mcode, int reg) { - u8 rex = 0x40; - if (reg >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xFF); - u8 modrm = 0xC0 | (reg & 7) | (2 << 3); // reg/opcode = 2 for CALL r/m64 - scc_mcode_add_u8(mcode, modrm); -} - -/** - * @brief 间接调用 CALL [base] - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_call_m64(scc_mcode_t *mcode, int base) { - u8 rex = 0x48; - if (base >= 8) - rex |= 0x01; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0xFF); - u8 modrm = (base & 7) | (2 << 3); - if ((base & 7) == 4) { - u8 sib = (base & 7) | (4 << 3); - scc_mcode_add_u8(mcode, modrm); - scc_mcode_add_u8(mcode, sib); - } else { - scc_mcode_add_u8(mcode, modrm); - } -} - -/** - * @brief 返回指令 RET - * - * @param mcode 机器码缓冲区 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_ret(scc_mcode_t *mcode) { - scc_mcode_add_u8(mcode, 0xC3); -} - -// ==================== 系统调用 ==================== - -/** - * @brief 执行系统调用 SYSCALL - * - * @param mcode 机器码缓冲区 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_syscall(scc_mcode_t *mcode) { - scc_mcode_add_u8(mcode, 0x0F); - scc_mcode_add_u8(mcode, 0x05); -} - -// ==================== 复杂寻址模式(SIB) ==================== - -// 辅助函数:根据 base, index, scale, disp 生成 ModRM 和 SIB 字节并写入 -// 返回需要写入 disp 的字节数(0,1,4),调用者需写入 disp - -SCC_MCODE_FUNC int scc_mcode_amd64_emit_sib_address(scc_mcode_t *mcode, - int base, int index, - int scale, u32 disp, - int has_disp, int disp8) { - // scale 编码: 0=1, 1=2, 2=4, 3=8 - u8 scale_code = 0; - switch (scale) { - case 1: - scale_code = 0; - break; - case 2: - scale_code = 1; - break; - case 4: - scale_code = 2; - break; - case 8: - scale_code = 3; - break; - default: - break; // 非法,但默认 0 - } - u8 index_reg = (index == -1) ? 4 : (index & 7); // 4 表示无 index - u8 base_reg = (base == -1) ? 5 : (base & 7); - - u8 mod = 0; - int disp_size = 0; - if (base == -1) { - // 无基址,只有 index*scale + disp32 - mod = 0; - base_reg = 5; // 必须为 101 - disp_size = 4; - } else { - if (!has_disp) { - mod = 0; - disp_size = 0; - } else if (disp8 && (disp <= 127 || (int)disp >= -128)) { - mod = 1; - disp_size = 1; - } else { - mod = 2; - disp_size = 4; - } - } - - u8 modrm = (mod << 6) | (0 << 3) | 4; // reg 字段为 0(调用者会覆盖) - scc_mcode_add_u8(mcode, modrm); - - u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; - scc_mcode_add_u8(mcode, sib); - - return disp_size; -} - -// 示例:带 SIB 的 MOV r64, [base+index*scale+disp32] - -// /** -// * @brief 从复杂地址加载到 64 位寄存器 (mov r64, [base + index*scale + disp]) -// * -// * @param mcode 机器码缓冲区 -// * @param dst 目标寄存器 -// * @param base 基址寄存器(-1 表示无基址) -// * @param index 索引寄存器(-1 表示无索引) -// * @param scale 比例因子(1,2,4,8) -// * @param disp 位移量 -// * @param disp_size 位移大小(0=无位移,1=8位,4=32位) -// */ -// SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_sib(scc_mcode_t *mcode, int -// dst, -// int base, int index, int -// scale, u32 disp, int -// disp_size) { -// u8 rex = 0x48; -// if (dst >= 8) -// rex |= 0x04; -// if (base >= 8 && base != -1) -// rex |= 0x01; -// if (index >= 8 && index != -1) -// rex |= 0x02; // REX.X -// scc_mcode_add_u8(mcode, rex); -// scc_mcode_add_u8(mcode, 0x8B); - -// // 保存 ModRM 的 reg 字段为 dst -// u8 modrm_byte = (dst & 7) << 3; -// // 临时占位,实际 mod 和 rm 由 sib 函数决定 -// // 我们先写入一个占位,稍后修改?为了方便,我们重写逻辑:直接调用 sib -// // 函数后,在适当位置写入 reg 字段? 更简单:构建 modrm 时,reg -// // 已知,我们可以在 sib 函数中传入 reg 参数。 重新设计:让 sib 函数返回 -// // modrm 和 sib 的字节,然后我们组合。 -// } - -// 为了简化,我们直接实现一个完整版本,不拆分辅助函数: - -/** - * @brief 从复杂地址加载到 64 位寄存器 (mov r64, [base + index*scale + disp]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器(-1 表示无基址) - * @param index 索引寄存器(-1 表示无索引) - * @param scale 比例因子(1,2,4,8) - * @param disp 位移量 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_sib(scc_mcode_t *mcode, int dst, - int base, int index, - int scale, u32 disp) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8 && base != -1) - rex |= 0x01; - if (index >= 8 && index != -1) - rex |= 0x02; // REX.X - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8B); - - int has_disp = (base != -1) ? 1 : 0; // 无基址时必须带 disp32 - int disp_size = 4; - if (base != -1) { - if (disp == 0) { - has_disp = 0; - disp_size = 0; - } else { - // 可添加 disp8 优化,但此处统一 disp32 - disp_size = 4; - } - } - - u8 scale_code = 0; - switch (scale) { - case 1: - scale_code = 0; - break; - case 2: - scale_code = 1; - break; - case 4: - scale_code = 2; - break; - case 8: - scale_code = 3; - break; - default: - scale_code = 0; - break; - } - u8 index_reg = (index == -1) ? 4 : (index & 7); - u8 base_reg = (base == -1) ? 5 : (base & 7); - - u8 mod = 0; - if (base == -1) { - mod = 0; - base_reg = 5; - disp_size = 4; - } else { - if (!has_disp) { - mod = 0; - } else { - mod = 2; // 强制 disp32 - } - } - - u8 modrm = (mod << 6) | ((dst & 7) << 3) | 4; // rm=4 表示使用 SIB - scc_mcode_add_u8(mcode, modrm); - - u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; - scc_mcode_add_u8(mcode, sib); - - if (disp_size == 4) { - scc_mcode_add_u32(mcode, disp); - } else if (disp_size == 1) { - scc_mcode_add_u8(mcode, (u8)disp); - } - // 无位移则不添加 -} - -/** - * @brief 存储 64 位寄存器到复杂地址 (mov [base+index*scale+disp], r64) - * - * @param mcode 机器码缓冲区 - * @param base 基址寄存器(-1 表示无基址) - * @param index 索引寄存器(-1 表示无索引) - * @param scale 比例因子 - * @param disp 位移量 - * @param src 源寄存器 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_sib_r64(scc_mcode_t *mcode, - int base, int index, - int scale, u32 disp, - int src) { - u8 rex = 0x48; - if (src >= 8) - rex |= 0x04; - if (base >= 8 && base != -1) - rex |= 0x01; - if (index >= 8 && index != -1) - rex |= 0x02; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x89); - - int has_disp = (base != -1) ? 1 : 0; - int disp_size = 4; - if (base != -1) { - if (disp == 0) { - has_disp = 0; - disp_size = 0; - } else { - disp_size = 4; - } - } - - u8 scale_code = 0; - switch (scale) { - case 1: - scale_code = 0; - break; - case 2: - scale_code = 1; - break; - case 4: - scale_code = 2; - break; - case 8: - scale_code = 3; - break; - default: - scale_code = 0; - break; - } - u8 index_reg = (index == -1) ? 4 : (index & 7); - u8 base_reg = (base == -1) ? 5 : (base & 7); - - u8 mod = 0; - if (base == -1) { - mod = 0; - base_reg = 5; - disp_size = 4; - } else { - if (!has_disp) { - mod = 0; - } else { - mod = 2; - } - } - - u8 modrm = (mod << 6) | ((src & 7) << 3) | 4; - scc_mcode_add_u8(mcode, modrm); - - u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; - scc_mcode_add_u8(mcode, sib); - - if (disp_size == 4) { - scc_mcode_add_u32(mcode, disp); - } else if (disp_size == 1) { - scc_mcode_add_u8(mcode, (u8)disp); - } -} - -/** - * @brief 加载有效地址到 64 位寄存器 (lea r64, [base+index*scale+disp]) - * - * @param mcode 机器码缓冲区 - * @param dst 目标寄存器 - * @param base 基址寄存器(-1 允许) - * @param index 索引寄存器(-1 允许) - * @param scale 比例因子 - * @param disp 位移量 - */ -SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_m64_sib(scc_mcode_t *mcode, int dst, - int base, int index, - int scale, u32 disp) { - u8 rex = 0x48; - if (dst >= 8) - rex |= 0x04; - if (base >= 8 && base != -1) - rex |= 0x01; - if (index >= 8 && index != -1) - rex |= 0x02; - scc_mcode_add_u8(mcode, rex); - scc_mcode_add_u8(mcode, 0x8D); - - int has_disp = (base != -1) ? 1 : 0; - int disp_size = 4; - if (base != -1) { - if (disp == 0) { - has_disp = 0; - disp_size = 0; - } else { - disp_size = 4; - } - } - - u8 scale_code = 0; - switch (scale) { - case 1: - scale_code = 0; - break; - case 2: - scale_code = 1; - break; - case 4: - scale_code = 2; - break; - case 8: - scale_code = 3; - break; - default: - scale_code = 0; - break; - } - u8 index_reg = (index == -1) ? 4 : (index & 7); - u8 base_reg = (base == -1) ? 5 : (base & 7); - - u8 mod = 0; - if (base == -1) { - mod = 0; - base_reg = 5; - disp_size = 4; - } else { - if (!has_disp) { - mod = 0; - } else { - mod = 2; - } - } - - u8 modrm = (mod << 6) | ((dst & 7) << 3) | 4; - scc_mcode_add_u8(mcode, modrm); - - u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; - scc_mcode_add_u8(mcode, sib); - - if (disp_size == 4) { - scc_mcode_add_u32(mcode, disp); - } else if (disp_size == 1) { - scc_mcode_add_u8(mcode, (u8)disp); - } -} - -#endif /* __SCC_MCODE_AMD64_H__ */ diff --git a/src/main.c b/src/main.c index 504b748..4d03e82 100644 --- a/src/main.c +++ b/src/main.c @@ -3,12 +3,12 @@ #include #include -#include -#include #include +#include +#include +#include +#include -// #include -// #include // #include // #include @@ -231,7 +231,7 @@ sstream_drop: } else { scc_tree_dump_init(&tree_dump, false); } - scc_hir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &cprog); + scc_hir_dump_init(&ir_dump_ctx, &tree_dump, &cprog); // scc_ir_dump_cprog(&ir_dump_ctx); scc_hir_dump_cprog_linear(&ir_dump_ctx); @@ -241,28 +241,26 @@ sstream_drop: return 0; } - // scc_lir_builder_t lir_builder; - // scc_lir_module_t lir_module; - // scc_lir_module_init(&lir_module); - // scc_lir_builder_init(&lir_builder, &lir_module); - // scc_ir2lir(&lir_builder, &cprog); - // if (config.emit_lir) { - // scc_lir_dump_ctx_t lir_dump_ctx; - // scc_tree_dump_t tree_dump; - // if (fp == nullptr) { - // scc_tree_dump_init(&tree_dump, true); - // } else { - // scc_tree_dump_init(&tree_dump, false); - // } - // scc_lir_dump_init(&lir_dump_ctx, &tree_dump); - // // scc_ir_dump_cprog(&ir_dump_ctx); - // scc_lir_dump_module(&lir_dump_ctx, &lir_module); + scc_lir_module_t lir_module; + scc_lir_module_init(&lir_module); + scc_hir2lir(&lir_module, &cprog); + if (config.emit_lir) { + scc_lir_dump_ctx_t lir_dump_ctx; + scc_tree_dump_t tree_dump; + if (fp == nullptr) { + scc_tree_dump_init(&tree_dump, true); + } else { + scc_tree_dump_init(&tree_dump, false); + } + scc_lir_dump_init(&lir_dump_ctx, &tree_dump, &lir_module); + // scc_ir_dump_cprog(&ir_dump_ctx); + scc_lir_dump_module(&lir_dump_ctx); - // scc_tree_dump_flush(&tree_dump, tree_dump_output, - // fp == nullptr ? scc_stdout : fp); - // scc_tree_dump_drop(&tree_dump); - // return 0; - // } + scc_tree_dump_flush(&tree_dump, tree_dump_output, + fp == nullptr ? scc_stdout : fp); + scc_tree_dump_drop(&tree_dump); + return 0; + } // scc_ir2mcode_ctx_t ir2mcode_ctx; // sccf_builder_t sccf_builder;