feat(compiler): 实现HIR到LIR的函数定义标记和直接/间接调用区分
- 在HIR函数元数据中添加defined字段来标记函数是否已定义 - 在AST到IR转换过程中设置函数定义状态 - 修改LIR模块函数声明接口以支持定义状态参数 - 实现直接调用和间接调用的区别处理,通过符号查找确定调用类型 - 更新LIR调用指令结构以支持直接和间接调用的不同表示方式 - 调整x86后端指令选择以正确处理不同类型的调用 fix(x86-isel): 优化x86指令发射和操作数大小处理 - 移除move/load/store函数中的size参数,改由操作数本身携带大小信息 - 简化x86指令操作数结构,减少操作数数量限制 - 添加专门的mov系列表单选择函数,根据操作数类型和大小自动选择正确的指令形式 - 修正间接调用的指令形式为CALL_NEAR_MEMV而非GPRV - 添加向量版本的load/store/move发射函数 refactor(reg-alloc): 更新寄存器分配迭代器接口 - 为分配迭代器的替换方法添加size参数,以便正确处理不同大小的寄存器
This commit is contained in:
@@ -60,7 +60,14 @@ static int infer_operand_width(const scc_x86_iform_info_t *info,
|
||||
const scc_x86_operand_value_t ops[]) {
|
||||
for (int i = 0; i < info->num_explicit_ops; i++) {
|
||||
if (ops[i].kind == SCC_X86_OPR_REG && !info->ops[i].is_implicit) {
|
||||
uint16_t w = scc_reg_width(ops[i].reg);
|
||||
uint16_t w;
|
||||
if (ops[i].size > 0 && ops[i].reg >= SCC_X86_REG_R8 &&
|
||||
ops[i].reg <= SCC_X86_REG_R15) {
|
||||
/* R8-R15:宽度由 size 字段推导 */
|
||||
w = ops[i].size * 8;
|
||||
} else {
|
||||
w = scc_reg_width(ops[i].reg);
|
||||
}
|
||||
if (w > 0)
|
||||
return w;
|
||||
}
|
||||
@@ -177,7 +184,8 @@ static void emit_escape_map(scc_mcode_t *m, const scc_x86_encoding_t *enc) {
|
||||
}
|
||||
|
||||
static void emit_opcode(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
scc_x86_reg_t rm_reg, scc_x86_reg_t base_reg) {
|
||||
scc_x86_reg_t rm_reg, scc_x86_reg_t base_reg,
|
||||
int op_width) {
|
||||
for (int i = 0; i < enc->opcode_len; i++) {
|
||||
uint8_t byte = enc->opcode[i];
|
||||
if (enc->partial_opcode && i == enc->opcode_len - 1) {
|
||||
@@ -186,6 +194,9 @@ static void emit_opcode(scc_mcode_t *m, const scc_x86_encoding_t *enc,
|
||||
if (target != SCC_X86_REG_INVALID)
|
||||
byte |= (reg_low3(target) & 7);
|
||||
}
|
||||
/* MOV r8, imm8: B8-BF → B0-B7 */
|
||||
if (op_width == 8 && (byte & 0xF8) == 0xB8)
|
||||
byte -= 8;
|
||||
emit_u8(m, byte);
|
||||
}
|
||||
}
|
||||
@@ -442,100 +453,6 @@ static void emit_modrm_sib_disp(scc_mcode_t *m,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -546,15 +463,9 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t 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;
|
||||
LOG_INFO("[IFORM] %s, explicit_ops=%d (total=%d)", info->iform_name,
|
||||
num_ops, info->num_ops);
|
||||
LOG_INFO("[ENCODE] %s", info->iform_name);
|
||||
|
||||
scc_x86_reg_t reg_field = SCC_X86_REG_INVALID;
|
||||
scc_x86_reg_t rm_field = SCC_X86_REG_INVALID;
|
||||
@@ -616,10 +527,10 @@ int scc_x86_encode_inst(scc_mcode_t *mcode, scc_x86_iform_t iform,
|
||||
emit_escape_map(mcode, enc);
|
||||
|
||||
if (enc->has_modrm) {
|
||||
emit_opcode(mcode, enc, rm_field, base_reg);
|
||||
emit_opcode(mcode, enc, rm_field, base_reg, op_width);
|
||||
emit_modrm_sib_disp(mcode, info, ops, op_width);
|
||||
} else {
|
||||
emit_opcode(mcode, enc, rm_field, base_reg);
|
||||
emit_opcode(mcode, enc, rm_field, base_reg, op_width);
|
||||
if (imm_idx >= 0) {
|
||||
emit_immediate(mcode, enc, tmpl, imm_idx, imm_val, op_width);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user