Wolfgang Thallergcc16 merge934c3885 months agoHistory
727 lines · 22.6 KB · D
RawDownload
// Written in the D programming language. /** * Builtin SIMD intrinsics * * Source: $(DRUNTIMESRC core/_simd.d) * * Copyright: Copyright Digital Mars 2012-2020 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors:   $(HTTP digitalmars.com, Walter Bright), * Source:    $(DRUNTIMESRC core/_simd.d) */ module core.simd; pure:nothrow:@safe:@nogc: /******************************* * Create a vector type. * * Parameters: *      T = one of double[2], float[4], void[16], byte[16], ubyte[16], *      short[8], ushort[8], int[4], uint[4], long[2], ulong[2]. *      For 256 bit vectors, *      one of double[4], float[8], void[32], byte[32], ubyte[32], *      short[16], ushort[16], int[8], uint[8], long[4], ulong[4] */ template Vector(T){    /* __vector is compiler magic, hide it behind a template.     * The compiler will reject T's that don't work.     */    alias Vector = __vector(T);} /* Handy aliases */static if (is(Vector!(void[8])))    alias void8 = Vector!(void[8]);        ///static if (is(Vector!(double[1])))  alias double1 = Vector!(double[1]);      ///static if (is(Vector!(float[2])))   alias float2 = Vector!(float[2]);       ///static if (is(Vector!(byte[8])))    alias byte8 = Vector!(byte[8]);        ///static if (is(Vector!(ubyte[8])))   alias ubyte8 = Vector!(ubyte[8]);       ///static if (is(Vector!(short[4])))   alias short4 = Vector!(short[4]);       ///static if (is(Vector!(ushort[4])))  alias ushort4 = Vector!(ushort[4]);      ///static if (is(Vector!(int[2])))     alias int2 = Vector!(int[2]);         ///static if (is(Vector!(uint[2])))    alias uint2 = Vector!(uint[2]);        ///static if (is(Vector!(long[1])))    alias long1 = Vector!(long[1]);        ///static if (is(Vector!(ulong[1])))   alias ulong1 = Vector!(ulong[1]);       /// static if (is(Vector!(void[16])))   alias void16 = Vector!(void[16]);       ///static if (is(Vector!(double[2])))  alias double2 = Vector!(double[2]);      ///static if (is(Vector!(float[4])))   alias float4 = Vector!(float[4]);       ///static if (is(Vector!(byte[16])))   alias byte16 = Vector!(byte[16]);       ///static if (is(Vector!(ubyte[16])))  alias ubyte16 = Vector!(ubyte[16]);      ///static if (is(Vector!(short[8])))   alias short8 = Vector!(short[8]);       ///static if (is(Vector!(ushort[8])))  alias ushort8 = Vector!(ushort[8]);      ///static if (is(Vector!(int[4])))     alias int4 = Vector!(int[4]);         ///static if (is(Vector!(uint[4])))    alias uint4 = Vector!(uint[4]);        ///static if (is(Vector!(long[2])))    alias long2 = Vector!(long[2]);        ///static if (is(Vector!(ulong[2])))   alias ulong2 = Vector!(ulong[2]);       /// static if (is(Vector!(void[32])))   alias void32 = Vector!(void[32]);       ///static if (is(Vector!(double[4])))  alias double4 = Vector!(double[4]);      ///static if (is(Vector!(float[8])))   alias float8 = Vector!(float[8]);       ///static if (is(Vector!(byte[32])))   alias byte32 = Vector!(byte[32]);       ///static if (is(Vector!(ubyte[32])))  alias ubyte32 = Vector!(ubyte[32]);      ///static if (is(Vector!(short[16])))  alias short16 = Vector!(short[16]);      ///static if (is(Vector!(ushort[16]))) alias ushort16 = Vector!(ushort[16]);     ///static if (is(Vector!(int[8])))     alias int8 = Vector!(int[8]);         ///static if (is(Vector!(uint[8])))    alias uint8 = Vector!(uint[8]);        ///static if (is(Vector!(long[4])))    alias long4 = Vector!(long[4]);        ///static if (is(Vector!(ulong[4])))   alias ulong4 = Vector!(ulong[4]);       /// static if (is(Vector!(void[64])))   alias void64 = Vector!(void[64]);       ///static if (is(Vector!(double[8])))  alias double8 = Vector!(double[8]);      ///static if (is(Vector!(float[16])))  alias float16 = Vector!(float[16]);      ///static if (is(Vector!(byte[64])))   alias byte64 = Vector!(byte[64]);       ///static if (is(Vector!(ubyte[64])))  alias ubyte64 = Vector!(ubyte[64]);      ///static if (is(Vector!(short[32])))  alias short32 = Vector!(short[32]);      ///static if (is(Vector!(ushort[32]))) alias ushort32 = Vector!(ushort[32]);     ///static if (is(Vector!(int[16])))    alias int16 = Vector!(int[16]);        ///static if (is(Vector!(uint[16])))   alias uint16 = Vector!(uint[16]);       ///static if (is(Vector!(long[8])))    alias long8 = Vector!(long[8]);        ///static if (is(Vector!(ulong[8])))   alias ulong8 = Vector!(ulong[8]);       /// version (D_SIMD){    /** XMM opcodes that conform to the following:    *    *  opcode xmm1,xmm2/mem    *    * and do not have side effects (i.e. do not write to memory).    */    enum XMM    {        ADDSS = 0xF30F58,        ADDSD = 0xF20F58,        ADDPS = 0x000F58,        ADDPD = 0x660F58,        PADDB = 0x660FFC,        PADDW = 0x660FFD,        PADDD = 0x660FFE,        PADDQ = 0x660FD4,         SUBSS = 0xF30F5C,        SUBSD = 0xF20F5C,        SUBPS = 0x000F5C,        SUBPD = 0x660F5C,        PSUBB = 0x660FF8,        PSUBW = 0x660FF9,        PSUBD = 0x660FFA,        PSUBQ = 0x660FFB,         MULSS = 0xF30F59,        MULSD = 0xF20F59,        MULPS = 0x000F59,        MULPD = 0x660F59,        PMULLW = 0x660FD5,         DIVSS = 0xF30F5E,        DIVSD = 0xF20F5E,        DIVPS = 0x000F5E,        DIVPD = 0x660F5E,         PAND  = 0x660FDB,        POR   = 0x660FEB,         UCOMISS = 0x000F2E,        UCOMISD = 0x660F2E,         XORPS = 0x000F57,        XORPD = 0x660F57,         // Use STO and LOD instead of MOV to distinguish the direction        // (Destination is first operand, Source is second operand)        STOSS  = 0xF30F11,        /// MOVSS xmm1/m32, xmm2        STOSD  = 0xF20F11,        /// MOVSD xmm1/m64, xmm2        STOAPS = 0x000F29,        /// MOVAPS xmm2/m128, xmm1        STOAPD = 0x660F29,        /// MOVAPD xmm2/m128, xmm1        STODQA = 0x660F7F,        /// MOVDQA xmm2/m128, xmm1        STOD   = 0x660F7E,        /// MOVD reg/mem64, xmm   66 0F 7E /r        STOQ   = 0x660FD6,        /// MOVQ xmm2/m64, xmm1         LODSS  = 0xF30F10,        /// MOVSS xmm1, xmm2/m32        LODSD  = 0xF20F10,        /// MOVSD xmm1, xmm2/m64        LODAPS = 0x000F28,        /// MOVAPS xmm1, xmm2/m128        LODAPD = 0x660F28,        /// MOVAPD xmm1, xmm2/m128        LODDQA = 0x660F6F,        /// MOVDQA xmm1, xmm2/m128        LODD   = 0x660F6E,        /// MOVD xmm, reg/mem64   66 0F 6E /r        LODQ   = 0xF30F7E,        /// MOVQ xmm1, xmm2/m64         LODDQU   = 0xF30F6F,      /// MOVDQU xmm1, xmm2/mem128  F3 0F 6F /r        STODQU   = 0xF30F7F,      /// MOVDQU xmm1/mem128, xmm2  F3 0F 7F /r        MOVDQ2Q  = 0xF20FD6,      /// MOVDQ2Q mmx, xmm          F2 0F D6 /r        MOVHLPS  = 0x0F12,        /// MOVHLPS xmm1, xmm2        0F 12 /r        LODHPD   = 0x660F16,      /// MOVHPD xmm1, m64        STOHPD   = 0x660F17,      /// MOVHPD mem64, xmm1        66 0F 17 /r        LODHPS   = 0x0F16,        /// MOVHPS xmm1, m64        STOHPS   = 0x0F17,        /// MOVHPS m64, xmm1        MOVLHPS  = 0x0F16,        /// MOVLHPS xmm1, xmm2        LODLPD   = 0x660F12,      /// MOVLPD xmm1, m64        STOLPD   = 0x660F13,      /// MOVLPD m64, xmm1        LODLPS   = 0x0F12,        /// MOVLPS xmm1, m64        STOLPS   = 0x0F13,        /// MOVLPS m64, xmm1        MOVMSKPD = 0x660F50,      /// MOVMSKPD reg, xmm        MOVMSKPS = 0x0F50,        /// MOVMSKPS reg, xmm        MOVNTDQ  = 0x660FE7,      /// MOVNTDQ m128, xmm1        MOVNTI   = 0x0FC3,        /// MOVNTI m32, r32        MOVNTPD  = 0x660F2B,      /// MOVNTPD m128, xmm1        MOVNTPS  = 0x0F2B,        /// MOVNTPS m128, xmm1        MOVNTQ   = 0x0FE7,        /// MOVNTQ m64, mm        MOVQ2DQ  = 0xF30FD6,      /// MOVQ2DQ        LODUPD   = 0x660F10,      /// MOVUPD xmm1, xmm2/m128        STOUPD   = 0x660F11,      /// MOVUPD xmm2/m128, xmm1        LODUPS   = 0x0F10,        /// MOVUPS xmm1, xmm2/m128        STOUPS   = 0x0F11,        /// MOVUPS xmm2/m128, xmm1         PACKSSDW = 0x660F6B,        PACKSSWB = 0x660F63,        PACKUSWB = 0x660F67,        PADDSB = 0x660FEC,        PADDSW = 0x660FED,        PADDUSB = 0x660FDC,        PADDUSW = 0x660FDD,        PANDN = 0x660FDF,        PCMPEQB = 0x660F74,        PCMPEQD = 0x660F76,        PCMPEQW = 0x660F75,        PCMPGTB = 0x660F64,        PCMPGTD = 0x660F66,        PCMPGTW = 0x660F65,        PMADDWD = 0x660FF5,        PSLLW = 0x660FF1,        PSLLD = 0x660FF2,        PSLLQ = 0x660FF3,        PSRAW = 0x660FE1,        PSRAD = 0x660FE2,        PSRLW = 0x660FD1,        PSRLD = 0x660FD2,        PSRLQ = 0x660FD3,        PSUBSB = 0x660FE8,        PSUBSW = 0x660FE9,        PSUBUSB = 0x660FD8,        PSUBUSW = 0x660FD9,        PUNPCKHBW = 0x660F68,        PUNPCKHDQ = 0x660F6A,        PUNPCKHWD = 0x660F69,        PUNPCKLBW = 0x660F60,        PUNPCKLDQ = 0x660F62,        PUNPCKLWD = 0x660F61,        PXOR = 0x660FEF,        ANDPD = 0x660F54,        ANDPS = 0x0F54,        ANDNPD = 0x660F55,        ANDNPS = 0x0F55,        CMPPS = 0x0FC2,        CMPPD = 0x660FC2,        CMPSD = 0xF20FC2,        CMPSS = 0xF30FC2,        COMISD = 0x660F2F,        COMISS = 0x0F2F,        CVTDQ2PD = 0xF30FE6,        CVTDQ2PS = 0x0F5B,        CVTPD2DQ = 0xF20FE6,        CVTPD2PI = 0x660F2D,        CVTPD2PS = 0x660F5A,        CVTPI2PD = 0x660F2A,        CVTPI2PS = 0x0F2A,        CVTPS2DQ = 0x660F5B,        CVTPS2PD = 0x0F5A,        CVTPS2PI = 0x0F2D,        CVTSD2SI = 0xF20F2D,        CVTSD2SS = 0xF20F5A,        CVTSI2SD = 0xF20F2A,        CVTSI2SS = 0xF30F2A,        CVTSS2SD = 0xF30F5A,        CVTSS2SI = 0xF30F2D,        CVTTPD2PI = 0x660F2C,        CVTTPD2DQ = 0x660FE6,        CVTTPS2DQ = 0xF30F5B,        CVTTPS2PI = 0x0F2C,        CVTTSD2SI = 0xF20F2C,        CVTTSS2SI = 0xF30F2C,        MASKMOVDQU = 0x660FF7,        MASKMOVQ = 0x0FF7,        MAXPD = 0x660F5F,        MAXPS = 0x0F5F,        MAXSD = 0xF20F5F,        MAXSS = 0xF30F5F,        MINPD = 0x660F5D,        MINPS = 0x0F5D,        MINSD = 0xF20F5D,        MINSS = 0xF30F5D,        ORPD = 0x660F56,        ORPS = 0x0F56,        PAVGB = 0x660FE0,        PAVGW = 0x660FE3,        PMAXSW = 0x660FEE,        //PINSRW = 0x660FC4,        PMAXUB = 0x660FDE,        PMINSW = 0x660FEA,        PMINUB = 0x660FDA,        //PMOVMSKB = 0x660FD7,        PMULHUW = 0x660FE4,        PMULHW = 0x660FE5,        PMULUDQ = 0x660FF4,        PSADBW = 0x660FF6,        PUNPCKHQDQ = 0x660F6D,        PUNPCKLQDQ = 0x660F6C,        RCPPS = 0x0F53,        RCPSS = 0xF30F53,        RSQRTPS = 0x0F52,        RSQRTSS = 0xF30F52,        SQRTPD = 0x660F51,        SHUFPD = 0x660FC6,        SHUFPS = 0x0FC6,        SQRTPS = 0x0F51,        SQRTSD = 0xF20F51,        SQRTSS = 0xF30F51,        UNPCKHPD = 0x660F15,        UNPCKHPS = 0x0F15,        UNPCKLPD = 0x660F14,        UNPCKLPS = 0x0F14,         PSHUFD = 0x660F70,        PSHUFHW = 0xF30F70,        PSHUFLW = 0xF20F70,        PSHUFW = 0x0F70,        PSLLDQ = 0x07660F73,        PSRLDQ = 0x03660F73,         //PREFETCH = 0x0F18,         // SSE3 Pentium 4 (Prescott)         ADDSUBPD = 0x660FD0,        ADDSUBPS = 0xF20FD0,        HADDPD   = 0x660F7C,        HADDPS   = 0xF20F7C,        HSUBPD   = 0x660F7D,        HSUBPS   = 0xF20F7D,        MOVDDUP  = 0xF20F12,        MOVSHDUP = 0xF30F16,        MOVSLDUP = 0xF30F12,        LDDQU    = 0xF20FF0,        MONITOR  = 0x0F01C8,        MWAIT    = 0x0F01C9,         // SSSE3        PALIGNR = 0x660F3A0F,        PHADDD = 0x660F3802,        PHADDW = 0x660F3801,        PHADDSW = 0x660F3803,        PABSB = 0x660F381C,        PABSD = 0x660F381E,        PABSW = 0x660F381D,        PSIGNB = 0x660F3808,        PSIGND = 0x660F380A,        PSIGNW = 0x660F3809,        PSHUFB = 0x660F3800,        PMADDUBSW = 0x660F3804,        PMULHRSW = 0x660F380B,        PHSUBD = 0x660F3806,        PHSUBW = 0x660F3805,        PHSUBSW = 0x660F3807,         // SSE4.1         BLENDPD   = 0x660F3A0D,        BLENDPS   = 0x660F3A0C,        BLENDVPD  = 0x660F3815,        BLENDVPS  = 0x660F3814,        DPPD      = 0x660F3A41,        DPPS      = 0x660F3A40,        EXTRACTPS = 0x660F3A17,        INSERTPS  = 0x660F3A21,        MPSADBW   = 0x660F3A42,        PBLENDVB  = 0x660F3810,        PBLENDW   = 0x660F3A0E,        PEXTRD    = 0x660F3A16,        PEXTRQ    = 0x660F3A16,        PINSRB    = 0x660F3A20,        PINSRD    = 0x660F3A22,        PINSRQ    = 0x660F3A22,         MOVNTDQA = 0x660F382A,        PACKUSDW = 0x660F382B,        PCMPEQQ = 0x660F3829,        PEXTRB = 0x660F3A14,        PHMINPOSUW = 0x660F3841,        PMAXSB = 0x660F383C,        PMAXSD = 0x660F383D,        PMAXUD = 0x660F383F,        PMAXUW = 0x660F383E,        PMINSB = 0x660F3838,        PMINSD = 0x660F3839,        PMINUD = 0x660F383B,        PMINUW = 0x660F383A,        PMOVSXBW = 0x660F3820,        PMOVSXBD = 0x660F3821,        PMOVSXBQ = 0x660F3822,        PMOVSXWD = 0x660F3823,        PMOVSXWQ = 0x660F3824,        PMOVSXDQ = 0x660F3825,        PMOVZXBW = 0x660F3830,        PMOVZXBD = 0x660F3831,        PMOVZXBQ = 0x660F3832,        PMOVZXWD = 0x660F3833,        PMOVZXWQ = 0x660F3834,        PMOVZXDQ = 0x660F3835,        PMULDQ   = 0x660F3828,        PMULLD   = 0x660F3840,        PTEST    = 0x660F3817,         ROUNDPD = 0x660F3A09,        ROUNDPS = 0x660F3A08,        ROUNDSD = 0x660F3A0B,        ROUNDSS = 0x660F3A0A,         // SSE4.2        PCMPESTRI  = 0x660F3A61,        PCMPESTRM  = 0x660F3A60,        PCMPISTRI  = 0x660F3A63,        PCMPISTRM  = 0x660F3A62,        PCMPGTQ    = 0x660F3837,        //CRC32         // SSE4a (AMD only)        // EXTRQ,INSERTQ,MOVNTSD,MOVNTSS         // POPCNT and LZCNT (have their own CPUID bits)        POPCNT     = 0xF30FB8,        // LZCNT    }     /**    * Generate two operand instruction with XMM 128 bit operands.    *    * This is a compiler magic function - it doesn't behave like    * regular D functions.    *    * Parameters:    *      opcode = any of the XMM opcodes; it must be a compile time constant    *      op1    = first operand    *      op2    = second operand    * Returns:    *      result of opcode    * Example:    ---    import core.simd;    import core.stdc.stdio;     void main()    {        float4 A = [2.34f, -70000.0f, 0.00001f, 345.5f];        float4 R = A;        R = cast(float4) __simd(XMM.RCPSS, R, A);        printf("%g %g %g %g\n", R.array[0], R.array[1], R.array[2], R.array[3]);    }    ---    * Prints `0.427368 -70000 1e-05 345.5`.    * The use of the two operand form for `XMM.RCPSS` is necessary because the result of the instruction    * contains elements of both operands.    * Example:    ---    double[2] A = [56.0, -75.0];    double2 R = cast(double2) __simd(XMM.LODUPD, *cast(double2*)A.ptr);    ---    * The cast to `double2*` is necessary because the type of `*A.ptr` is `double`.    */    pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2);     ///    unittest    {        float4 a;        a = cast(float4)__simd(XMM.PXOR, a, a);    }     /**    * Unary SIMD instructions.    */    pure @safe void16 __simd(XMM opcode, void16 op1);    pure @safe void16 __simd(XMM opcode, double d);   ///    pure @safe void16 __simd(XMM opcode, float f);    ///     ///    unittest    {        float4 a;        a = cast(float4)__simd(XMM.LODSS, a);    }     /****    * For instructions:    * CMPPD, CMPSS, CMPSD, CMPPS,    * PSHUFD, PSHUFHW, PSHUFLW,    * BLENDPD, BLENDPS, DPPD, DPPS,    * MPSADBW, PBLENDW,    * ROUNDPD, ROUNDPS, ROUNDSD, ROUNDSS    * Parameters:    *      opcode = any of the above XMM opcodes; it must be a compile time constant    *      op1    = first operand    *      op2    = second operand    *      imm8   = third operand; must be a compile time constant    * Returns:    *      result of opcode    */    pure @safe void16 __simd(XMM opcode, void16 op1, void16 op2, ubyte imm8);     ///    unittest    {        float4 a;        a = cast(float4)__simd(XMM.CMPPD, a, a, 0x7A);    }     /***    * For instructions with the imm8 version:    * PSLLD, PSLLQ, PSLLW, PSRAD, PSRAW, PSRLD, PSRLQ, PSRLW,    * PSRLDQ, PSLLDQ    * Parameters:    *      opcode = any of the XMM opcodes; it must be a compile time constant    *      op1    = first operand    *      imm8   = second operand; must be a compile time constant    * Returns:    *      result of opcode    */    pure @safe void16 __simd_ib(XMM opcode, void16 op1, ubyte imm8);     ///    unittest    {        float4 a;        a = cast(float4) __simd_ib(XMM.PSRLQ, a, 0x7A);    }

Lines 1–500 of 727.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t