refactor(ast2ir): 提取模块访问函数并优化类型大小计算
- 添加 scc_ast2ir_mir_module 内联函数统一访问模块 - 替换所有直接访问 ctx->builder.cprog->module 的地方 - 移除重复的 scc_hir_type_size 函数实现 - 添加 scc_hir_module_type_size 函数到模块接口 - 更新所有类型大小计算调用使用新函数 feat(hir): 增强构建器安全性和全局变量处理 - 为 scc_hir_builder_integer 添加空指针检查断言 - 修复 scc_hir_builder_global_alloca 中全局变量类型设置 - 改进 scc_hir_builder_get_elem_ptr 处理空指针索引情况 - 重构字符串常量生成使用 get_elem_ptr 构建器函数 refactor(lir): 简化地址表达式表示并增强内置函数支持 - 移除复杂地址结构体 scc_lir_addr_t - 简化 scc_lir_instr 结构体中的地址表示 - 移除 STORE_ADDR 操作码 - 添加 memcpy 和 memset 内置函数操作码 - 在符号元数据中使用联合体替代嵌套结构体 feat(hir2lir): 完善 HIR 到 LIR 转换中的内置函数处理 - 添加 ensure_vreg 辅助函数确保虚拟寄存器操作数 - 正确处理全局变量地址符号引用 - 优化 GET_ELEM_PTR 转换使用类型大小计算 - 完整实现所有内置函数(BUILTIN)的 LIR 转换 - 包括 memcpy、memset、va_start、va_arg、va_end、va_copy 等
This commit is contained in:
@@ -12,76 +12,76 @@ typedef SCC_VEC(u8) scc_mcode_buff_t;
|
||||
typedef struct {
|
||||
cbool is_littel_endian;
|
||||
scc_mcode_arch_t arch;
|
||||
scc_mcode_buff_t mcode;
|
||||
scc_mcode_buff_t code;
|
||||
} scc_mcode_t;
|
||||
|
||||
static inline void scc_mcode_init(scc_mcode_t *mcode, scc_mcode_arch_t arch) {
|
||||
scc_vec_init(mcode->mcode);
|
||||
scc_vec_init(mcode->code);
|
||||
mcode->arch = arch;
|
||||
mcode->is_littel_endian = true;
|
||||
}
|
||||
|
||||
static inline char *scc_mcode_unsafe_data(scc_mcode_t *mcode) {
|
||||
return (char *)scc_vec_unsafe_get_data(mcode->mcode);
|
||||
return (char *)scc_vec_unsafe_get_data(mcode->code);
|
||||
}
|
||||
|
||||
static inline usize scc_mcode_size(scc_mcode_t *mcode) {
|
||||
return scc_vec_size(mcode->mcode);
|
||||
return scc_vec_size(mcode->code);
|
||||
}
|
||||
|
||||
static inline void scc_mcode_drop(scc_mcode_t *mcode) {
|
||||
scc_vec_free(mcode->mcode);
|
||||
scc_vec_free(mcode->code);
|
||||
mcode->arch = SCC_MCODE_ARCH_NONE;
|
||||
mcode->is_littel_endian = true;
|
||||
}
|
||||
|
||||
static inline void scc_mcode_add_u8(scc_mcode_t *mcode, u8 data) {
|
||||
scc_vec_push(mcode->mcode, data);
|
||||
scc_vec_push(mcode->code, data);
|
||||
}
|
||||
|
||||
static inline void scc_mcode_add_u16(scc_mcode_t *mcode, u16 data) {
|
||||
if (mcode->is_littel_endian) {
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
} else {
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scc_mcode_add_u32(scc_mcode_t *mcode, u32 data) {
|
||||
if (mcode->is_littel_endian) {
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 24));
|
||||
} else {
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scc_mcode_add_u64(scc_mcode_t *mcode, uint64_t data) {
|
||||
if (mcode->is_littel_endian) {
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 32));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 40));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 48));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 56));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 32));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 40));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 48));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 56));
|
||||
} else {
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 56));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 48));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 40));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 32));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->mcode, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->mcode, (u8)(data & 0xFF));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 56));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 48));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 40));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 32));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 24));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 16));
|
||||
scc_vec_push(mcode->code, (u8)(data >> 8));
|
||||
scc_vec_push(mcode->code, (u8)(data & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,16 +45,21 @@ typedef struct {
|
||||
scc_x86_mem_t mem;
|
||||
scc_x86_reloc_op_t reloc;
|
||||
};
|
||||
usize size;
|
||||
} scc_x86_operand_value_t;
|
||||
|
||||
static inline scc_x86_operand_value_t scc_x86_op_preg(scc_x86_reg_t reg) {
|
||||
scc_x86_operand_value_t o = {.kind = SCC_X86_OPR_REG, .reg = reg};
|
||||
return o;
|
||||
}
|
||||
static inline scc_x86_reg_t scc_x86_op_vreg_reg(int vreg) {
|
||||
return (int)SCC_X86_REG_COUNT + vreg;
|
||||
}
|
||||
static inline scc_x86_operand_value_t scc_x86_op_vreg(int vreg) {
|
||||
scc_x86_operand_value_t o = {
|
||||
.kind = SCC_X86_OPR_REG,
|
||||
.reg = (scc_x86_reg_t)((int)SCC_X86_REG_COUNT + vreg)};
|
||||
.reg = scc_x86_op_vreg_reg(vreg),
|
||||
};
|
||||
return o;
|
||||
}
|
||||
static inline scc_x86_operand_value_t scc_x86_op_relbr(i32 rel) {
|
||||
@@ -81,6 +86,16 @@ scc_x86_op_reloc_global_imm(const char *sym, i64 addend) {
|
||||
return op;
|
||||
}
|
||||
|
||||
static inline scc_x86_operand_value_t
|
||||
scc_x86_op_reloc_global_relrip(const char *sym, i64 addend) {
|
||||
scc_x86_operand_value_t op = {.kind = SCC_X86_OPR_RELOC};
|
||||
op.reloc.kind = SCC_X86_OPR_MEM;
|
||||
op.reloc.target = SCC_X86_RELOC_TARGET_SYMBOL;
|
||||
op.reloc.global_name = sym;
|
||||
op.reloc.addend = addend;
|
||||
return op;
|
||||
}
|
||||
|
||||
// 2. 全局符号重定位(相对跳转/调用:CALL/JMP rel32)
|
||||
static inline scc_x86_operand_value_t
|
||||
scc_x86_op_reloc_global_relbr(const char *sym, i64 addend) {
|
||||
|
||||
@@ -23,8 +23,6 @@ static inline void patch_bytes(scc_mcode_t *mcode, usize offset,
|
||||
scc_memcpy(buf + offset, data, size);
|
||||
}
|
||||
|
||||
/* ---------- 实现补丁接口 ---------- */
|
||||
|
||||
static inline int scc_x86_patch_disp(scc_mcode_t *mcode, usize offset,
|
||||
scc_x86_disp_t disp) {
|
||||
if (!mcode || disp.displacement_bits == 0)
|
||||
|
||||
@@ -37,11 +37,19 @@ static inline int scc_reg_ordinal(scc_x86_reg_t reg) {
|
||||
static int reg_low3(scc_x86_reg_t reg) {
|
||||
if (reg == SCC_X86_REG_INVALID)
|
||||
return 0;
|
||||
// RIP/EIP/IP 必须返回 5,否则无法编码 RIP 相对寻址
|
||||
if (reg == SCC_X86_REG_RIP || reg == SCC_X86_REG_EIP ||
|
||||
reg == SCC_X86_REG_IP)
|
||||
return 5;
|
||||
return scc_reg_ordinal(reg) & 7;
|
||||
}
|
||||
static int reg_rex_bit(scc_x86_reg_t reg) {
|
||||
if (reg == SCC_X86_REG_INVALID)
|
||||
return 0;
|
||||
// RIP 不需要 REX 扩展
|
||||
if (reg == SCC_X86_REG_RIP || reg == SCC_X86_REG_EIP ||
|
||||
reg == SCC_X86_REG_IP)
|
||||
return 0;
|
||||
if (reg >= SCC_X86_REG_AH && reg <= SCC_X86_REG_DH)
|
||||
return 0;
|
||||
return (scc_reg_ordinal(reg) >= 8) ? 1 : 0;
|
||||
@@ -138,9 +146,11 @@ static void emit_legacy_prefixes(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
|
||||
static void emit_rex(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
scc_x86_reg_t reg_op, scc_x86_reg_t rm_op,
|
||||
scc_x86_reg_t base, scc_x86_reg_t idx) {
|
||||
scc_x86_reg_t base, scc_x86_reg_t idx,
|
||||
int op_width) { // 新增 op_width 参数
|
||||
int rex = 0x40;
|
||||
if (need_rexw(enc, reg_op, rm_op, base, idx))
|
||||
// 仅当 op_width == 64 时才考虑 REX.W
|
||||
if (op_width == 64 && need_rexw(enc, reg_op, rm_op, base, idx))
|
||||
rex |= 8;
|
||||
if (reg_op != SCC_X86_REG_INVALID && reg_rex_bit(reg_op))
|
||||
rex |= 4;
|
||||
@@ -154,7 +164,6 @@ static void emit_rex(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
emit_u8(m, (uint8_t)rex);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_escape_map(scc_mcode_t *m, const scc_x86_encoding_t *enc) {
|
||||
if (enc->map == 1) {
|
||||
emit_u8(m, 0x0F);
|
||||
@@ -196,15 +205,17 @@ static int scale_to_enc(uint8_t scale) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 修正:位移大小只由数值范围决定,与基址寄存器无关 */
|
||||
static int disp_size(int32_t disp, scc_x86_reg_t base) {
|
||||
if (disp == 0 && base != SCC_X86_REG_RBP && base != SCC_X86_REG_R13)
|
||||
(void)base;
|
||||
if (disp == 0)
|
||||
return 0;
|
||||
if (disp >= -128 && disp <= 127)
|
||||
return 8;
|
||||
return 32;
|
||||
}
|
||||
|
||||
/* ---------- 立即数发射(独立函数) ---------- */
|
||||
/* ---------- 立即数发射 ---------- */
|
||||
static void emit_immediate(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
const scc_x86_operand_t *tmpl, int imm_idx,
|
||||
int64_t imm_val, int op_width) {
|
||||
@@ -285,17 +296,58 @@ static void emit_modrm_sib_disp(scc_mcode_t *m,
|
||||
scc_reg_ordinal(reg_r), reg_b, scc_reg_ordinal(reg_b));
|
||||
|
||||
uint8_t modrm = 0;
|
||||
|
||||
if (has_mem) {
|
||||
// ========== RIP 相对寻址特殊处理 ==========
|
||||
if (memdesc.base == SCC_X86_REG_RIP &&
|
||||
memdesc.index == SCC_X86_REG_INVALID) {
|
||||
// RIP 相对:mod=00, r/m=101,位移固定 32 位
|
||||
if (reg_r != SCC_X86_REG_INVALID)
|
||||
modrm |= (reg_low3(reg_r) & 7) << 3;
|
||||
else if (enc->modrm_reg_fix >= 0)
|
||||
modrm |= (enc->modrm_reg_fix & 7) << 3;
|
||||
modrm |= 0x05; // r/m = 101
|
||||
emit_u8(m, modrm);
|
||||
// 写入 32 位位移(小端)
|
||||
int32_t disp32 = (int32_t)memdesc.disp.displacement;
|
||||
emit_u32(m, (uint32_t)disp32);
|
||||
// 处理立即数(如果有)
|
||||
if (imm_idx >= 0) {
|
||||
emit_immediate(m, enc, tmpl, imm_idx, imm_val, op_width);
|
||||
}
|
||||
return; // 已处理完,跳过后续 SIB/位移逻辑
|
||||
}
|
||||
// ==========================================
|
||||
|
||||
if (reg_r != SCC_X86_REG_INVALID)
|
||||
modrm |= (reg_low3(reg_r) & 7) << 3;
|
||||
else if (enc->modrm_reg_fix >= 0)
|
||||
modrm |= (enc->modrm_reg_fix & 7) << 3;
|
||||
|
||||
int32_t disp = memdesc.disp.displacement;
|
||||
int dsize = disp_size(disp, memdesc.base);
|
||||
modrm |= (dsize == 0) ? 0 : (dsize == 8) ? 0x40 : 0x80;
|
||||
// 优先使用用户指定的 displacement_bits,转换为字节数
|
||||
int dsize = 0;
|
||||
if (memdesc.disp.displacement_bits != 0) {
|
||||
dsize = memdesc.disp.displacement_bits / 8;
|
||||
if (dsize != 1 && dsize != 2 && dsize != 4 && dsize != 8)
|
||||
dsize = 0; // 无效则回退
|
||||
}
|
||||
if (dsize == 0) {
|
||||
// 使用自动计算:disp_size 返回位数,除以 8 得字节数
|
||||
int bits = disp_size(disp, memdesc.base);
|
||||
dsize = bits / 8;
|
||||
}
|
||||
|
||||
// 设置 ModRM 的 mod 字段
|
||||
if (dsize == 0)
|
||||
modrm |= 0x00;
|
||||
else if (dsize == 1)
|
||||
modrm |= 0x40;
|
||||
else if (dsize == 2 || dsize == 4 || dsize == 8)
|
||||
modrm |= 0x80; // 2/4/8 字节位移均使用 mod=10b
|
||||
|
||||
if (memdesc.index != SCC_X86_REG_INVALID) {
|
||||
// SIB 寻址
|
||||
modrm |= 4;
|
||||
int idx_ord = scc_reg_ordinal(memdesc.index);
|
||||
int base_ord = scc_reg_ordinal(memdesc.base);
|
||||
@@ -306,45 +358,57 @@ static void emit_modrm_sib_disp(scc_mcode_t *m,
|
||||
(base_ord & 7));
|
||||
emit_u8(m, modrm);
|
||||
emit_u8(m, sib);
|
||||
if (dsize == 8)
|
||||
if (dsize == 1)
|
||||
emit_u8(m, (uint8_t)disp);
|
||||
else if (dsize == 32)
|
||||
else if (dsize == 2)
|
||||
emit_u16(m, (uint16_t)disp);
|
||||
else if (dsize == 4)
|
||||
emit_u32(m, (uint32_t)disp);
|
||||
else if (dsize == 8)
|
||||
emit_u64(m, (uint64_t)disp);
|
||||
} else if (memdesc.base == SCC_X86_REG_INVALID) {
|
||||
// 绝对地址:mod=00, r/m=101,位移 32 位
|
||||
modrm |= 5;
|
||||
emit_u8(m, modrm);
|
||||
emit_u32(m, (uint32_t)disp);
|
||||
} else {
|
||||
// 一般基址寻址
|
||||
int base_ord = scc_reg_ordinal(memdesc.base);
|
||||
if (memdesc.base == SCC_X86_REG_RSP ||
|
||||
memdesc.base == SCC_X86_REG_R12) {
|
||||
// 需要 SIB(基址为 RSP/R12 时强制)
|
||||
modrm |= 4;
|
||||
uint8_t sib = (uint8_t)((base_ord & 7) | (4 << 3));
|
||||
emit_u8(m, modrm);
|
||||
emit_u8(m, sib);
|
||||
if (dsize == 8)
|
||||
if (dsize == 1)
|
||||
emit_u8(m, (uint8_t)disp);
|
||||
else if (dsize == 32)
|
||||
else if (dsize == 2)
|
||||
emit_u16(m, (uint16_t)disp);
|
||||
else if (dsize == 4)
|
||||
emit_u32(m, (uint32_t)disp);
|
||||
else if (dsize == 8)
|
||||
emit_u64(m, (uint64_t)disp);
|
||||
} else {
|
||||
modrm |= (base_ord & 7);
|
||||
emit_u8(m, modrm);
|
||||
if (dsize == 8)
|
||||
if (dsize == 1)
|
||||
emit_u8(m, (uint8_t)disp);
|
||||
else if (dsize == 32)
|
||||
else if (dsize == 2)
|
||||
emit_u16(m, (uint16_t)disp);
|
||||
else if (dsize == 4)
|
||||
emit_u32(m, (uint32_t)disp);
|
||||
else if (dsize == 8)
|
||||
emit_u64(m, (uint64_t)disp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 特殊情况:只有一个显式寄存器操作数,且 reg_fix/rm_fix 均未指定,且
|
||||
// mod_fix == 3 此时操作数应放在 rm 字段,reg 字段固定为 0(例如 SETZ
|
||||
// 指令)
|
||||
// 没有内存操作数:寄存器-寄存器或单个寄存器
|
||||
int is_single_reg_op =
|
||||
(info->num_explicit_ops == 1 && enc->modrm_reg_fix == -1 &&
|
||||
enc->modrm_rm_fix == -1 && enc->mod_fix == 3);
|
||||
if (is_single_reg_op && reg_r != SCC_X86_REG_INVALID &&
|
||||
reg_b == SCC_X86_REG_INVALID) {
|
||||
// 操作数作为 rm,reg 部分为 0
|
||||
modrm = 0xC0 | (reg_low3(reg_r) & 7);
|
||||
emit_u8(m, modrm);
|
||||
LOG_INFO("[MODRM] single reg operand treated as rm, emit 0x%02x",
|
||||
@@ -369,28 +433,126 @@ static void emit_modrm_sib_disp(scc_mcode_t *m,
|
||||
emit_u8(m, modrm);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO("[MODRM] emit byte 0x%02x", modrm);
|
||||
|
||||
/* 立即数在 ModRM 后发射 */
|
||||
// 立即数在 ModRM 后发射
|
||||
if (imm_idx >= 0) {
|
||||
emit_immediate(m, enc, tmpl, imm_idx, imm_val, op_width);
|
||||
}
|
||||
}
|
||||
|
||||
static scc_x86_iform_t adapt_iform_to_8bit(scc_x86_iform_t iform,
|
||||
const scc_x86_operand_value_t *ops,
|
||||
int num_ops) {
|
||||
// 只处理第一个操作数是 8
|
||||
// 位寄存器的情况(大多数指令的目标或源是第一个寄存器)
|
||||
if (num_ops > 0 && ops[0].kind == SCC_X86_OPR_REG &&
|
||||
scc_reg_width(ops[0].reg) == 8) {
|
||||
switch (iform) {
|
||||
// ---- MOV 类 ----
|
||||
case SCC_X86_IFORM_MOV_GPRV_IMMV:
|
||||
case SCC_X86_IFORM_MOV_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_MOV_GPR8_IMMB_B0;
|
||||
case SCC_X86_IFORM_MOV_GPRV_GPRV_89: // mov r/m, r
|
||||
return SCC_X86_IFORM_MOV_GPR8_GPR8_88;
|
||||
case SCC_X86_IFORM_MOV_GPRV_GPRV_8B: // mov r, r/m
|
||||
return SCC_X86_IFORM_MOV_GPR8_GPR8_8A;
|
||||
case SCC_X86_IFORM_MOV_GPRV_MEMV: // mov r, mem
|
||||
return SCC_X86_IFORM_MOV_GPR8_MEMB;
|
||||
case SCC_X86_IFORM_MOV_MEMV_GPRV: // mov mem, r
|
||||
return SCC_X86_IFORM_MOV_MEMB_GPR8;
|
||||
// ---- ADD ----
|
||||
case SCC_X86_IFORM_ADD_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_ADD_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_ADD_GPR8_IMMB_80R0;
|
||||
case SCC_X86_IFORM_ADD_GPRV_GPRV_01: // add r/m, r
|
||||
return SCC_X86_IFORM_ADD_GPR8_GPR8_00;
|
||||
case SCC_X86_IFORM_ADD_GPRV_GPRV_03: // add r, r/m
|
||||
return SCC_X86_IFORM_ADD_GPR8_GPR8_02;
|
||||
// ---- SUB ----
|
||||
case SCC_X86_IFORM_SUB_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_SUB_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_SUB_GPR8_IMMB_80R5;
|
||||
case SCC_X86_IFORM_SUB_GPRV_GPRV_29:
|
||||
return SCC_X86_IFORM_SUB_GPR8_GPR8_28;
|
||||
case SCC_X86_IFORM_SUB_GPRV_GPRV_2B:
|
||||
return SCC_X86_IFORM_SUB_GPR8_GPR8_2A;
|
||||
// ---- CMP ----
|
||||
case SCC_X86_IFORM_CMP_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_CMP_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_CMP_GPR8_IMMB_80R7;
|
||||
case SCC_X86_IFORM_CMP_GPRV_GPRV_39:
|
||||
return SCC_X86_IFORM_CMP_GPR8_GPR8_38;
|
||||
case SCC_X86_IFORM_CMP_GPRV_GPRV_3B:
|
||||
return SCC_X86_IFORM_CMP_GPR8_GPR8_3A;
|
||||
// ---- AND ----
|
||||
case SCC_X86_IFORM_AND_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_AND_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_AND_GPR8_IMMB_80R4;
|
||||
case SCC_X86_IFORM_AND_GPRV_GPRV_21:
|
||||
return SCC_X86_IFORM_AND_GPR8_GPR8_20;
|
||||
// ---- OR ----
|
||||
case SCC_X86_IFORM_OR_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_OR_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_OR_GPR8_IMMB_80R1;
|
||||
case SCC_X86_IFORM_OR_GPRV_GPRV_09:
|
||||
return SCC_X86_IFORM_OR_GPR8_GPR8_08;
|
||||
// ---- XOR ----
|
||||
case SCC_X86_IFORM_XOR_GPRV_IMMB:
|
||||
case SCC_X86_IFORM_XOR_GPRV_IMMZ:
|
||||
return SCC_X86_IFORM_XOR_GPR8_IMMB_80R6;
|
||||
case SCC_X86_IFORM_XOR_GPRV_GPRV_31:
|
||||
return SCC_X86_IFORM_XOR_GPR8_GPR8_30;
|
||||
// ---- TEST ----
|
||||
case SCC_X86_IFORM_TEST_GPRV_GPRV:
|
||||
return SCC_X86_IFORM_TEST_GPR8_GPR8;
|
||||
case SCC_X86_IFORM_TEST_GPRV_IMMZ_F7R0:
|
||||
return SCC_X86_IFORM_TEST_GPR8_IMMB_F6R0;
|
||||
// ---- INC/DEC ----
|
||||
case SCC_X86_IFORM_INC_GPRV_40:
|
||||
case SCC_X86_IFORM_INC_GPRV_FFR0:
|
||||
return SCC_X86_IFORM_INC_GPR8;
|
||||
case SCC_X86_IFORM_DEC_GPRV_48:
|
||||
case SCC_X86_IFORM_DEC_GPRV_FFR1:
|
||||
return SCC_X86_IFORM_DEC_GPR8;
|
||||
// ---- NEG/NOT ----
|
||||
case SCC_X86_IFORM_NEG_GPRV:
|
||||
return SCC_X86_IFORM_NEG_GPR8;
|
||||
case SCC_X86_IFORM_NOT_GPRV:
|
||||
return SCC_X86_IFORM_NOT_GPR8;
|
||||
// ---- 移位操作 ----
|
||||
case SCC_X86_IFORM_SHL_GPRV_ONE_D1R4:
|
||||
return SCC_X86_IFORM_SHL_GPR8_ONE_D0R4;
|
||||
case SCC_X86_IFORM_SHR_GPRV_ONE:
|
||||
return SCC_X86_IFORM_SHR_GPR8_ONE;
|
||||
case SCC_X86_IFORM_SAR_GPRV_ONE:
|
||||
return SCC_X86_IFORM_SAR_GPR8_ONE;
|
||||
// ---- 其他(根据需求继续添加)----
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return iform;
|
||||
}
|
||||
|
||||
/* ---------- 主编码入口 ---------- */
|
||||
int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
const scc_x86_operand_value_t *ops) {
|
||||
if (!mcode || !ops)
|
||||
return -1;
|
||||
|
||||
if (iform >= SCC_X86_IFORM_COUNT || iform < 0)
|
||||
if (iform >= SCC_X86_IFORM_COUNT)
|
||||
Panic("invalid iform %d", iform);
|
||||
|
||||
const scc_x86_iform_info_t *info = &scc_x86_iform_table[iform];
|
||||
int num_ops = info->num_explicit_ops;
|
||||
// FIXME 自动适配 8 位操作数
|
||||
iform = adapt_iform_to_8bit(iform, ops, num_ops);
|
||||
// FIXME 重新获取 info 因为 iform 可能变了
|
||||
info = &scc_x86_iform_table[iform];
|
||||
|
||||
const scc_x86_encoding_t *enc = &info->encode;
|
||||
const scc_x86_operand_t *tmpl = info->ops;
|
||||
int num_ops = info->num_explicit_ops;
|
||||
|
||||
LOG_INFO("[IFORM] %s, explicit_ops=%d (total=%d)", info->iform_name,
|
||||
num_ops, info->num_ops);
|
||||
|
||||
@@ -399,7 +561,6 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
scc_x86_reg_t base_reg = SCC_X86_REG_INVALID;
|
||||
scc_x86_reg_t idx_reg = SCC_X86_REG_INVALID;
|
||||
|
||||
/* ---------- 收集立即数信息(用于无 ModRM 指令) ---------- */
|
||||
int64_t imm_val = 0;
|
||||
int imm_idx = -1;
|
||||
for (int i = 0; i < num_ops; i++) {
|
||||
@@ -407,16 +568,15 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
if (ops[i].kind == SCC_X86_OPR_REG) {
|
||||
if (scc_strcmp(tname, "REG0") == 0) {
|
||||
if (enc->modrm_reg_fix >= 0)
|
||||
rm_field = ops[i].reg; // reg固定 → REG0为rm
|
||||
rm_field = ops[i].reg;
|
||||
else
|
||||
reg_field = ops[i].reg; // 否则为reg
|
||||
reg_field = ops[i].reg;
|
||||
} else if (scc_strcmp(tname, "REG1") == 0) {
|
||||
if (enc->modrm_rm_fix >= 0)
|
||||
reg_field = ops[i].reg; // rm固定 → REG1为reg
|
||||
reg_field = ops[i].reg;
|
||||
else
|
||||
rm_field = ops[i].reg; // 否则为rm
|
||||
rm_field = ops[i].reg;
|
||||
} else {
|
||||
// 未命名的寄存器,按先 reg 后 rm 填充
|
||||
if (reg_field == SCC_X86_REG_INVALID)
|
||||
reg_field = ops[i].reg;
|
||||
else if (rm_field == SCC_X86_REG_INVALID)
|
||||
@@ -432,38 +592,33 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 新增:特殊处理 SETZ 类指令(只有一个寄存器操作数,mod_fix=3 且
|
||||
// reg_fix/rm_fix 未指定)=====
|
||||
// 特殊处理 SETZ 等单寄存器指令
|
||||
if (enc->has_modrm && info->num_explicit_ops == 1 &&
|
||||
enc->modrm_reg_fix == -1 && enc->modrm_rm_fix == -1 &&
|
||||
enc->mod_fix == 3) {
|
||||
if (reg_field != SCC_X86_REG_INVALID &&
|
||||
rm_field == SCC_X86_REG_INVALID) {
|
||||
// 将操作数从 reg_field 移到 rm_field
|
||||
rm_field = reg_field;
|
||||
reg_field = SCC_X86_REG_INVALID;
|
||||
}
|
||||
}
|
||||
// ========================================================================
|
||||
|
||||
int op_width = infer_operand_width(info, ops);
|
||||
LOG_INFO("[OPWIDTH] %d bits", op_width);
|
||||
|
||||
// +++ 新增:无 ModRM 时,寄存器用 REX.B 扩展 +++
|
||||
if (!enc->has_modrm) {
|
||||
rm_field = reg_field;
|
||||
reg_field = SCC_X86_REG_INVALID;
|
||||
}
|
||||
|
||||
emit_legacy_prefixes(mcode, enc, reg_field, rm_field, base_reg, idx_reg);
|
||||
emit_rex(mcode, enc, reg_field, rm_field, base_reg, idx_reg);
|
||||
emit_rex(mcode, enc, reg_field, rm_field, base_reg, idx_reg, op_width);
|
||||
emit_escape_map(mcode, enc);
|
||||
|
||||
if (enc->has_modrm) {
|
||||
emit_opcode(mcode, enc, rm_field, base_reg);
|
||||
emit_modrm_sib_disp(mcode, info, ops, op_width);
|
||||
} else {
|
||||
// 无 ModRM:opcode 中的寄存器来自 rm_field
|
||||
emit_opcode(mcode, enc, rm_field, base_reg);
|
||||
if (imm_idx >= 0) {
|
||||
emit_immediate(mcode, enc, tmpl, imm_idx, imm_val, op_width);
|
||||
@@ -471,4 +626,4 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user