refactor(ast2ir): 重构ABI类型系统并修复union结构问题

- 将scc_ast_def.h中的attr_of从union改为struct以修复结构定义问题
- 添加type_abi依赖到ast2ir模块的cbuild.toml配置文件中
- 重命名scc_ast2ir.h中的abi字段为type_abi,并更新相关初始化函数签名
- 移除废弃的scc_abi_type.h和相关平台ABI头文件
- 添加辅助函数is_variadic_marker和fixed_param_count用于处理可变参数
- 添加数组和聚合类型初始化的辅助函数
This commit is contained in:
zzy
2026-06-01 12:14:13 +08:00
parent 8b817da3b6
commit 31d7e91ef1
45 changed files with 1918 additions and 1551 deletions

View File

@@ -52,7 +52,7 @@ static inline scc_x86_operand_value_t scc_x86_op_slot(int slot_id, u8 size) {
o.mem.scale = 1;
o.mem.disp.displacement = slot_id;
o.mem.disp.displacement_bits = 0;
o.size = size;
o.size_bits = size;
return o;
}

View File

@@ -14,8 +14,8 @@ typedef struct scc_mir_instr {
int opcode;
union {
struct {
int size;
int align;
int size_bits;
int align_bits;
int vreg;
} alloc;
} data;

View File

@@ -98,34 +98,34 @@ void scc_x86_instr_dump(scc_tree_dump_t *td, const scc_mir_func_t *func,
scc_tree_dump_append(td, "<?>");
break;
}
scc_tree_dump_append_fmt(td, ".(%zu)", op->size);
scc_tree_dump_append_fmt(td, ".(%zu)", op->size_bits);
}
}
// 将 LIR 值转换为 x86 操作数
scc_x86_operand_value_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
const scc_lir_val_t *val,
u8 size) {
u8 size_bits) {
scc_x86_operand_value_t op = {0};
switch (val->kind) {
case SCC_LIR_INSTR_KIND_NONE:
op.kind = SCC_X86_OPR_NONE;
break;
case SCC_LIR_INSTR_KIND_VREG:
op = scc_x86_op_vreg(val->data.reg, size);
op = scc_x86_op_vreg(val->data.reg, size_bits);
int id = 0;
int ret = scc_mir_vreg_lookup(isel->func, val->data.reg, &id);
if (ret > 0) {
op = scc_x86_op_preg(id, size);
op = scc_x86_op_preg(id, size_bits);
} else if (ret < 0) {
op = scc_x86_op_slot(id, size);
op = scc_x86_op_slot(id, size_bits);
}
break;
case SCC_LIR_INSTR_KIND_IMM:
op = scc_x86_op_imm(val->data.imm.data.digit, size);
op = scc_x86_op_imm(val->data.imm.data.digit, size_bits);
break;
case SCC_LIR_INSTR_KIND_FIMM:
op = scc_x86_op_imm(*(i64 *)&val->data.fimm, size);
op = scc_x86_op_imm(*(i64 *)&val->data.fimm, size_bits);
break;
case SCC_LIR_INSTR_KIND_SYMBOL:
op = scc_x86_op_reloc_global_relrip(val->data.symbol, 0);
@@ -133,7 +133,7 @@ scc_x86_operand_value_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
case SCC_LIR_INSTR_KIND_ARG:
Assert(isel->abi_lowering.lower_param);
isel->abi_lowering.lower_param(isel, val, &op);
op.size = size;
op.size_bits = size_bits;
break;
default:
Panic("unsupported lir instr kind %d", val->kind);
@@ -144,15 +144,15 @@ scc_x86_operand_value_t scc_x86_lir_val_to_mir_op(scc_x86_64_isel_t *isel,
// 虚拟临时寄存器分配(简单递增)
static scc_x86_operand_value_t new_vreg_temp(scc_x86_64_isel_t *isel,
int size) {
return scc_x86_op_vreg(scc_mir_alloc_vreg(isel->func), size);
int size_bits) {
return scc_x86_op_vreg(scc_mir_alloc_vreg(isel->func), size_bits);
}
/* 确保操作数为寄存器: IMM → 加载到临时虚拟寄存器 */
static scc_x86_operand_value_t ensure_reg(scc_x86_64_isel_t *isel,
scc_x86_operand_value_t op) {
if (op.kind == SCC_X86_OPR_IMM) {
scc_x86_operand_value_t tmp = new_vreg_temp(isel, op.size);
scc_x86_operand_value_t tmp = new_vreg_temp(isel, op.size_bits);
scc_x86_emit_move(isel, tmp, op);
return tmp;
}
@@ -202,8 +202,8 @@ static void emit_binary_op(scc_x86_64_isel_t *isel, scc_lir_op_t op,
scc_x86_operand_value_t src1) {
emit_copy_if_needed(isel, dst, src0);
Assert(src0.size == src1.size);
int is_8b = src0.size == 1;
Assert(src0.size_bits == src1.size_bits);
// int is_8b = src0.size_bits == 8;
int is_imm = src1.kind == SCC_X86_OPR_IMM;
scc_x86_iform_t opcode;
switch (op) {
@@ -242,7 +242,7 @@ void scc_x86_emit_load(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
scc_x86_operand_value_t src) {
scc_x86_operand_value_t tmp_reg = dst;
if (dst.kind != SCC_X86_OPR_REG) {
tmp_reg = new_vreg_temp(isel, src.size);
tmp_reg = new_vreg_temp(isel, src.size_bits);
}
scc_x86_emit_load_to_vec(&isel->instrs, tmp_reg, src);
if (dst.kind != SCC_X86_OPR_REG) {
@@ -253,7 +253,7 @@ void scc_x86_emit_load(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
void scc_x86_emit_store(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
scc_x86_operand_value_t src) {
if (src.kind == SCC_X86_OPR_MEM) {
scc_x86_operand_value_t tmp_reg = new_vreg_temp(isel, src.size);
scc_x86_operand_value_t tmp_reg = new_vreg_temp(isel, src.size_bits);
scc_x86_emit_load(isel, tmp_reg, src);
src = tmp_reg;
}
@@ -264,8 +264,8 @@ static void emit_load_addr(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
scc_x86_operand_value_t base,
scc_x86_operand_value_t index, int scale,
i64 offset) {
usize size = dst.size;
Assert(size == 8);
usize size_bits = dst.size_bits;
Assert(size_bits == 64);
// 前置断言dst 必须是寄存器
Assert(dst.kind == SCC_X86_OPR_REG);
// scale 必须是 1,2,4,8 之一
@@ -279,11 +279,11 @@ static void emit_load_addr(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
} break;
case SCC_X86_OPR_RELOC: {
Assert(base.reloc.target == SCC_X86_RELOC_TARGET_SYMBOL);
base_reg = new_vreg_temp(isel, 8);
base_reg = new_vreg_temp(isel, 64);
scc_x86_emit_move(isel, base_reg, base);
} break;
case SCC_X86_OPR_MEM: {
base_reg = new_vreg_temp(isel, 8);
base_reg = new_vreg_temp(isel, 64);
scc_x86_emit_move(isel, base_reg, base);
} break;
default: {
@@ -298,15 +298,15 @@ static void emit_load_addr(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
} break;
case SCC_X86_OPR_RELOC: {
Assert(index.reloc.target == SCC_X86_RELOC_TARGET_SYMBOL);
index_reg = new_vreg_temp(isel, 8);
index_reg = new_vreg_temp(isel, 64);
scc_x86_emit_move(isel, index_reg, index);
} break;
case SCC_X86_OPR_MEM: {
index_reg = new_vreg_temp(isel, 8);
index_reg = new_vreg_temp(isel, 64);
scc_x86_emit_move(isel, index_reg, index);
} break;
case SCC_X86_OPR_IMM: {
index_reg = new_vreg_temp(isel, index.size);
index_reg = new_vreg_temp(isel, index.size_bits);
scc_x86_emit_move(isel, index_reg, index);
} break;
default: {
@@ -320,18 +320,18 @@ static void emit_load_addr(scc_x86_64_isel_t *isel, scc_x86_operand_value_t dst,
.scale = scale,
.disp.displacement = offset,
.disp.displacement_bits = 8},
size);
size_bits);
scc_x86_emit_move(isel, dst, mem_op);
}
static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
u8 size = instr->size;
u8 size_bits = instr->size_bits;
scc_x86_operand_value_t dst =
scc_x86_lir_val_to_mir_op(isel, &instr->to, size);
scc_x86_lir_val_to_mir_op(isel, &instr->to, size_bits);
scc_x86_operand_value_t src0 =
scc_x86_lir_val_to_mir_op(isel, &instr->arg0, size);
scc_x86_lir_val_to_mir_op(isel, &instr->arg0, size_bits);
scc_x86_operand_value_t src1 =
scc_x86_lir_val_to_mir_op(isel, &instr->arg1, size);
scc_x86_lir_val_to_mir_op(isel, &instr->arg1, size_bits);
switch (instr->op) {
/* ---- 数据移动 ---- */
@@ -373,7 +373,7 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
case SCC_LIR_MUL:
emit_copy_if_needed(isel, dst, src0);
if (src1.kind == SCC_X86_OPR_IMM) {
scc_x86_operand_value_t op = new_vreg_temp(isel, size);
scc_x86_operand_value_t op = new_vreg_temp(isel, size_bits);
scc_x86_emit_move(isel, op, src1);
src1 = op;
}
@@ -401,7 +401,7 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
}
add_instr_2(isel, iform, dst, src1);
} else {
scc_x86_operand_value_t cl = scc_x86_op_preg(SCC_X86_REG_CL, 1);
scc_x86_operand_value_t cl = scc_x86_op_preg(SCC_X86_REG_CL, 8);
scc_x86_emit_move(isel, cl, src1);
scc_x86_iform_t iform;
switch (instr->op) {
@@ -426,14 +426,16 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
case SCC_LIR_DIV_U:
case SCC_LIR_REM_S:
case SCC_LIR_REM_U: {
scc_x86_operand_value_t rax = scc_x86_op_preg(SCC_X86_REG_RAX, size);
scc_x86_operand_value_t rdx = scc_x86_op_preg(SCC_X86_REG_RDX, size);
scc_x86_operand_value_t rax =
scc_x86_op_preg(SCC_X86_REG_RAX, size_bits);
scc_x86_operand_value_t rdx =
scc_x86_op_preg(SCC_X86_REG_RDX, size_bits);
if (instr->op == SCC_LIR_DIV_S || instr->op == SCC_LIR_REM_S) {
if (size < 8) {
if (size_bits < 64) {
// TODO 可能需要在lir进行size对齐
scc_x86_operand_value_t rax64 =
scc_x86_op_preg(SCC_X86_REG_RAX, 8);
scc_x86_op_preg(SCC_X86_REG_RAX, 64);
add_instr_2(isel, SCC_X86_IFORM_MOVSXD_GPRV_GPRZ, rax64, src0);
} else {
scc_x86_emit_move(isel, rax, src0);
@@ -441,7 +443,7 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
add_instr_0(isel, SCC_X86_IFORM_CQO);
} else {
scc_x86_emit_move(isel, rax, src0);
scc_x86_operand_value_t zero = scc_x86_op_imm(0, size);
scc_x86_operand_value_t zero = scc_x86_op_imm(0, size_bits);
scc_x86_emit_move(isel, rdx, zero);
}
@@ -451,7 +453,7 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
: SCC_X86_IFORM_DIV_GPRV;
scc_x86_operand_value_t divisor = src1;
if (src1.kind == SCC_X86_OPR_IMM) {
divisor = new_vreg_temp(isel, size);
divisor = new_vreg_temp(isel, size_bits);
scc_x86_emit_move(isel, divisor, src1);
}
add_instr_1(isel, div_if, divisor);
@@ -464,33 +466,34 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
/* ---- 比较指令 ---- */
case SCC_LIR_CMP: {
Assert(src0.size == src1.size);
Assert(src0.size_bits == src1.size_bits);
if (src0.kind == SCC_X86_OPR_IMM) {
scc_x86_operand_value_t tmp_reg = new_vreg_temp(isel, src0.size);
scc_x86_operand_value_t tmp_reg =
new_vreg_temp(isel, src0.size_bits);
scc_x86_emit_move(isel, tmp_reg, src0);
src0 = tmp_reg;
}
if (scc_x86_op_is_vreg(&src0) && src1.kind == SCC_X86_OPR_IMM)
// SCC_X86_IFORM_CMP_GPR8_IMMB_82R7 历史遗留指令在amd64中已不再使用
add_instr_2(isel,
src0.size == 1 ? SCC_X86_IFORM_CMP_GPR8_IMMB_80R7
: SCC_X86_IFORM_CMP_GPRV_IMMZ,
src0.size_bits == 8 ? SCC_X86_IFORM_CMP_GPR8_IMMB_80R7
: SCC_X86_IFORM_CMP_GPRV_IMMZ,
src0, src1);
else if (scc_x86_op_is_vreg(&src0) && scc_x86_op_is_vreg(&src1))
add_instr_2(isel,
src0.size == 1 ? SCC_X86_IFORM_CMP_GPR8_GPR8_3A
: SCC_X86_IFORM_CMP_GPRV_GPRV_3B,
src0.size_bits == 8 ? SCC_X86_IFORM_CMP_GPR8_GPR8_3A
: SCC_X86_IFORM_CMP_GPRV_GPRV_3B,
src0, src1);
else
UNREACHABLE();
scc_x86_iform_t setcc = cond_to_setcc(instr->metadata.cond);
add_instr_1(isel, setcc, dst);
if (size > 1) {
scc_x86_operand_value_t one = scc_x86_op_imm(1, size);
if (size_bits > 8) {
scc_x86_operand_value_t one = scc_x86_op_imm(1, size_bits);
add_instr_2(isel,
src1.size == 1 ? SCC_X86_IFORM_AND_GPR8_IMMB_82R4
: SCC_X86_IFORM_AND_GPRV_IMMZ,
src1.size_bits == 8 ? SCC_X86_IFORM_AND_GPR8_IMMB_82R4
: SCC_X86_IFORM_AND_GPRV_IMMZ,
dst, one);
}
} break;
@@ -501,11 +504,11 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
scc_x86_op_reloc_block(instr->metadata.br.true_target, 0);
scc_x86_operand_value_t false_bb =
scc_x86_op_reloc_block(instr->metadata.br.false_target, 0);
true_bb.size = instr->size;
false_bb.size = instr->size;
true_bb.size_bits = instr->size_bits;
false_bb.size_bits = instr->size_bits;
add_instr_2(isel,
src0.size == 1 ? SCC_X86_IFORM_TEST_GPR8_GPR8
: SCC_X86_IFORM_TEST_GPRV_GPRV,
src0.size_bits == 8 ? SCC_X86_IFORM_TEST_GPR8_GPR8
: SCC_X86_IFORM_TEST_GPRV_GPRV,
src0, src0);
add_instr_1(isel, SCC_X86_IFORM_JNZ_RELBRZ, true_bb);
add_instr_1(isel, SCC_X86_IFORM_JMP_RELBRZ, false_bb);
@@ -520,49 +523,50 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
/* ---- 栈分配 ---- */
case SCC_LIR_ALLOCA: {
scc_x86_operand_value_t op =
scc_x86_lir_val_to_mir_op(isel, &instr->to, instr->size);
scc_x86_lir_val_to_mir_op(isel, &instr->to, instr->size_bits);
scc_mir_x86_instr_t x86instr;
x86instr.instr.opcode = SCC_MIR_PSEUDO_ALLOCA;
Assert(op.kind == SCC_X86_OPR_REG);
x86instr.instr.data.alloc.vreg = op.reg;
x86instr.instr.data.alloc.size = instr->metadata.alloca.size_bytes;
x86instr.instr.data.alloc.align = instr->metadata.alloca.align_bytes;
x86instr.instr.data.alloc.size_bits = instr->metadata.alloca.size_bits;
x86instr.instr.data.alloc.align_bits =
instr->metadata.alloca.align_bits;
scc_vec_push(isel->instrs, x86instr);
scc_mir_vreg_map2slot(isel->func, instr->to.data.reg,
instr->metadata.alloca.size_bytes,
instr->metadata.alloca.align_bytes
? instr->metadata.alloca.align_bytes
instr->metadata.alloca.size_bits,
instr->metadata.alloca.align_bits
? instr->metadata.alloca.align_bits
: 8);
break;
}
/* ---- 类型扩展 ---- */
case SCC_LIR_EXTEND: {
int from_size = instr->metadata.extend.from_size;
int from_size_bits = instr->metadata.extend.from_size_bits;
scc_x86_operand_value_t ext_src =
scc_x86_lir_val_to_mir_op(isel, &instr->arg0, from_size);
scc_x86_lir_val_to_mir_op(isel, &instr->arg0, from_size_bits);
ext_src = ensure_reg(isel, ext_src);
if (instr->ext == SCC_LIR_EXT_ZEXT) {
if (from_size == 4) {
if (from_size_bits == 32) {
// 32→64: x86-64 写32位寄存器自动零扩展到64位
scc_x86_emit_move(isel, dst, ext_src);
} else {
scc_x86_iform_t iform = (from_size == 1)
scc_x86_iform_t iform = (from_size_bits == 8)
? SCC_X86_IFORM_MOVZX_GPRV_GPR8
: SCC_X86_IFORM_MOVZX_GPRV_GPR16;
add_instr_2(isel, iform, dst, ext_src);
}
} else if (instr->ext == SCC_LIR_EXT_SEXT) {
scc_x86_iform_t iform;
switch (from_size) {
case 1:
switch (from_size_bits) {
case 8:
iform = SCC_X86_IFORM_MOVSX_GPRV_GPR8;
break;
case 2:
case 16:
iform = SCC_X86_IFORM_MOVSX_GPRV_GPR16;
break;
case 4:
case 32:
iform = SCC_X86_IFORM_MOVSXD_GPRV_GPRZ;
break;
default:
@@ -600,18 +604,18 @@ static void sel_mir(scc_x86_64_isel_t *isel, const scc_lir_instr_t *instr) {
// 将 dest 的地址放入 RDI
scc_x86_operand_value_t dest_op =
scc_x86_lir_val_to_mir_op(isel, &dest_val, 8);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RDI, 8), dest_op);
scc_x86_lir_val_to_mir_op(isel, &dest_val, 64);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RDI, 64), dest_op);
// 将 src 的地址放入 RSI
scc_x86_operand_value_t src_op =
scc_x86_lir_val_to_mir_op(isel, &src_val, 8);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RSI, 8), src_op);
scc_x86_lir_val_to_mir_op(isel, &src_val, 64);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RSI, 64), src_op);
// 长度处理保持不变...
scc_x86_operand_value_t len_op =
scc_x86_lir_val_to_mir_op(isel, &instr->metadata.memcpy.size, 8);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RCX, 8), len_op);
scc_x86_lir_val_to_mir_op(isel, &instr->metadata.memcpy.size, 64);
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RCX, 64), len_op);
add_instr_0(isel, SCC_X86_IFORM_REP_MOVSB);
} break;
@@ -632,9 +636,9 @@ static void sel_func(const scc_lir_module_t *lir_module,
scc_lir_instr_vec_t *instrs = SCC_LIR_BBLOCK_VALUES(bb);
scc_vec_foreach(*instrs, i) {
scc_lir_instr_t *ins = &scc_vec_at(*instrs, i);
// HACK BR size
// HACK BR size_bits
if (ins->op == SCC_LIR_BR) {
ins->size = scc_vec_at(*instrs, i - 1).size;
ins->size_bits = scc_vec_at(*instrs, i - 1).size_bits;
}
sel_mir(isel, ins);
}

View File

@@ -3,63 +3,64 @@
static inline scc_x86_iform_t
scc_mir_x86_mov_reg_mem(scc_x86_operand_value_t op0,
scc_x86_operand_value_t op1) {
Assert(op0.size == op1.size);
Assert(op0.size_bits == op1.size_bits);
Assert(op0.kind == SCC_X86_OPR_REG && op1.kind == SCC_X86_OPR_MEM);
return op0.size == 1 ? SCC_X86_IFORM_MOV_GPR8_MEMB
: SCC_X86_IFORM_MOV_GPRV_MEMV;
return op0.size_bits == 8 ? SCC_X86_IFORM_MOV_GPR8_MEMB
: SCC_X86_IFORM_MOV_GPRV_MEMV;
}
static inline scc_x86_iform_t
scc_mir_x86_mov_reg_reg(scc_x86_operand_value_t op0,
scc_x86_operand_value_t op1) {
Assert(op0.size == op1.size);
Assert(op0.size_bits == op1.size_bits);
Assert(op0.kind == SCC_X86_OPR_REG && op1.kind == SCC_X86_OPR_REG);
return op0.size == 1 ? SCC_X86_IFORM_MOV_GPR8_GPR8_8A
: SCC_X86_IFORM_MOV_GPRV_GPRV_8B;
return op0.size_bits == 8 ? SCC_X86_IFORM_MOV_GPR8_GPR8_8A
: SCC_X86_IFORM_MOV_GPRV_GPRV_8B;
}
static inline scc_x86_iform_t
scc_mir_x86_mov_reg_imm(scc_x86_operand_value_t op0,
scc_x86_operand_value_t op1) {
Assert(op0.size == op1.size);
Assert(op0.size_bits == op1.size_bits);
Assert(op0.kind == SCC_X86_OPR_REG && op1.kind == SCC_X86_OPR_IMM);
return op0.size == 1 ? SCC_X86_IFORM_MOV_GPR8_IMMB_B0
: SCC_X86_IFORM_MOV_GPRV_IMMV;
return op0.size_bits == 8 ? SCC_X86_IFORM_MOV_GPR8_IMMB_B0
: SCC_X86_IFORM_MOV_GPRV_IMMV;
}
static inline scc_x86_iform_t
scc_mir_x86_mov_mem_reg(scc_x86_operand_value_t op0,
scc_x86_operand_value_t op1) {
Assert(op0.size == op1.size);
Assert(op0.size_bits == op1.size_bits);
Assert(op0.kind == SCC_X86_OPR_MEM && op1.kind == SCC_X86_OPR_REG);
return op0.size == 1 ? SCC_X86_IFORM_MOV_MEMB_GPR8
: SCC_X86_IFORM_MOV_MEMV_GPRV;
return op0.size_bits == 8 ? SCC_X86_IFORM_MOV_MEMB_GPR8
: SCC_X86_IFORM_MOV_MEMV_GPRV;
}
static inline scc_x86_iform_t
scc_mir_x86_mov_mem_imm(scc_x86_operand_value_t op0,
scc_x86_operand_value_t op1) {
Assert(op0.size == op1.size);
Assert(op0.size_bits == op1.size_bits);
Assert(op0.kind == SCC_X86_OPR_MEM && op1.kind == SCC_X86_OPR_IMM);
return op0.size == 1 ? SCC_X86_IFORM_MOV_MEMB_IMMB
: SCC_X86_IFORM_MOV_MEMV_IMMZ;
return op0.size_bits == 8 ? SCC_X86_IFORM_MOV_MEMB_IMMB
: SCC_X86_IFORM_MOV_MEMV_IMMZ;
}
static inline u8 get_op_size(scc_x86_operand_value_t op, cbool get_value) {
static inline u8 get_op_size_bits(scc_x86_operand_value_t op, cbool get_value) {
if (get_value) {
return op.size;
return op.size_bits;
}
if (op.kind == SCC_X86_OPR_MEM) {
return 8;
return 64;
}
if (op.kind == SCC_X86_OPR_RELOC && op.reloc.kind == SCC_X86_OPR_MEM) {
return 8;
return 64;
}
return op.size;
return op.size_bits;
}
void scc_x86_emit_move_to_vec(scc_mir_x86_instr_vec_t *vec,
scc_x86_operand_value_t dst,
scc_x86_operand_value_t src) {
u8 dst_size = get_op_size(dst, false);
u8 src_size = get_op_size(src, false);
u8 dst_size = get_op_size_bits(dst, false);
u8 src_size = get_op_size_bits(src, false);
if (dst_size != src_size) {
LOG_FATAL("Mismatched register sizes for move %d != %d", dst_size,
src_size);
@@ -75,7 +76,7 @@ void scc_x86_emit_move_to_vec(scc_mir_x86_instr_vec_t *vec,
} else if (src.kind == SCC_X86_OPR_MEM ||
(src.kind == SCC_X86_OPR_RELOC &&
src.reloc.target == SCC_X86_RELOC_TARGET_SYMBOL)) {
Assert(dst_size == 8);
Assert(dst_size == 64);
scc_mir_x86_instr_2(&ins, SCC_X86_IFORM_LEA_GPRV_AGEN, dst, src,
scc_pos_create());
} else {
@@ -100,8 +101,8 @@ void scc_x86_emit_move_to_vec(scc_mir_x86_instr_vec_t *vec,
void scc_x86_emit_load_to_vec(scc_mir_x86_instr_vec_t *vec,
scc_x86_operand_value_t dst,
scc_x86_operand_value_t src_addr) {
u8 dst_size = get_op_size(dst, false);
u8 src_addr_size = get_op_size(src_addr, true);
u8 dst_size = get_op_size_bits(dst, false);
u8 src_addr_size = get_op_size_bits(src_addr, true);
if (dst_size != src_addr_size) {
LOG_FATAL("Mismatched sizes for load %d != %d", dst_size,
src_addr_size);
@@ -117,9 +118,9 @@ void scc_x86_emit_load_to_vec(scc_mir_x86_instr_vec_t *vec,
.index = SCC_X86_REG_INVALID,
.scale = 1,
.disp.displacement = 0,
.disp.displacement_bits = src_addr_size * 8,
.disp.displacement_bits = src_addr_size,
},
.size = src_addr_size,
.size_bits = src_addr_size,
};
} else if (src_addr.kind == SCC_X86_OPR_MEM) {
mem_op = src_addr;
@@ -135,8 +136,8 @@ void scc_x86_emit_load_to_vec(scc_mir_x86_instr_vec_t *vec,
void scc_x86_emit_store_to_vec(scc_mir_x86_instr_vec_t *vec,
scc_x86_operand_value_t dst_addr,
scc_x86_operand_value_t src) {
u8 dst_addr_size = get_op_size(dst_addr, true);
u8 src_size = get_op_size(src, false);
u8 dst_addr_size = get_op_size_bits(dst_addr, true);
u8 src_size = get_op_size_bits(src, false);
if (dst_addr_size != src_size) {
LOG_FATAL("Mismatched sizes for store %d != %d", dst_addr_size,
src_size);
@@ -151,9 +152,9 @@ void scc_x86_emit_store_to_vec(scc_mir_x86_instr_vec_t *vec,
.index = SCC_X86_REG_INVALID,
.scale = 1,
.disp.displacement = 0,
.disp.displacement_bits = dst_addr_size * 8,
.disp.displacement_bits = dst_addr_size,
},
.size = dst_addr_size,
.size_bits = dst_addr_size,
};
} else if (dst_addr.kind == SCC_X86_OPR_MEM) {
mem_op = dst_addr;

View File

@@ -179,7 +179,7 @@ static void x86_alloc_iter_begin(scc_reg_alloc_iter_t *iter) {
}
static cbool x86_alloc_iter_next(scc_reg_alloc_iter_t *iter, int *out_vreg,
int *out_size,
int *out_size_bits,
scc_reg_op_access_t *out_access) {
const scc_mir_x86_instr_t *ins = (const scc_mir_x86_instr_t *)iter->instr;
scc_x86_iform_t opcode = ins->x86_instr.opcode;
@@ -191,7 +191,7 @@ static cbool x86_alloc_iter_next(scc_reg_alloc_iter_t *iter, int *out_vreg,
scc_reg_op_access_t base_access =
get_operand_access(opcode, iter->op_idx);
*out_size = op->size;
*out_size_bits = op->size_bits;
if (op->kind == SCC_X86_OPR_REG) {
if (iter->op_sub_idx == 0 && scc_x86_op_is_vreg(op)) {
*out_vreg = scc_x86_op_get_vreg(op);
@@ -204,7 +204,7 @@ static cbool x86_alloc_iter_next(scc_reg_alloc_iter_t *iter, int *out_vreg,
continue;
} else if (op->kind == SCC_X86_OPR_MEM) {
const scc_x86_mem_t *mem = &op->mem;
*out_size = 8;
*out_size_bits = 64;
// 子索引 0: 基址寄存器
if (iter->op_sub_idx == 0) {
if (mem->base != SCC_X86_REG_INVALID &&

View File

@@ -23,7 +23,7 @@ void scc_mir_dump_bblock(scc_mir_dump_ctx_t *ctx, const scc_mir_func_t *func,
switch (instr->opcode) {
case SCC_MIR_PSEUDO_ALLOCA:
scc_tree_dump_append_fmt(td, " alloca(%d)",
instr->data.alloc.size);
instr->data.alloc.size_bits);
break;
default:
break;

View File

@@ -41,7 +41,7 @@ static void frame_layout_impl(scc_frame_layout_t *ctx,
.index = SCC_X86_REG_INVALID,
.scale = 1,
},
op->size);
op->size_bits);
}
}
}
@@ -82,7 +82,7 @@ static void frame_layout_impl(scc_frame_layout_t *ctx,
.index = SCC_X86_REG_INVALID,
.scale = 1,
},
op->size);
op->size_bits);
}
}
}
@@ -118,7 +118,7 @@ static void prologue(scc_mir_instr_vec_t *userdata,
/// FILL to shadow space
}
u8 size = 8;
u8 size = 64;
// sub rsp, frame_size
if (frame_size > 0) {
scc_mir_x86_instr_2(&instr, SCC_X86_IFORM_SUB_GPRV_IMMZ,
@@ -141,7 +141,7 @@ static void epilogue(scc_mir_instr_vec_t *userdata,
*/
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(func);
int frame_size = meta->frame_size;
u8 size = 8;
u8 size = 64;
// add rsp, frame_size
if (frame_size > 0) {
scc_mir_x86_instr_2(&instr, SCC_X86_IFORM_ADD_GPRV_IMMZ,
@@ -178,7 +178,7 @@ https://learn.microsoft.com/zh-cn/cpp/build/x64-calling-convention?view=msvc-180
static void lower_call(void *userdata, const scc_lir_instr_t *instr) {
scc_x86_64_isel_t *isel = userdata;
u8 size = 8;
u8 size = 64;
scc_mir_func_meta_t *meta = SCC_MIR_FUNC_META(isel->func);
int call_stack_size = instr->metadata.call.arg_count * 8;
if (meta->frame_size < call_stack_size) {
@@ -233,7 +233,7 @@ static void lower_call(void *userdata, const scc_lir_instr_t *instr) {
Panic("unhandled opcode");
}
int ret_size = instr->size;
int ret_size = instr->size_bits;
scc_x86_operand_value_t ret_reg =
scc_x86_lir_val_to_mir_op(isel, &instr->to, ret_size);
if (ret_reg.kind != SCC_X86_OPR_NONE && ret_size != 0) {
@@ -265,7 +265,7 @@ static void lower_param(void *userdata, const scc_lir_val_t *val,
void *out_op) {
scc_x86_operand_value_t *out = out_op;
Assert(val->kind == SCC_LIR_INSTR_KIND_ARG);
u8 size = 8;
u8 size = 64;
switch (val->data.arg) {
case 0:
*out = scc_x86_op_preg(SCC_X86_REG_RCX, size);
@@ -292,10 +292,10 @@ static void lower_ret(void *userdata, const scc_lir_instr_t *instr) {
scc_x86_64_isel_t *isel = userdata;
scc_lir_val_t ret_val = instr->metadata.ret_val;
u8 size = 0;
if (instr->size) {
size = instr->size;
if (instr->size_bits) {
size = instr->size_bits;
} else {
size = 8;
size = 64;
}
if (ret_val.kind != SCC_LIR_INSTR_KIND_NONE) {
scc_x86_emit_move(isel, scc_x86_op_preg(SCC_X86_REG_RAX, size),