Files
scc/libs/mcode/include/x86/scc_x86_patch.h
zzy cec96333e7 feat(ast2ir): 实现C11类型提升系统并重构HIR基本块管理
- 新增 scc_ast2ir_promote.c 实现整数提升(6.3.1.1)和寻常算术转换(6.3.1.8)
- 重构 HIR Builder: bblock → create_bblock + append_bblock,引入BBList链表管理
- AST2IR 全面集成类型提升:二元运算、赋值、函数调用参数、自增/自减操作符
- 变参函数支持:跳过 ... 假参数,实现默认参数提升(float→double等)
- 简化 HIR Dump 实现
- MIR: Win64 ABI改进、x86指令选择优化
- 新增 printf 测试用例
2026-05-24 15:46:22 +08:00

136 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __SCC_X86_PATCH_H__
#define __SCC_X86_PATCH_H__
#include "scc_x86_encode.h"
// x86-64 重定位类型(由底层 patch 函数处理)
typedef enum {
SCC_X86_PATCH_NONE,
SCC_X86_PATCH_PC32, // 32 位 PC 相对偏移CALL/JMP/Jcc
SCC_X86_PATCH_ABS64, // 64 位绝对地址MOV reg, imm64
SCC_X86_PATCH_ABS32, // 32 位绝对地址MOV reg, imm32
SCC_X86_PATCH_DISP8, // 8 位内存位移([RIP+disp8] 或 [base+disp8]
SCC_X86_PATCH_DISP32, // 32 位内存位移([RIP+disp32]
} scc_x86_patch_type_t;
static inline void patch_bytes(scc_mcode_t *mcode, usize offset,
const void *data, usize size) {
u8 *buf = (u8 *)scc_mcode_unsafe_data(mcode);
usize total = scc_mcode_size(mcode);
if (offset + size > total) {
Panic("patch offset out of range: offset=%zu size=%zu total=%zu",
offset, size, total);
}
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)
return -1;
usize bytes = disp.displacement_bits / 8;
if (bytes == 0) {
bytes = 4; // RELBR 32
}
if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8) {
Panic("invalid displacement bits: %u", disp.displacement_bits);
}
// 将 displacement 截断到对应宽度(小端写入)
i64 val = disp.displacement;
switch (bytes) {
case 1: {
u8 v = (u8)val;
patch_bytes(mcode, offset, &v, 1);
break;
}
case 2: {
u16 v = (u16)val;
patch_bytes(mcode, offset, &v, 2);
break;
}
case 4: {
u32 v = (u32)val;
patch_bytes(mcode, offset, &v, 4);
break;
}
case 8:
patch_bytes(mcode, offset, &val, 8);
break;
}
return 0;
}
static inline int scc_x86_patch_brdisp(scc_mcode_t *mcode, usize offset,
scc_x86_operand_value_t disp) {
if (disp.kind != SCC_X86_OPR_RELBR && disp.kind != SCC_X86_OPR_RELOC) {
Panic("patch_brdisp called with non-branch operand kind %d", disp.kind);
}
i32 brdisp;
if (disp.kind == SCC_X86_OPR_RELBR)
brdisp = disp.brdisp;
else
brdisp = (i32)disp.reloc.imm; // 从重定位占位中获取值(上层会先填好)
patch_bytes(mcode, offset, &brdisp, 4);
return 0;
}
static inline int scc_x86_patch_imm0(scc_mcode_t *mcode, usize offset,
scc_x86_operand_value_t imm0) {
// 注意:原声明未提供大小参数,我们假定调用者保证了正确的宽度。
// 此处默认写入 8 字节(最常用)。若需要其他宽度,请使用扩展版本。
if (imm0.kind != SCC_X86_OPR_IMM && imm0.kind != SCC_X86_OPR_RELOC) {
Panic("patch_imm0 called with non-immediate operand kind %d",
imm0.kind);
}
u64 val;
if (imm0.kind == SCC_X86_OPR_IMM)
val = imm0.imm0;
else
val = (u64)imm0.reloc.imm; // 从重定位占位中获取
patch_bytes(mcode, offset, &val, 8);
return 0;
}
/* ---------- 扩展:带大小的立即数 patch推荐上层使用 ---------- */
static inline int scc_x86_patch_imm0_ex(scc_mcode_t *mcode, usize offset,
u64 value, usize size) {
if (size != 1 && size != 2 && size != 4 && size != 8)
return -1;
switch (size) {
case 1: {
u8 v = (u8)value;
patch_bytes(mcode, offset, &v, 1);
break;
}
case 2: {
u16 v = (u16)value;
patch_bytes(mcode, offset, &v, 2);
break;
}
case 4: {
u32 v = (u32)value;
patch_bytes(mcode, offset, &v, 4);
break;
}
case 8:
patch_bytes(mcode, offset, &value, 8);
break;
}
return 0;
}
static inline void scc_x86_patch(scc_mcode_t *mcode,
scc_x86_patch_type_t patch_type, u64 offset,
u64 value) {
switch (patch_type) {
case SCC_X86_PATCH_PC32:
i32 rel = value - offset;
scc_x86_patch_brdisp(mcode, offset - 4, scc_x86_op_relbr(rel));
break;
default:
TODO();
break;
}
}
#endif /* __SCC_X86_PATCH_H__ */