3

ymm0問題文:値がレジスタ内にある位置にあるバイトをレジスタから抽出する必要がありますAL

私の方法:(かなり醜い):

        ; XMM1 を「1 バイト右シフト」マスクに設定します。
        ; XMM1 : 000F0E0D0C0B0A090807060504030201

        cmp al,15 ; ymm0 以上の下位 xmmword にあるかどうかを確認します
        ja is_in_higher
        xor CX,CX
        移動CL、AL
    loop_for_next :
       vpextrb edx,ymm0,ymm0,0
       vpshufb xmm0,xm​​m0,xm​​m1 ; xmm0 をマスクとして右シフト
       ループ loop_for_next
    ..
    is_in_higher :
        vperm2i128 ymm0,ymm0,ymm0,01 ; 上位 128 を下位 128 にスワップします。
    jmp loop_for_next

これを行うためのよりエレガントな方法はありますか? アドバイスをいただければ幸いです。課題の核心は、インデックス値として(または) レジスタVPEXTRBではなく、即時のインデックス値のみを取ることです。CLAL

ありがとう...

4

2 に答える 2

0

コードには AVX2 ( vperm2i128) が必要ですが、AVX しか持っていないため、テストできませんでした。とにかく、あなたのコードは、ループが必要ないタスクにループを使用しています。私のソリューションでは、単純なルックアップ テーブルとvpshufb(SSSE3 が必要な) 命令を使用して、バイトを並べ替えます。YASM でテスト済み。

コードは次のとおりです。

[ビット 64]

セクション .text
グローバル_開始

_始める:

set_example_values:
        移動、0x1e ; バイトインデックス: 0...31、0x00...0x1f
        vmovaps ymm0,[例のデータ] ; データを定義する

code_starts_here:
        cmp al,15
        jna no_need_to_reorder_octalwords

        vperm2f128 ymm0、ymm0、ymm0、0x81 ; ymm0 を並べ替えます。上位 16 バイトをゼロにします。

no_need_to_reorder_octalwords:
        そして eax,15
        shl eax,4
        vmovaps xmm1,[rax+shuffle_table] ; 各バイトはインデックスで、f0 = 0 に設定されます。
        vpshufb xmm0,xm​​m1 ; 右側のバイトを xmm0 のバイト 0 にコピーします。
                                         ; xmm0 の残りのバイトをゼロにします。

        movq rdx,xmm0 ; rdx にコピーします。

        ...

。データ
整列 32
; フェドバ 9 8 7 6 5 4 3 2 1 0
example_data do 0xafaeadacabaaa9a8a7a6a5a4a3a2a1a0
; 1f1e1d1c1b1a19181716151413121110
             0xbfbebdbcbbbab9b8b7b6b5b4b3b2b1b0を実行します

shuffle_table dd 0xf0f0f000、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f001、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f002、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f003、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f004、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f005、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f006、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f007、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f008、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f009、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00a、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00b、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00c、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00d、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00e、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
                dd 0xf0f0f00f、0xf0f0f0f0、0xf0f0f0f0、0xf0f0f0f0
于 2013-11-20T22:45:57.200 に答える