英語版
このページの英語版を見る

core.simd

ビルトインSIMD intrinsics

ソース core/simd.d

Authors:

ソース core/simd.d

template Vector(T)
ベクトル型を作成する。

パラメータ T = double[2]、float[4]、void[16]、byte[16]、ubyte[16]のいずれか、 short[8]、ushort[8]、int[4]、uint[4]、long[2]、ulong[2]。 256ビット・ベクトルの場合、 double[4]、float[8]、void[32]、byte[32]、ubyte[32]のいずれか、 short[16]、ushort[16]、int[8]、uint[8]、long[4]、ulong[4]のいずれか。

alias void16 = __vector(void[16]);
alias double2 = __vector(double[2]);
alias float4 = __vector(float[4]);
alias byte16 = __vector(byte[16]);
alias ubyte16 = __vector(ubyte[16]);
alias short8 = __vector(short[8]);
alias ushort8 = __vector(ushort[8]);
alias int4 = __vector(int[4]);
alias uint4 = __vector(uint[4]);
alias long2 = __vector(long[2]);
alias ulong2 = __vector(ulong[2]);
enum XMM: int;
以下に適合するXMMオペコード:
オペコード xmm1,xmm2/mem
で、副作用がない(つまり、メモリに書き込まない)。
STOSS
MOVSS xmm1/m32, xmm2
STOSD
MOVSD xmm1/m64, xmm2
STOAPS
MOVAPS xmm2/m128, xmm1
STOAPD
MOVAPD xmm2/m128, xmm1
STODQA
MOVDQA xmm2/m128、xmm1
STOD
MOVD reg/mem64, xmm 66 0F 7E /r
STOQ
MOVQ xmm2/m64, xmm1
LODSS
MOVSS xmm1, xmm2/m32
LODSD
MOVSD xmm1, xmm2/m64
LODAPS
MOVAPS xmm1, xmm2/m128
LODAPD
MOVAPD xmm1, xmm2/m128
LODDQA
MOVDQA xmm1、xmm2/m128
LODD
MOVD xmm, reg/mem64 66 0F 6E /r
LODQ
MOVQ xmm1, xmm2/m64
LODDQU
MOVDQU xmm1, xmm2/mem128 F3 0F 6F /r
STODQU
MOVDQU xmm1/mem128, xmm2 F3 0F 7F /r
MOVDQ2Q
MOVDQ2Q mmx, xmm F2 0F D6 /r
MOVHLPS
MOVHLPS xmm1, xmm2 0F 12 /r
LODHPD
MOVHPD xmm1, m64
STOHPD
MOVHPD mem64, xmm1 66 0F 17 /r
LODHPS
MOVHPS xmm1, m64
STOHPS
MOVHPS m64, xmm1
MOVLHPS
MOVLHPS xmm1, xmm2
LODLPD
MOVLPD xmm1, m64
STOLPD
MOVLPD m64, xmm1
LODLPS
MOVLPS xmm1, m64
STOLPS
MOVLPS m64, xmm1
MOVMSKPD
MOVMSKPD reg, xmm
MOVMSKPS
MOVMSKPS reg, xmm
MOVNTDQ
MOVNTDQ m128, xmm1
MOVNTI
MOVNTI m32, r32
MOVNTPD
MOVNTPD m128, xmm1
MOVNTPS
MOVNTPS m128, xmm1
MOVNTQ
MOVNTQ m64, mm
MOVQ2DQ
MOVQ2DQ
LODUPD
MOVUPD xmm1, xmm2/m128
STOUPD
MOVUPD xmm2/m128, xmm1
LODUPS
MOVUPS xmm1, xmm2/m128
STOUPS
MOVUPS xmm2/m128, xmm1
pure nothrow @nogc @safe void16 __simd(XMM opcode, void16 op1, void16 op2);
XMM 128 ビット・オペランドで 2 オペランド命令を生成する。
これはコンパイラのマジック関数であり、通常のD関数のようには動作しない。 通常のD関数のようには動作しない。

パラメータ opcode = XMM オペコードのいずれか。コンパイル時の定数でなければならない。 op1 = 第1オペランド op2 = 第2オペランド

Returns:
オペコードの結果

例:

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]);
}
0.427368 -70000 1e-05 345.5 を印字する。 XMM.RCPSS 、2つのオペランド形式を使用する必要がある。 の結果は両方のオペランドの要素を含むからである。

例:

double[2] A = [56.0, -75.0];
double2 R = cast(double2) __simd(XMM.LODUPD, *cast(double2*)A.ptr);
*A.ptr の型がdouble であるため、double2* へのキャストが必要である。

Examples:
float4 a;
a = cast(float4)__simd(XMM.PXOR, a, a);
pure nothrow @nogc @safe void16 __simd(XMM opcode, void16 op1);
単項SIMD命令。
pure nothrow @nogc @safe void16 __simd(XMM opcode, double d);
pure nothrow @nogc @safe void16 __simd(XMM opcode, float f);
Examples:
float4 a;
a = cast(float4)__simd(XMM.LODSS, a);
pure nothrow @nogc @safe void16 __simd(XMM opcode, void16 op1, void16 op2, ubyte imm8);
命令の場合: cmppd、cmpss、cmpsd、cmpps、 pshufd、pshufhw、pshuflw、 blendpd、blendps、dppd、dpps、 ppsadbw、pblendw、 ラウンドpd、ラウンドps、ラウンドsd、ラウンドss

パラメータ opcode = 上記のXMMオペコードのいずれか。コンパイル時定数でなければならない。 op1 = 第1オペランド op2 = 2 番目のオペランド imm8 = 第3オペランド。コンパイル時定数でなければならない。

Returns:
オペコードの結果
Examples:
float4 a;
a = cast(float4)__simd(XMM.CMPPD, a, a, 0x7A);
pure nothrow @nogc @safe void16 __simd_ib(XMM opcode, void16 op1, ubyte imm8);
imm8バージョンでの指示の場合: PSLD、PSLLQ、PSLLW、PSRAD、PSRAW、PSRLD、PSRLQ、PSRLW、 PSRLDQ、PSLLDQ

パラメータ opcode = XMMオペコードのいずれか。コンパイル時定数でなければならない。 op1 = 第1オペランド imm8 = 第2オペランド。コンパイル時定数でなければならない。

Returns:
オペコードの結果
Examples:
float4 a;
a = cast(float4) __simd_ib(XMM.PSRLQ, a, 0x7A);
pure nothrow @nogc @safe void16 __simd_sto(XMM opcode, void16 op1, void16 op2);
という形式の「ストア」操作の場合である: op1 op= op2 MOVLPSのような形である。
Returns:
op2 これらは、semantic() がチェックしないため、純粋とマークすることはできない。
pure nothrow @nogc @safe void16 __simd_sto(XMM opcode, double op1, void16 op2);
pure nothrow @nogc @safe void16 __simd_sto(XMM opcode, float op1, void16 op2);
pure nothrow @nogc @safe void16 __simd_sto(XMM opcode, void16 op1, long op2);
Examples:
void16 a;
float f = 1;
double d = 1;

cast(void)__simd_sto(XMM.STOUPS, a, a);
cast(void)__simd_sto(XMM.STOUPS, f, a);
cast(void)__simd_sto(XMM.STOUPS, d, a);
void prefetch(bool writeFetch, ubyte locality)(const(void)* address);
プリフェッチ命令を出す。
Parameters:
const(void)* address プリフェッチされるアドレス
writeFetch 書き込みフェッチの場合はtrue、読み出しフェッチの場合はfalse。
locality 0..3(0は最小ローカル、3は最大ローカルを意味する)

注釈:以下の通りである。 インテルのマッピングは以下の通りである:

writeFetchlocalityInstruction
false0プリフェッチンタ
1プリフェッチ2
2プリフェッチ1
3プリフェッチ0
0プリフェッチw
1プリフェッチュ
2プリフェッチュ
3プリフェッチ

V loadUnaligned(V)(const V* p)
if (is(V == void16) || is(V == byte16) || is(V == ubyte16) || is(V == short8) || is(V == ushort8) || is(V == int4) || is(V == uint4) || is(V == long2) || is(V == ulong2) || is(V == double2) || is(V == float4));
アドレスから非整列ベクトルをロードする。 これはコンパイラの組込み関数である。
Parameters:
V* p ベクトルへのポインタ
Returns:
ベクトル
V storeUnaligned(V)(V* p, V value)
if (is(V == void16) || is(V == byte16) || is(V == ubyte16) || is(V == short8) || is(V == ushort8) || is(V == int4) || is(V == uint4) || is(V == long2) || is(V == ulong2) || is(V == double2) || is(V == float4));
ベクタを非整列アドレスに格納する。 これはコンパイラの組込み関数である。
Parameters:
V* p ベクトルへのポインタ
V value 格納する値
Returns: