stage1 初步实现
This commit is contained in:
@@ -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_S(SLT/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] CALLI(VM: 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)) {
|
||||
/* 聚合值参数:分配 vreg(prologue 从参数区 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;
|
||||
|
||||
/* prologue:ALLOC + 聚合值参数 memcpy(参数区 → param vreg) */
|
||||
|
||||
Reference in New Issue
Block a user