1

ネオンに64ビットのdレジスタがあるとします。値 ABCDEFGH が格納されているとしましょう。ここで、A&E、B&F、C&G、D&H などを追加したいと思います。このような操作を可能にする組み込み関数はありますか?

ドキュメントを見ましたが、適切なものが見つかりませんでした。

4

1 に答える 1

1

加算を 16 ビットで実行する場合、つまり uint16x4 の結果を生成する場合は、vmovl を使用して入力ベクトルを uint8x8 から uint8x16 にプロモートし、vadd を使用して下位半分と上位半分を加算します。NEON 組み込み関数で表現すると、これは次のように実現されます。

const int16x8_t t = vmovl_u8(input);
const int16x4_t r = vadd_u16(vget_low(t), vget_high(t))

これは、次のアセンブリにコンパイルされます (d0 は 64 ビット入力レジスタ、d1 は 64 ビット出力レジスタです)。vget_low と vget_high は命令を生成しないことに注意してください。これらの組み込み関数は、Q レジスターが 2 つの連続する D レジスターに名前を付ける便利な方法であることを利用して、適切なレジスター割り当てによって実装されます。Q{n} はペア (D{2n}, D{2n+1}) を参照します。

VMOVL.U8 q1, d0
VADD.I16 d1, d2

演算を 8 ビットで実行し、オーバーフローの場合に飽和させたい場合は、次のようにします。

const int8x8_t t = vreinterpret_u8_u64(vshr_n_u64(vreinterpret_u64_u8(input), 32));
const int8x8_t r = vqadd_u8(input, t);

これはコンパイルされます(d0は再び入力、d1で出力)

VSHR.U64 d1, d0, #32
VQADD.I8 d1, d0

VQADD を VADD だけに置き換えると、結果は 0xff に飽和するのではなく、オーバーフロー時にラップアラウンドします。

于 2012-08-31T10:48:08.513 に答える