diff --git a/Test/TestFBProject/App/main.vp b/Test/TestFBProject/App/main.vp index e107a17..0ca823f 100644 --- a/Test/TestFBProject/App/main.vp +++ b/Test/TestFBProject/App/main.vp @@ -138,7 +138,8 @@ def main() -> t.CInt | t.CExport: testcheck.section("Test LLVMIR: inline LLVM IR add") x: t.CInt = 10 y: t.CInt = 20 - r: t.CInt = c.LLVMIR(f"add i32 {c.LInp(x)}, {c.LInp(y)}", t.CInt) + r: t.CInt + c.LLVMIR(f"{c.LOut(r)} = add i32 {c.LInp(x)}, {c.LInp(y)}") print("LLVMIR add result:", r) testcheck.check(r == 30, "LLVMIR add (10+20=30)", "LLVMIR add result mismatch") @@ -152,7 +153,7 @@ def main() -> t.CInt | t.CExport: testcheck.section("Test LLVMIR with LOut") out_val: t.CInt = 0 - c.LLVMIR(f"{c.LOut(out_val)} = add i32 {c.LInp(x)}, {c.LInp(y)}", t.CInt) + c.LLVMIR(f"{c.LOut(out_val)} = add i32 {c.LInp(x)}, {c.LInp(y)}") print("LLVMIR LOut result:", out_val) testcheck.check(out_val == 30, "LLVMIR LOut (10+20=30)", "LLVMIR LOut result mismatch") diff --git a/includes/vipersimd.vp b/includes/vipersimd.vp index 53b0f22..e567495 100644 --- a/includes/vipersimd.vp +++ b/includes/vipersimd.vp @@ -378,42 +378,58 @@ vzeroupper""", def simd_sqrt(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: sqrt(x)""" - return c.LLVMIR(f"call double @llvm.sqrt.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.sqrt.f64(double {c.LInp(x)})") + return out def simd_fabs(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: |x|""" - return c.LLVMIR(f"call double @llvm.fabs.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.fabs.f64(double {c.LInp(x)})") + return out def simd_floor(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: floor(x)""" - return c.LLVMIR(f"call double @llvm.floor.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.floor.f64(double {c.LInp(x)})") + return out def simd_ceil(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: ceil(x)""" - return c.LLVMIR(f"call double @llvm.ceil.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.ceil.f64(double {c.LInp(x)})") + return out def simd_round(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: round(x)""" - return c.LLVMIR(f"call double @llvm.round.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.round.f64(double {c.LInp(x)})") + return out def simd_trunc(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: trunc(x)""" - return c.LLVMIR(f"call double @llvm.trunc.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.trunc.f64(double {c.LInp(x)})") + return out def simd_fma(a: t.CDouble, b: t.CDouble, c_val: t.CDouble) -> t.CDouble: """LLVM intrinsic: a*b + c (single rounding)""" - return c.LLVMIR(f"call double @llvm.fma.f64(double {c.LInp(a)}, double {c.LInp(b)}, double {c.LInp(c_val)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.fma.f64(double {c.LInp(a)}, double {c.LInp(b)}, double {c.LInp(c_val)})") + return out def simd_copysign(mag: t.CDouble, sign: t.CDouble) -> t.CDouble: """LLVM intrinsic: copysign(mag, sign)""" - return c.LLVMIR(f"call double @llvm.copysign.f64(double {c.LInp(mag)}, double {c.LInp(sign)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.copysign.f64(double {c.LInp(mag)}, double {c.LInp(sign)})") + return out def simd_neg(x: t.CDouble) -> t.CDouble: @@ -422,39 +438,55 @@ def simd_neg(x: t.CDouble) -> t.CDouble: copysign(x, -1.0) is wrong for x < 0 (returns -|x| instead of +|x|). copysign(x, -x) = |x| * sign(-x) = -x is correct for all IEEE 754 values. """ - return c.LLVMIR(f"call double @llvm.copysign.f64(double {c.LInp(x)}, double {c.LInp(t.CDouble(0.0) - x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.copysign.f64(double {c.LInp(x)}, double {c.LInp(t.CDouble(0.0) - x)})") + return out def simd_minnum(a: t.CDouble, b: t.CDouble) -> t.CDouble: """LLVM intrinsic: min(a, b) (NaN-aware)""" - return c.LLVMIR(f"call double @llvm.minnum.f64(double {c.LInp(a)}, double {c.LInp(b)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.minnum.f64(double {c.LInp(a)}, double {c.LInp(b)})") + return out def simd_maxnum(a: t.CDouble, b: t.CDouble) -> t.CDouble: """LLVM intrinsic: max(a, b) (NaN-aware)""" - return c.LLVMIR(f"call double @llvm.maxnum.f64(double {c.LInp(a)}, double {c.LInp(b)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.maxnum.f64(double {c.LInp(a)}, double {c.LInp(b)})") + return out def simd_exp(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: e^x""" - return c.LLVMIR(f"call double @llvm.exp.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.exp.f64(double {c.LInp(x)})") + return out def simd_log(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: ln(x)""" - return c.LLVMIR(f"call double @llvm.log.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.log.f64(double {c.LInp(x)})") + return out def simd_sin(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: sin(x)""" - return c.LLVMIR(f"call double @llvm.sin.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.sin.f64(double {c.LInp(x)})") + return out def simd_cos(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: cos(x)""" - return c.LLVMIR(f"call double @llvm.cos.f64(double {c.LInp(x)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.cos.f64(double {c.LInp(x)})") + return out def simd_pow(x: t.CDouble, y: t.CDouble) -> t.CDouble: """LLVM intrinsic: x^y""" - return c.LLVMIR(f"call double @llvm.pow.f64(double {c.LInp(x)}, double {c.LInp(y)})", t.CDouble) + out: t.CDouble + c.LLVMIR(f"{c.LOut(out)} = call double @llvm.pow.f64(double {c.LInp(x)}, double {c.LInp(y)})") + return out diff --git a/lib/includes/c.py b/lib/includes/c.py index 5881be5..c24a3db 100644 --- a/lib/includes/c.py +++ b/lib/includes/c.py @@ -615,13 +615,14 @@ class CUndef: class LLVMIR: - """内联 LLVM IR - - 用法: c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt) - 或: c.LLVMIR(f"%{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt) - - c.LInp(expr) - 输入操作数,翻译后替换为对应的 LLVM 临时变量名 - c.LOut(expr) - 输出操作数,翻译后替换为对应的 LLVM 临时变量名 + """内联 LLVM IR(无返回值,直接嵌入原始 IR 文本) + + 用法: c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}") + 或: c.LLVMIR(f"{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}") + + c.LInp(expr) - 输入操作数,替换为 expr 的 LLVM 值引用文本(%x 或常量) + c.LOut(expr) - 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN, + 模板嵌入后自动追加 store 写回变量 alloca """ def __init__(self, ir_template: Any, ret_type: Any = None) -> None: self.ir_template: Any = ir_template diff --git a/wiki/08-c-operations.md b/wiki/08-c-operations.md index 253a74c..2c51ac0 100644 --- a/wiki/08-c-operations.md +++ b/wiki/08-c-operations.md @@ -284,10 +284,10 @@ errno: t.CExtern | t.CInt # extern int errno; ### c.LLVMIR -直接嵌入 LLVM IR 指令来实现高效且跨平台的汇编操作: +直接嵌入原始 LLVM IR 文本来实现高效且跨平台的汇编操作(无返回值、不做指令解析): ```python -c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt) +c.LLVMIR(f"{c.LOut(r)} = add i32 {c.LInp(a)}, {c.LInp(b)}") ``` ### c.LInp / c.LOut @@ -295,8 +295,9 @@ c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt) 标记 LLVM IR 的输入/输出操作数: ```python -c.LInp(expr) # 输入操作数 -c.LOut(expr) # 输出操作数 +c.LInp(expr) # 输入操作数:替换为 expr 的 LLVM 值引用文本(%x 或常量文本) +c.LOut(expr) # 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN, + # 模板嵌入后自动追加 store 写回变量 alloca ``` ## 运算符重载