_mm_maddubs_epi16
[このドキュメントはプレビュー版であり、後のリリースで変更されることがあります。 Blank topics are included as placeholders.]
Microsoft 固有の仕様 →
追加のストリーミング SIMD 拡張命令 SSSE3 3 () pmaddubsw を生成します。 この命令ではで整数を大きくして追加します。
__m128i _mm_maddubs_epi16(
__m128i a,
__m128i b
);
パラメーター
[入力] a
16 個の 8 ビット符号なし整数を含む 128 ビットのパラメーター。[入力] b
16 個の 8 ビット符号付き整数を含む 128 ビットのパラメーター。
戻り値
各要素の結果が隣接 SIMD の製品の飽和合計を表す8 個の 16 ビット符号付き整数を含むビットの結果。 これは次のの式として表現できます :
r0 := SATURATE_16((a0 * b0) + (a1 * b1))
r1 := SATURATE_16((a2 * b2) + (a3 * b3))
...
r7 := SATURATE_16((a14 * b14) + (a15 * b15))
必要条件
組み込み |
アーキテクチャ |
---|---|
_mm_maddubs_epi16 |
x86x64 |
ヘッダー ファイル <tmmintrin.h>
解説
r0-r7 は戻り値 r の順次順序付き 16 ビット コンポーネントです。 r0 は最下位の 16 ビットを示します。
a0-a15 と b0-b15 はパラメーター a と b の順次順序ありそれぞれ 8 ビット コンポーネントです。 a0 と b0 は最下位の 8 ビットです。 パラメーター a は符号なしバイトが含まれています。 パラメーター b符号付きバイト数が含まれます。
SATURATE_16(x) が ((x > 32767) ? 32767 : ((x < -32768) ? -32768 : x)) です。
この組み込みを使用する前にソフトウェアは基になるプロセッサが命令がサポートされていることを確認する必要があります。
使用例
#include <stdio.h>
#include <tmmintrin.h>
int main ()
{
__m128i a, b, final;
int temp;
a.m128i_u8[0] = 1;
b.m128i_i8[0] = 32;
a.m128i_u8[1] = 1;
b.m128i_i8[1] = -32;
temp = (a.m128i_u8[0] * b.m128i_i8[0]) + (a.m128i_u8[1] * b.m128i_i8[1]);
final.m128i_i16[0] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[2] = 1;
b.m128i_i8[2] = 2;
a.m128i_u8[3] = 2;
b.m128i_i8[3] = 4;
temp = (a.m128i_u8[2] * b.m128i_i8[2]) + (a.m128i_u8[3] * b.m128i_i8[3]);
final.m128i_i16[1] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[4] = 10;
b.m128i_i8[4] = -128;
a.m128i_u8[5] = 12;
b.m128i_i8[5] = 12;
temp = (a.m128i_u8[4] * b.m128i_i8[4]) + (a.m128i_u8[5] * b.m128i_i8[5]);
final.m128i_i16[2] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[6] = 255;
b.m128i_i8[6] = -128;
a.m128i_u8[7] = 255;
b.m128i_i8[7] = -128;
temp = (a.m128i_u8[6] * b.m128i_i8[6]) + (a.m128i_u8[7] * b.m128i_i8[7]);
final.m128i_i16[3] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[8] = 0;
b.m128i_i8[8] = 100;
a.m128i_u8[9] = 20;
b.m128i_i8[9] = 20;
temp = (a.m128i_u8[8] * b.m128i_i8[8]) + (a.m128i_u8[9] * b.m128i_i8[9]);
final.m128i_i16[4] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[10] = 10;
b.m128i_i8[10] = 10;
a.m128i_u8[11] = 11;
b.m128i_i8[11] = 11;
temp = (a.m128i_u8[10] * b.m128i_i8[10]) + (a.m128i_u8[11] * b.m128i_i8[11]);
final.m128i_i16[5] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[12] = 12;
b.m128i_i8[12] = 12;
a.m128i_u8[13] = 13;
b.m128i_i8[13] = 13;
temp = (a.m128i_u8[12] * b.m128i_i8[12]) + (a.m128i_u8[13] * b.m128i_i8[13]);
final.m128i_i16[6] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
a.m128i_u8[14] = 14;
b.m128i_i8[14] = 14;
a.m128i_u8[15] = 15;
b.m128i_i8[15] = 15;
temp = (a.m128i_u8[14] * b.m128i_i8[14]) + (a.m128i_u8[15] * b.m128i_i8[15]);
final.m128i_i16[7] = (temp > 32767) ? 32767 : (temp < -32768) ? -32768 : temp;
__m128i res = _mm_maddubs_epi16(a, b);
printf_s("Res0 should be %d: %d\nRes1 should be %d: %d\n",
final.m128i_i16[0], res.m128i_i16[0], final.m128i_i16[1], res.m128i_i16[1]);
printf_s("Res2 should be %d: %d\nRes3 should be %d: %d\n",
final.m128i_i16[2], res.m128i_i16[2], final.m128i_i16[3], res.m128i_i16[3]);
printf_s("Res4 should be %d: %d\nRes5 should be %d: %d\n",
final.m128i_i16[4], res.m128i_i16[4], final.m128i_i16[5], res.m128i_i16[5]);
printf_s("Res6 should be %d: %d\nRes7 should be %d: %d\n",
final.m128i_i16[6], res.m128i_i16[6], final.m128i_i16[7], res.m128i_i16[7]);
return 0;
}