import t, c # ============================================================ # AVX2 双精度向量运算 (4 x double, 256-bit YMM) # ============================================================ def simd_add4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] + b[0:4]""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vaddpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_sub4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] - b[0:4]""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vsubpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_mul4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] * b[0:4]""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vmulpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_div4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] / b[0:4]""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vdivpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_sqrt4d(a: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = sqrt(a[0:4])""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vsqrtpd ymm0, ymm0 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0']) def simd_neg4d(a: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = -a[0:4] (flip sign bit via XOR)""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vpcmpeqd ymm1, ymm1, ymm1 vpsllq ymm1, ymm1, 63 vxorpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_abs4d(a: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = |a[0:4]| (clear sign bit via ANDN)""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vpcmpeqd ymm1, ymm1, ymm1 vpsllq ymm1, ymm1, 63 vandnpd ymm0, ymm1, ymm0 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_max4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = max(a[0:4], b[0:4])""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vmaxpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_min4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = min(a[0:4], b[0:4])""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vminpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_mul_scalar4d(a: t.CPtr, scalar: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] * scalar (broadcast)""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vbroadcastsd ymm1, [{c.AsmInp(scalar, t.ASM_DESCR.REG_ANY)}] vmulpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_add_scalar4d(a: t.CPtr, scalar: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4] + scalar (broadcast)""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vbroadcastsd ymm1, [{c.AsmInp(scalar, t.ASM_DESCR.REG_ANY)}] vaddpd ymm0, ymm0, ymm1 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_hsum4d(a: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0] = a[0]+a[1]+a[2]+a[3] (horizontal sum)""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vextractf128 xmm1, ymm0, 1 vaddpd xmm0, xmm0, xmm1 vhaddpd xmm0, xmm0, xmm0 vmovsd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_dot4d(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0] = dot(a[0:4], b[0:4])""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vmulpd ymm0, ymm0, ymm1 vextractf128 xmm1, ymm0, 1 vaddpd xmm0, xmm0, xmm1 vhaddpd xmm0, xmm0, xmm0 vmovsd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1']) def simd_fma4d(a: t.CPtr, b: t.CPtr, c_val: t.CPtr, out: t.CPtr) -> t.CVoid: """AVX2: out[0:4] = a[0:4]*b[0:4] + c[0:4] (fused multiply-add) Uses vfmadd213pd: ymm0 = ymm1 * ymm0 + ymm2 Load order: b->ymm0, a->ymm1, c->ymm2""" c.Asm(f"""vmovupd ymm0, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] vmovupd ymm1, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] vmovupd ymm2, [{c.AsmInp(c_val, t.ASM_DESCR.REG_ANY)}] vfmadd213pd ymm0, ymm1, ymm2 vmovupd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], ymm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'ymm2']) # ============================================================ # SSE2 单精度向量运算 (4 x float, 128-bit XMM) # ============================================================ def simd_add4f(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """SSE2: out[0:4] = a[0:4] + b[0:4] (float)""" c.Asm(f"""movups xmm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] movups xmm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] addps xmm0, xmm1 movups [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'xmm0', 'xmm1']) def simd_sub4f(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """SSE2: out[0:4] = a[0:4] - b[0:4] (float)""" c.Asm(f"""movups xmm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] movups xmm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] subps xmm0, xmm1 movups [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'xmm0', 'xmm1']) def simd_mul4f(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """SSE2: out[0:4] = a[0:4] * b[0:4] (float)""" c.Asm(f"""movups xmm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] movups xmm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] mulps xmm0, xmm1 movups [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'xmm0', 'xmm1']) def simd_div4f(a: t.CPtr, b: t.CPtr, out: t.CPtr) -> t.CVoid: """SSE2: out[0:4] = a[0:4] / b[0:4] (float)""" c.Asm(f"""movups xmm0, [{c.AsmInp(a, t.ASM_DESCR.REG_ANY)}] movups xmm1, [{c.AsmInp(b, t.ASM_DESCR.REG_ANY)}] divps xmm0, xmm1 movups [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm0""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'xmm0', 'xmm1']) # ============================================================ # 批量数组运算 (AVX2 循环, 处理 N 个 double) # ============================================================ def simd_add_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = a[i:i+4] + b[i:i+4], i=0,4,8,...""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r9, {c.AsmInp(b, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} test rcx, rcx jz .Ladd_end .Ladd_loop: vmovupd ymm0, [r8] vmovupd ymm1, [r9] vaddpd ymm0, ymm0, ymm1 vmovupd [r10], ymm0 add r8, 32 add r9, 32 add r10, 32 dec rcx jnz .Ladd_loop .Ladd_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'rcx', 'r8', 'r9', 'r10']) def simd_sub_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = a[i:i+4] - b[i:i+4]""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r9, {c.AsmInp(b, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} test rcx, rcx jz .Lsub_end .Lsub_loop: vmovupd ymm0, [r8] vmovupd ymm1, [r9] vsubpd ymm0, ymm0, ymm1 vmovupd [r10], ymm0 add r8, 32 add r9, 32 add r10, 32 dec rcx jnz .Lsub_loop .Lsub_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'rcx', 'r8', 'r9', 'r10']) def simd_mul_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = a[i:i+4] * b[i:i+4]""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r9, {c.AsmInp(b, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} test rcx, rcx jz .Lmul_end .Lmul_loop: vmovupd ymm0, [r8] vmovupd ymm1, [r9] vmulpd ymm0, ymm0, ymm1 vmovupd [r10], ymm0 add r8, 32 add r9, 32 add r10, 32 dec rcx jnz .Lmul_loop .Lmul_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'rcx', 'r8', 'r9', 'r10']) def simd_div_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = a[i:i+4] / b[i:i+4]""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r9, {c.AsmInp(b, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} test rcx, rcx jz .Ldiv_end .Ldiv_loop: vmovupd ymm0, [r8] vmovupd ymm1, [r9] vdivpd ymm0, ymm0, ymm1 vmovupd [r10], ymm0 add r8, 32 add r9, 32 add r10, 32 dec rcx jnz .Ldiv_loop .Ldiv_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'rcx', 'r8', 'r9', 'r10']) def simd_sqrt_array(a: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = sqrt(a[i:i+4])""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} test rcx, rcx jz .Lsqrt_end .Lsqrt_loop: vmovupd ymm0, [r8] vsqrtpd ymm0, ymm0 vmovupd [r10], ymm0 add r8, 32 add r10, 32 dec rcx jnz .Lsqrt_loop .Lsqrt_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'rcx', 'r8', 'r10']) def simd_abs_array(a: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = |a[i:i+4]|""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} vpcmpeqd ymm2, ymm2, ymm2 vpsllq ymm2, ymm2, 63 test rcx, rcx jz .Labs_end .Labs_loop: vmovupd ymm0, [r8] vandnpd ymm0, ymm2, ymm0 vmovupd [r10], ymm0 add r8, 32 add r10, 32 dec rcx jnz .Labs_loop .Labs_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm2', 'rcx', 'r8', 'r10']) def simd_neg_array(a: t.CPtr, out: t.CPtr, n: t.CSizeT) -> t.CVoid: """AVX2 batch: out[i:i+4] = -a[i:i+4] (flip sign bit via XOR)""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r10, {c.AsmInp(out, t.ASM_DESCR.REG_ANY)} vpcmpeqd ymm2, ymm2, ymm2 vpsllq ymm2, ymm2, 63 test rcx, rcx jz .Lneg_end .Lneg_loop: vmovupd ymm0, [r8] vxorpd ymm0, ymm0, ymm2 vmovupd [r10], ymm0 add r8, 32 add r10, 32 dec rcx jnz .Lneg_loop .Lneg_end: vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm2', 'rcx', 'r8', 'r10']) def simd_dot_array(a: t.CPtr, b: t.CPtr, n: t.CSizeT, out: t.CPtr) -> t.CVoid: """AVX2 batch: out[0] = dot(a[0:n], b[0:n]) using FMA accumulation""" c.Asm(f"""mov rcx, {c.AsmInp(n, t.ASM_DESCR.REG_ANY)} shr rcx, 2 mov r8, {c.AsmInp(a, t.ASM_DESCR.REG_ANY)} mov r9, {c.AsmInp(b, t.ASM_DESCR.REG_ANY)} vxorpd ymm2, ymm2, ymm2 test rcx, rcx jz .Ldot_end .Ldot_loop: vmovupd ymm0, [r8] vmovupd ymm1, [r9] vfmadd231pd ymm2, ymm0, ymm1 add r8, 32 add r9, 32 dec rcx jnz .Ldot_loop .Ldot_end: vextractf128 xmm1, ymm2, 1 vaddpd xmm2, xmm2, xmm1 vhaddpd xmm2, xmm2, xmm2 vmovsd [{c.AsmInp(out, t.ASM_DESCR.REG_ANY)}], xmm2 vzeroupper""", op=[t.ASM_DESCR.CLOBBER_MEMORY, 'ymm0', 'ymm1', 'ymm2', 'rcx', 'r8', 'r9']) # ============================================================ # LLVMIR 精确标量运算 (LLVM 内置函数) # ============================================================ 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) 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) 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) 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) 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) 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) 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) 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) def simd_neg(x: t.CDouble) -> t.CDouble: """LLVM intrinsic: -x (via copysign, correct for negative/-0.0/NaN inputs) 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) 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) 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) 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) 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) 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) 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) 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)