stage1 初步实现

This commit is contained in:
zzy
2026-08-06 19:26:30 +08:00
parent a56b4cbb70
commit 314100afbc
35 changed files with 556 additions and 2236 deletions

View File

@@ -709,7 +709,16 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
emit_value(fc, n->arith.left);
if (n->arith.right)
emit_value(fc, n->arith.right);
emit_arith(fc, arith_op(n->kind, is_signed_type(ty, tid)), arith_tag(ty, tid));
spl_opcode_t aop = arith_op(n->kind, is_signed_type(ty, tid));
/* 浮点除法/取余VM 的 DIV_S/REM_S 宏DIV_REM_S含 float 分支DIV_U/REM_U 无 */
spl_type_node_t *at = tn(ty, under(ty, tid));
if (at && at->kind == SPL_TYPE_FLOAT) {
if (n->kind == SPL_IR_ARITH_DIV)
aop = SPL_DIV_S;
else if (n->kind == SPL_IR_ARITH_REM)
aop = SPL_REM_S;
}
emit_arith(fc, aop, arith_tag(ty, tid));
emit_store_vreg(fc, ref);
return;
}
@@ -753,6 +762,11 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
emit_value(fc, n->cmp.a);
emit_value(fc, n->cmp.b);
spl_opcode_t op;
/* 浮点顺序比较VM 的 CMP_U 无 float 分支,须走 CMP_SSLT/SLE/SGT/SGE 含 float case */
int is_f = 0;
spl_type_node_t *ct = tn(ty, under(ty, tid));
if (ct && ct->kind == SPL_TYPE_FLOAT)
is_f = 1;
switch (n->kind) {
case SPL_IR_CMP_EQ:
op = SPL_EQ;
@@ -761,16 +775,16 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
op = SPL_NE;
break;
case SPL_IR_CMP_LT:
op = is_signed_type(ty, tid) ? SPL_SLT : SPL_ULT;
op = (is_signed_type(ty, tid) || is_f) ? SPL_SLT : SPL_ULT;
break;
case SPL_IR_CMP_LE:
op = is_signed_type(ty, tid) ? SPL_SLE : SPL_ULE;
op = (is_signed_type(ty, tid) || is_f) ? SPL_SLE : SPL_ULE;
break;
case SPL_IR_CMP_GT:
op = is_signed_type(ty, tid) ? SPL_SGT : SPL_UGT;
op = (is_signed_type(ty, tid) || is_f) ? SPL_SGT : SPL_UGT;
break;
default:
op = is_signed_type(ty, tid) ? SPL_SGE : SPL_UGE;
op = (is_signed_type(ty, tid) || is_f) ? SPL_SGE : SPL_UGE;
break;
}
emit_arith(fc, op, arith_tag(ty, tid));
@@ -845,8 +859,13 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
case SPL_IR_MEM_OFFSET: {
emit_value(fc, n->mem_offset.ptr);
emit_value(fc, n->mem_offset.offset);
emit_push(fc, type_size(ty, n->mem_offset.tid));
emit_arith(fc, SPL_MUL, SPL_USIZE);
/* 指针运算C 语义):*_void 元素)看成整数,偏移即字节、不 scale
* *T非 void偏移为元素索引乘 sizeof(T)。 */
spl_type_id_t ut = under(ty, n->mem_offset.tid);
if (!is_void(ty, ut)) {
emit_push(fc, type_size(ty, n->mem_offset.tid));
emit_arith(fc, SPL_MUL, SPL_USIZE);
}
emit_arith(fc, SPL_ADD, SPL_USIZE);
emit_store_vreg(fc, ref);
return;
@@ -1032,14 +1051,18 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
vec_push(fc->c->fnfixes, fx);
add_insn(fc, SPL_CALL, SPL_VOID, nargs);
}
if (ret && !is_agg(ty, ret))
emit_store_vreg(fc, ref);
} else {
/* 间接调用:栈 [args, func_addr, nargs] CALLI */
emit_value(fc, n->control_call.func);
/* 间接调用:栈 [args, nargs, func_addr] CALLIVM: POP addr, POP nargs
* 先 push 实参(上方循环),再 push nargs最后 push func_addr */
emit_push(fc, nargs);
emit_value(fc, n->control_call.func);
add_insn(fc, SPL_CALLI, SPL_VOID, 0);
/* 返回值留在栈顶,与直接调用一致:存入 vreg */
if (ret && !is_agg(ty, ret))
emit_store_vreg(fc, ref);
}
if (ret && !is_agg(ty, ret))
emit_store_vreg(fc, ref);
return;
}
case SPL_IR_CONTROL_RET: {
@@ -1065,10 +1088,12 @@ static void emit_node(fctx_t *fc, spl_ir_node_ref_t ref) {
return;
}
case SPL_IR_CONTROL_UNREACHABLE:
case SPL_IR_CONTROL_TRAP:
diag(fc->c, fc->fid, ref, "control.unreachable/trap not implemented");
add_insn(fc, SPL_HALT, SPL_VOID, 0);
return;
case SPL_IR_CONTROL_TRAP:
/* trap → halt 带非零退出码assert 失败语义) */
add_insn(fc, SPL_HALT, SPL_VOID, 1);
return;
case SPL_IR_DBG_BREAKPOINT:
add_insn(fc, SPL_BK, SPL_VOID, 0);
return;
@@ -1185,8 +1210,9 @@ static void gen_func(ctx_t *c, spl_ir_func_ref_t fid) {
usize locals = 0;
for (usize ref = 1; ref < fc.f->nodes.size; ref++) {
spl_ir_node_t *rn = &fc.f->nodes.data[ref];
if (!produces_value(rn->kind))
continue;
/* 无条件分配(不按 produces_value 过滤):某些节点 produces_value 误报 0 但
* 仍会被 emit_value 引用并 store_vreg如聚合字段提取编译成的节点。若跳过则
* vreg_off 保持 calloc 的 0多个节点共享槽 0 互相覆盖(指针偏移/写地址损坏根源)。 */
spl_type_id_t tid = 0;
if (!needs_vreg_slot(fc.f, ref)) {
/* 聚合值参数:分配 vregprologue 从参数区 memcpy 进来) */
@@ -1200,8 +1226,13 @@ static void gen_func(ctx_t *c, spl_ir_func_ref_t fid) {
if (rn->kind == SPL_IR_MEM_ALLOCA)
tid = rn->mem_alloc.tid;
}
if (!tid)
if (!tid) {
/* tid 未解析MEM_LOAD / BITCAST 未标 tid 等):占位一个 usize 槽,
* 否则 vreg_off 保持 0多个节点共享槽 0 互相覆盖。 */
fc.vreg_off[ref] = align_up(locals, 8);
locals = fc.vreg_off[ref] + 8;
continue;
}
usize sz = type_size(ty, tid);
usize al = type_align(ty, tid);
if (is_agg(ty, tid))
@@ -1211,7 +1242,9 @@ static void gen_func(ctx_t *c, spl_ir_func_ref_t fid) {
locals += sz;
}
fc.temp_off = align_up(locals, 8);
locals = fc.temp_off + 8; /* mem.set 计数器槽 */
/* 临时区bytes表达式/调用的 PUSH/POP 堆叠、store/bnz 的弹栈会临时压低 sp
* 若无此区 sp 会降入 vreg 槽区覆盖尚未使用的 vreg大数组构造等深表达式。 */
locals = fc.temp_off + 8 + 1024 * 8;
fc.locals_bytes = locals;
/* prologueALLOC + 聚合值参数 memcpy参数区 → param vreg */