Intel AVX その3 命令

x86 (IA32) の命令は Prefix を追加し op code 長を増やすことで拡張されてきました。
SSE の命令は 2byte escape 0F + 1byte opcode の空間に割り当てられています。
例えば ADDPS は 0F 58 です。バリエーションであるスカラー ADDSS は Prefix と
して F3 が追加され、SSE2 の倍精度命令はさらに 66 と F2 も加わります。

ADDPS     0F 58 ~
ADDSS  F3 0F 58 ~
ADDPD  66 0F 58 ~
ADDSD  F2 0F 58 ~

x64 (AMD64/Intel64/EM64T) の拡張レジスタ xmm8~xmm15 にアクセスするには
上記にさらに REX Prefix が追加されます。
40~4F が REX Prefix で、4bit 分のオプション bit を持っています。

ADDPS     45 0F 58 ~
ADDSS  F3 45 0F 58 ~
ADDPD  66 45 0F 58 ~
ADDSD  F2 45 0F 58 ~

IA32 命令のレジスタフィールドは 3bit しかなく、レジスタ上限は 8個でした。
64bit モードでは REX Prefix 内の機能 bit を追加して、レジスタフィールドを
4bit とみなすことができます。
これで最大 16個のレジスタを指定可能です。

REX Prefix
H---------------L
[0|1|0|0|W|R|X|B]

REX.RXB の 3bit がレジスタ/Index フィールド拡張用です。
残り 1bit REX.W が 64bit オペランドサイズの指定に使われます。

SSE4.x ではさらに opcode が拡張されて 3byte escape の 0F 38 や 0F 3A で
始まるスペースが割り当てられています。(SSE5 は 0F 24)

// SSE4.1
DPPS      66 [REX] 0F 3A 40 ~
BLENDPS   66 [REX] 0F 3A 0C ~
EXTRACTPS 66 [REX] 0F 3A 17 ~

// SSE4.2
CRC32     F2 [REX] 0F 38 F0 ~

追加命令が増える度に命令は長くなる一方です。

AVX でも命令を区別するために、さらに VEX Prefix が定義されています。
今までの命令 Prefix と違うのは、最初から 2~3byte の長さを確保したことと、
その中に従来使われていた Prefix や opcode を組み込んでしまったことです。

例えば SSE 命令の前に付く 66/F2/F3 Prefix は無印を含めて 4通りしかありません。
これは 2bit にエンコードできます。

最初から REX も opcode の機能 bit に組み込んでしまえば 8bit フルに割り
当てる必要もなくなります。

必ず 0F が含まれるとわかっているなら、これを命令から取り除くことが可能です。

2byte-VEX (C5+1byte)
H---C5---L  H---------------L
[11000101]  [R|V|V|V|V|L|P|P]

3byte-VEX (C4+2byte)
H---C4---L  H---------------L   H---------------L
[11000100]  [R|X|B|M|M|M|M|M]   [W|V|V|V|V|L|P|P]

2bit の PP がまさに Prefix の有無を表しています。
 0= なし
 1= 66
 2= F3
 3= F2

L は 256bit (ymm) モードの指定です。0 なら 128bit (xmm)

R X B W は REX Prefix に含まれていた機能 bit です。

4bit の VVVV は追加のレジスタフィールドです。
AVX は 3オペランド命令で source/destination が分離されているので、増えた
レジスタオペランドの指定にここが使われます。

5bit の MMMMM は拡張命令用フィールドでその多くが予約されています。
現在定義されているのは次の 3パターンのみ。
 1= 0F (2byte escape)
 2= 0F 38 (3byte escape)
 3= 0F 3A (3byte escape)

2byte-VEX には MMMMM は含まれていませんが、無条件で 0F とみなします。

これで上で紹介した多くの命令が VEX Prefix で置き換えられることがわかります。
VEX Prefix 以降の 1byte opcode や ModR/M 等のフィールドには互換性があります。

また MMMMM の多くが余っているので、例えば、まず無いとは思いますが

MMMMM: 4= 0F 24

と定義してしまえば AMD SSE5 の VEX 化も可能でしょう。
今後はおそらく命令が長くなることもなく ぐっすり眠れます。

Intel AVX は IA64 のような全く新しい互換性のない命令セットではなく、
x86 (IA32) の命令を圧縮してエンコードしたものです。

追加されたレジスタフィールド以外はこれまでの命令や prefix と同じもの。
従来の命令形式にデコード可能な互換性を保っています。

命令長は必ずしも短くなるわけではなく、ADDPS などは VEX 化することで 1byte
増えそうです。
ただし x64 拡張レジスタへアクセスする場合は長さは変わらず、source と
destination を別指定できるため場合によっては MOV 命令を減らすことができるでしょう。

関連エントリ
Intel AVX その2 転送
Intel AVX

Intel AVX その3 命令” に1件のフィードバックがあります

コメントは停止中です。