Clang 23.1.2 は 7,575 個の x86 組み込み関数を定義しています。そのうち 6,916 個は、このリファレンスの単一の命令にコンパイルされ、下の一覧と命令のページに掲載しています。621 個は、複数の命令にコンパイルされるか命令にならない、マスクを扱うが汎用命令にコンパイルされる、または固有の命令を持たないものです。23 個は、ドキュメントコメントとコンパイル結果が一致しないため除外しています。15 個は単独ではコンパイルできませんでした。

一覧は名前に含まれる演算で並べているため、_mm_add_ps、_mm256_add_ps、_mm512_mask_add_ps は A の下にまとまります。各名前は命令ページのその行にリンクしており、そこには組み込み関数のシグネチャ、コンパイル先の正確な形式、必要な Clang のオプションを示しています。オペランドによって複数の命令のいずれかにコンパイルされる組み込み関数、たとえばアキュムレーターがすでにデスティネーションレジスターにある FMA では、そのすべてを載せています。組み込み関数を命令に対応付ける方法は一覧の後で説明します。

A

B

C

D

E

F

G

H

I

K

L

M

N

O

P

R

S

T

U

W

X

Z

その他

組み込み関数の対応付け方

組み込み関数は Clang 23.1.2 (コミット 85ac56026243) の x86 ヘッダーから取っています。このヘッダーは LLVM プロジェクトの一部で、Apache License 2.0 with LLVM Exceptions に従います。ビルドは各組み込み関数について次のことを行います。

  • シグネチャ、必要なターゲット機能 (target feature)、命令についてのドキュメントコメントの記述 (「This intrinsic corresponds to the VPDPBUSD instruction」) を読み取ります。
  • 同じリリースの Clang で、その組み込み関数自身のターゲット機能を指定して呼び出しをコンパイルし、マシンコードを Intel XED でデコードします。呼び出しのバリアントでは、別のオペランドをデスティネーションレジスターやメモリに置いたり、SSE の組み込み関数に AVX を加えて VEX 形式にコンパイルさせたりします。また、マスクだけを扱う組み込み関数では、マスクを呼び出し自身の引数として受け取る代わりに、すべてのマスクを KADD から作るバリアントも使います (KADD は AND、OR、XOR、NOT や移動と異なり、汎用レジスターの形式を持ちません)。こうすると、呼び出し規約がふだんは隠してしまう k レジスターがコードに残ります (_mm512_kunpackw などの KUNPCK 組み込み関数は各マスクの下位半分しか読まないため、マスクをその半分の幅で作ります。全幅のマスクからだと、Clang はこれらの組み込み関数をマスクからベクトルへの変換で組み立ててしまいます)。
  • 引数を渡して結果を返すコードを除いて、呼び出しがちょうどその 1 つの命令にコンパイルされる場合にだけ、その命令のページに載せます。結果を返すコードには、_mm512_2intersect_epi32 の 2 つのマスクのように、組み込み関数がポインター経由で返す結果のストアも含みます。

Clang のドキュメントコメントが命令を挙げている場合は、コンパイルされたコードがそれを裏付けなければなりません。ビット上は同じ処理をしながら別のデータ型を想定する命令にコンパイルされることもあり、たとえば文書上は VMOVDQA のところが VMOVAPS になります。その場合、組み込み関数は文書に記された命令とともに載せます。_mm_insert_ps のように、コメントが SSE 命令の VEX 形式だけを挙げている場合は、AVX なしで呼び出しをコンパイルしたときのレガシ形式も裏付けとして認めます。誤った命令を挙げているドキュメントコメントもいくつかあります。このリファレンスに関わるものは手作業で確認し、コメントのどこが誤っているかを命令ページに記しています。

載せていない組み込み関数は、複数の命令にコンパイルされるものや命令にならないもの、レジスターをゼロにするだけのもの、メモリ上の定数から作られるもの (符号マスクから作る絶対値など)、マスクだけを扱い、それでも実際の命令を残さないもの (ビットを解釈し直すだけの _cvtmask16_u32 など)、呼び出しに 2 つの結果が必要なため常に複数の命令にコンパイルされるもの (2 つのフラグのために KORTESTW を 2 回実行する _kortest_mask16_u8 など)、独自の命令を持たないと Clang が文書化しているもの、そしてドキュメントコメントとコンパイルされたコードが食い違うものです。形式はコンパイラーに依存します。別のコンパイラーや、同じコンパイラーでも別のオプションでは、等価な別の命令が選ばれることがあります。

各呼び出しは、Clang の実行ドメインパス (execution-domain pass) を無効にしてコンパイルします。プログラム全体の中では、このパスは周囲のコードに合わせて、ある命令を、ビット上は同じ処理をしながら別のデータ型を想定する命令 (PAND と ANDPS など) に置き換えることがあります。単独でコンパイルした呼び出しには周囲のコードがないため、このパスを有効にしたままだと、整数の組み込み関数に対しても浮動小数点の形式を選んでしまいます。そのため、載せている形式は、各組み込み関数自身の型に対して Clang が選択するものです。_mm_and_si128 は PAND とともに載せていますが、このサイトのビルドでは -O2 のとき、結果をストアするか返すだけの場合に Clang はこれに ANDPS を出力し、整数演算が続く場合に PAND を出力します。

出典

  1. The LLVM Project, whose Clang has the x86 intrinsic headers in clang/lib/Headers
  2. Intel XED, the X86 Encoder Decoder