// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause // Differential kernel for the arm64 SIMD arrangement bits: the FP one-bit // size field (S=0, D=1 at bit 22), the immh field of the long extends, the // narrow family's fixed bit 16, the SSHL/USHL size bits, the scalar D forms // of the bare VADD/VSUB spellings and the INS lane packing. Every function // is byte-compared against go tool asm. #include "textflag.h" // func fpthree() TEXT ·fpthree(SB), NOSPLIT, $0-0 VFADD V0.S4, V0.S4, V1.S4 VFADD V0.D2, V0.D2, V1.D2 VFMUL V0.S4, V0.S4, V1.S4 VFMUL V0.D2, V0.D2, V1.D2 VFDIV V0.S4, V0.S4, V1.S4 VFDIV V0.D2, V0.D2, V1.D2 VFMLA V1.D2, V12.D2, V1.D2 VFMLA V1.S2, V12.S2, V1.S2 VFMLA V1.S4, V12.S4, V1.S4 VFMAX V3.S4, V2.S4, V1.S4 VFMAXNM V3.S4, V2.S4, V1.S4 VFADDP V3.D2, V2.D2, V1.D2 VFCMEQ V1.S4, V2.S4, V3.S4 VFCMGE V1.S4, V2.S4, V3.S4 RET // func fpunary() TEXT ·fpunary(SB), NOSPLIT, $0-0 VFABS V0.D2, V1.D2 VFNEG V0.D2, V1.D2 VFSQRT V0.D2, V1.D2 VFRINTN V0.D2, V1.D2 VFRINTP V0.D2, V1.D2 VFRINTM V0.D2, V1.D2 VFRINTZ V0.D2, V1.D2 VFCVTZS V1.D2, V2.D2 VFCVTZU V1.D2, V2.D2 VSCVTF V1.D2, V2.D2 VUCVTF V1.D2, V2.D2 VFABS V0.S4, V1.S4 VSCVTF V1.S4, V2.S4 VFNEG V0.S2, V1.S2 RET // func shifts() TEXT ·shifts(SB), NOSPLIT, $0-0 VSSHL V1.S4, V2.S4, V3.S4 VSSHL V1.S2, V2.S2, V3.S2 VSSHL V1.H4, V2.H4, V3.H4 VSSHL V1.H8, V2.H8, V3.H8 VSSHL V1.B8, V2.B8, V3.B8 VSSHL V1.B16, V2.B16, V3.B16 VUSHL V1.S4, V2.S4, V3.S4 VUSHL V1.S2, V2.S2, V3.S2 VUSHL V1.H4, V2.H4, V3.H4 VUSHL V1.H8, V2.H8, V3.H8 VUSHL V1.B8, V2.B8, V3.B8 VUSHL V1.B16, V2.B16, V3.B16 VRBIT V24.B8, V24.B8 RET // func widen() TEXT ·widen(SB), NOSPLIT, $0-0 VUXTL V30.B8, V30.H8 VUXTL V30.H4, V29.S4 VUXTL V29.S2, V2.D2 VUXTL2 V30.H8, V30.S4 VUXTL2 V29.S4, V2.D2 VUXTL2 V30.B16, V2.H8 VSXTL V1.B8, V2.H8 VSXTL V1.H4, V2.S4 VSXTL V1.S2, V2.D2 VSXTL2 V1.B16, V2.H8 VSXTL2 V1.H8, V2.S4 VSXTL2 V1.S4, V2.D2 VXTN V1.H8, V2.B8 VXTN V1.S4, V2.H4 VXTN V1.D2, V2.S2 VXTN2 V1.H8, V2.B16 VSQXTN V1.D2, V2.S2 VSQXTN2 V1.S4, V2.H8 VSQXTUN V1.H8, V2.B8 VUQXTN V1.S4, V2.H4 VUQXTN2 V1.D2, V2.S4 RET // func uaddw() TEXT ·uaddw(SB), NOSPLIT, $0-0 VUADDW V9.B8, V12.H8, V14.H8 VUADDW V13.H4, V10.S4, V11.S4 VUADDW V21.S2, V24.D2, V29.D2 VUADDW2 V9.B16, V12.H8, V14.H8 VUADDW2 V13.H8, V20.S4, V30.S4 VUADDW2 V21.S4, V24.D2, V29.D2 RET // func bareadd() TEXT ·bareadd(SB), NOSPLIT, $0-0 VADD V1, V2, V3 VADD V1, V3, V3 VSUB V12, V30, V30 VSUB V12, V20, V30 VADD V1.B8, V2.B8, V3.B8 VSUB V12.B8, V30.B8, V30.B8 RET // func lanes() TEXT ·lanes(SB), NOSPLIT, $0-0 VMOV V12.D[0], V12.D[1] VMOV V10.S[0], V12.S[1] VMOV V9.H[0], V12.H[1] VMOV V12.B[0], V12.B[1] VMOV V12.S[2], V12.S[3] VMOV V12.H[3], V12.H[5] RET