feat(funcattrs): 支持 stackrealign 函数属性

入口函数(_start)由 bootloader jmp 进入(rsp≡0 mod 16),llc 按 call 约定
假设入口 rsp≡8 → 帧整体偏 8 → 所有调用 rsp≡8 → 变参函数保存 xmm 的
movaps #GP。新增 t.attr.stackrealign → LLVM stackrealign 属性,序言动态
重对齐栈,与入口约定无关。
This commit is contained in:
TermiNexus committed 2026-08-26 20:18:01 +08:00
1 parent 9f19673072
commit 2165c171e7
1 file changed
+58 -1
+58 -1
View File
@@ -142,6 +142,12 @@ class FuncGenBase(CallGenBase.CallGenBase):
llvm_name = "nounwind"
elif string.strcmp(attr_name, "noredzone") == 0:
llvm_name = "noredzone"
elif string.strcmp(attr_name, "stackrealign") == 0:
# 动态重对齐栈(LLVM 序言 and rsp,-16)。入口函数(_start)由 bootloader
# jmp 进入(rsp≡0 mod 16),而 llc 按 call 约定假设入口 rsp≡8 → 帧整体
# 偏 8 → 所有调用 rsp≡8 → 变参函数保存 xmm 的 movaps #GP。stackrealign
# 使序言动态对齐,与入口约定无关(sched started 后 movaps #GP 根因)。
llvm_name = "stackrealign"
elif string.strcmp(attr_name, "willreturn") == 0:
llvm_name = "willreturn"
elif string.strcmp(attr_name, "mustprogress") == 0:
@@ -283,6 +289,57 @@ class FuncGenBase(CallGenBase.CallGenBase):
return 1
return 0
# ============================================================
# _resolve_creturn_ret_ty - @c.CReturn(ty1, ty2, ...) → 多返回 struct 类型
#
# 对齐 TPC DeclarationGenerator:CReturn 声明函数返回多个值(如
# GetMemoryStats @c.CReturn(t.CUInt64T, t.CUInt64T, t.CUInt64T) →
# {i64, i64, i64})。pre_scan 前向声明与 translate_function_def 定义
# 两阶段必须一致,否则 declare i32 + define {i64,i64,i64} → llc
# "ret doesn't match function result type"。
# ============================================================
def _resolve_creturn_ret_ty(self, pool: memhub.MemBuddy | t.CPtr,
fd: ast.FunctionDef | t.CPtr,
imported_modules: str,
from_imports: str,
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
"""解析 @c.CReturn 装饰器为 struct 返回类型;无 CReturn 返回 None"""
if fd is None or fd.decorator_list is None:
return None
cr_head: llvmlite.ParamNode | t.CPtr = None
cr_last: llvmlite.ParamNode | t.CPtr = None
cr_count: int = 0
cr_dn: t.CSizeT = len(fd.decorator_list)
for cdi in range(cr_dn):
deco_cr: ast.AST | t.CPtr = fd.decorator_list.get(cdi)
if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call:
continue
deco_call_cr: ast.Call | t.CPtr = (ast.Call | t.CPtr)(deco_cr)
if deco_call_cr.func is None or deco_call_cr.func.kind() != ast.ASTKind.Attribute:
continue
deco_fa_cr: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(deco_call_cr.func)
if deco_fa_cr.attr is None or string.strcmp(deco_fa_cr.attr, "CReturn") != 0:
continue
cr_args: list[ast.AST | t.CPtr] | t.CPtr = deco_call_cr.args
if cr_args is None:
continue
cr_an: t.CSizeT = len(cr_args)
for cai in range(cr_an):
cr_aty: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type(
pool, cr_args.get(cai), imported_modules, from_imports, trans, 0)
if cr_aty is None:
continue
cr_pn: llvmlite.ParamNode | t.CPtr = llvmlite.new_param_node(pool, cr_aty)
if cr_pn is not None:
if cr_head is None:
cr_head = cr_pn
else:
cr_last.Next = cr_pn
cr_last = cr_pn
cr_count += 1
if cr_head is not None and cr_count > 0:
return llvmlite.Struct(pool, cr_head, cr_count, None)
return None
# ============================================================
# 创建 LLVM 函数(简单版本,仅声明)
# ============================================================
def create_function(self, pool: memhub.MemBuddy | t.CPtr,
@@ -316,7 +373,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
param_ty: llvmlite.LLVMType | t.CPtr = i32_ty
if arg.annotation is not None:
resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type(
pool, arg.annotation, None, None, None)
pool, arg.annotation, None, None, None, 0)
if resolved is not None:
param_ty = resolved
pname: str = pool.alloc(32)