x87は、 x86アーキテクチャ命令セットの浮動小数点関連のサブセットです。これは、対応するx86 CPUと連携して動作するオプションの浮動小数点コプロセッサ(FPU )の形で、8086命令セットの拡張として始まりました。これらのマイクロチップの名前は「87」で終わります。これはNPX(数値プロセッサ拡張)としても知られています。基本命令セットの他の拡張と同様に、x87命令は厳密には動作するプログラムを構築するために必要ではありませんが、一般的な数値タスクのハードウェアおよびマイクロコード実装を提供し、これらのタスクを対応するマシンコードルーチンよりもはるかに高速に実行できるようにします。x87命令セットには、加算、減算、比較などの基本的な浮動小数点演算の命令だけでなく、たとえば正接関数とその逆関数の計算などのより複雑な数値演算の命令も含まれています。
Intel 80486以降のほとんどのx86プロセッサでは、これらのx87命令がメインCPUに実装されていますが、この用語は命令セットのその部分を指すために今でも使われることがあります。x87命令がPCで標準になる前は、コンパイラやプログラマは浮動小数点演算を実行するためにかなり遅いライブラリ呼び出しを使用する必要がありました。この方法は、(低コストの)組み込みシステムでは今でも一般的です。
x87レジスタは、ST(0)からST(7)までの8階層の非厳密スタック構造を形成し、レジスタはオペランドによって直接アクセスでき、最上位からのオフセットを使用するとともに、プッシュおよびポップも可能です。(この方式は、スタックフレームのプッシュ/ポップとインデックス指定の両方に似ています。)
このスタックの最上位に値をプッシュ、計算、ポップするための命令があります。単項演算(FSQRT、FPTAN など) は暗黙的に最上位の ST(0) をアドレス指定し、二項演算(FADD、FMUL、FCOM など) は暗黙的に ST(0) と ST(1) をアドレス指定します。非厳密スタック モデルでは、二項演算で ST(0) を直接メモリ オペランドまたは明示的に指定されたスタック レジスタ ST( x ) とともに使用することもでき、これは従来のアキュムレータ(宛先と左オペランドの組み合わせ) と同様の役割を果たします。命令ごとに、ST(0) を変更しないオペランド、ST( x ) を宛先として、この動作を逆にすることもできます。さらに、FXCH ST( x )という命令を使用して、ST(0) の内容を別のスタック レジスタと交換することもできます。
これらの特性により、x87スタックは7つの自由にアドレス指定可能なレジスタと専用のアキュムレータ(または7つの独立したアキュムレータ)として使用できます。これは特にスーパースカラx86プロセッサ(1993年以降のPentiumなど)に適用され、これらの交換命令(コードD9C8..D9CF h)は、FXCH ST( x )の整数パスの1つをFPU命令と並列に使用することで、クロックペナルティがゼロになるように最適化されます。アセンブリ言語プログラマにとっては自然で便利であるにもかかわらず、一部のコンパイラ開発者は、x87コードを効率的にスケジュールする自動コードジェネレータを構築するのが複雑だと感じています。このようなスタックベースのインターフェースは、レジスタベースのインターフェースと比較して、関数呼び出しでスクラッチ変数を保存する必要性を最小限に抑える可能性があります[ 1 ](ただし、歴史的には、8087実装の設計上の問題により、その可能性は制限されていました[ 2 ] [ 3 ])。
x87 は、 IEEE 754-1985規格に従って、単精度、倍精度、および 80 ビット倍拡張精度のバイナリ浮動小数点演算を提供します。デフォルトでは、x87 プロセッサはすべて内部で 80 ビット倍拡張精度を使用します (多くの計算にわたって精度を維持するため、IEEE 754 設計の根拠を参照)。したがって、特定の一連の算術演算は、厳密な単精度または倍精度の IEEE 754 FPU と比較してわずかに異なる動作をする場合があります。[ 4 ]これは、正しい動作のために倍精度を前提として記述された一部の半数値計算で問題になる場合があるため、このような問題を回避するために、x87 は、特別な構成/ステータス レジスタを使用して、基本的な算術演算 (加算、減算、乗算、除算、および平方根) の後に単精度または倍精度に自動的に丸めるように構成できます。[ 5 ]対数、指数、三角関数などは常に倍精度(80ビット)になります。SSE2 の導入以来、 x87命令はかつてほど重要ではなくなりましたが、丸め誤差に敏感で、80ビット形式で利用可能な64ビット仮数精度と拡張範囲を必要とする数値計算のための高精度スカラーユニットとして依然として重要です。
典型的な x87 FPU 命令の例のクロックサイクル数 (ここではレジスタ-レジスタ版のみを表示)。[ 6 ]
A ... B表記(最小値から最大値)は、パイプラインの一時的な状態や選択された演算精度(32、64、または80ビット)によって生じるタイミングの変動を表します。また、数値的なケース(セットビット数、ゼロなど)による変動も含まれます。L → H表記は、利用可能な最大クロック周波数の最小値(L)と最大値(H)に対応する値を表します。
Intel 8087以降のモデルと互換性のある浮動小数点演算ユニットを設計または製造した企業には、AMD(287、387、486DX、5x86、K5 、 K6、K7、K8 )、 Chips and Technologies ( Super MATHコプロセッサ)、 Cyrix ( FasMath 、 Cx87SLC 、 Cx87DLCなど、6x86、Cyrix MII )、富士通(初期のPentium Mobileなど)、Harris Semiconductor(80387および486DXプロセッサを製造)、IBM(様々な387および486設計)、IDT(WinChip、C3、C7、Nanoなど)、IIT(2C87、3C87など)、LC Technology(Green MATHコプロセッサ)、National Semiconductor(Geode GX1)などがある。、Geode GXmなど)、NexGen ( Nx587 )、Rise Technology ( mP6 )、ST Microelectronics ( 486DX、5x86などを製造)、Texas Instruments ( 486DXプロセッサなどを製造)、Transmeta ( TM5600およびTM5800 )、ULSI ( Math·Coコプロセッサ)、VIA ( C3、C7、Nanoなど)、Weitek ( 1067、1167、3167、4167 )、およびXtend ( 83S87SX-25およびその他のコプロセッサ)。
8087は、 Intelが設計した16ビットプロセッサ向け初の数学コプロセッサでした。1980年にIntel 8088または8086マイクロプロセッサと組み合わせて使用されることを想定してリリースされました。(Intelの以前の浮動小数点プロセッサである8231と8232は、i8080 CPUで使用するために販売されていましたが、実際には1977年と1979年のAMDのAm9511とAm9512 FPUのライセンス版でした。[ 7 ])

( NMOSベースの)80188と80186の1982年のオリジナルデータシートには特定の数学コプロセッサについて言及されているようですが、[ 8 ]実際には両方のチップは8087とペアになっていました。
しかし、1987年に、改良されたCMOSベースのIntel 80C186 CPUに対応するため、Intelは80C187 [ 9 ]数学コプロセッサを導入しました。80C187のメインプロセッサへのインターフェースは8087と同じですが、そのコアは基本的に80387SXのものであり、IEEE 754に完全準拠しており、80387の追加命令をすべて実行できます。[ 10 ]
1982 年にリリースされた80287 ( i287 )は、Intel 80286シリーズマイクロプロセッサ用の数値計算コプロセッサです。Intel のモデルには、最大周波数制限が 6 MHz から 12 MHz まで指定されたバリアントが含まれていました。NMOS バージョンは 6、8、10 MHz で利用可能でした。[ 11 ] 10 MHz の Intel 80287-10 数値計算コプロセッサ バージョンは、100 個単位で250米ドルでした。 [ 12 ]これらのボックス版の 80287、80287-8、および 80287-10 は、それぞれ 212 ドル、326 ドル、および 374 ドルで利用可能でした。ボックス版の 80C287A は 457 ドルで利用可能でした。[ 13 ]
387と同等の性能を持つ他の287モデルとしては、 CHMOS IIIを使用して製造されたIntel 80C287と、AMDのCMOSプロセスで製造され、完全静的ゲートのみを使用するAMD 80EC287がある。
その後、287ピン配置の387SXマイクロアーキテクチャを採用したi80287XL [ 14 ] 、ラップトップ向け特別バージョンのi80287XLT、その他のバリアントが登場しました。内部に3/2乗算器が搭載されているため、コプロセッサをCPU速度の2/3で実行するマザーボードでは、FPUをCPUと同じ速度で実行できます。80287XLと80287XLTはどちらも、50%優れたパフォーマンス、83%低い消費電力、および追加の命令を提供しました。[ 15 ]
80287は80386マイクロプロセッサと連携して動作し、1987年に80387が登場するまでは、80386用の唯一のコプロセッサでした。80387は、その高い性能と豊富な命令セットにより、広く好まれています。

80387 ( 387またはi387 )は、 IEEE 754-1985規格に完全に準拠した最初の Intel コプロセッサです。1987 年にリリースされた i387 は、 386 チップの 2 年後に発売され[ 16 ]、Intel の以前の 8087/80287 コプロセッサよりも大幅に高速化され、三角関数の特性も向上しています。100 個単位で 500 ドルで販売されました。[ 17 ]その後まもなく、Intel のパーソナル コンピュータ エンハンスメント オペレーションを通じて、小売市場価格 795 ドルで販売されました。[ 18 ] 25 MHz バージョンは、小売チャネルで 1395 ドルで販売されました。[ 19 ] Intel M387 数学コプロセッサは、MIL-STD-883 Rev. C 規格に準拠しています。このデバイスは、-55~125℃の温度サイクル、気密シール、および長時間のバーンインを含むテストを受けました。この軍用バージョンは16MHzで動作します。この軍用バージョンは、68リードPGAとクワッドフラットパックで入手可能でした。この軍用バージョンは、PGAバージョンの場合、100ユニット単位で1155米ドルで入手可能でした。[ 20 ] 33MHzバージョンの387DXが利用可能で、毎秒3.4メガ砥石の性能があります。[ 21 ] 16、20、25、および33MHzの387DX数学コプロセッサのボックス版は、それぞれ570、647、814、および994米ドルで入手可能でした。[ 22 ] 8087と80287のFPTANとFPATAN命令は、引数の範囲が±π/4(±45°)に制限されており、8087と80287にはSIN関数とCOS関数を直接扱う命令はありません。[ 23 ]
コプロセッサがない場合、386は通常、(比較的低速な)ソフトウェアルーチンを介して浮動小数点演算を実行します。このルーチンは、実行時にソフトウェア例外ハンドラによって実装されます。386に数学コプロセッサを組み合わせると、コプロセッサがハードウェアで浮動小数点演算を実行し、(エミュレーションによる)ソフトウェアライブラリ呼び出しよりもはるかに高速に結果を返します。
i387は、32ビットプロセッサバスを持つ標準のi386チップとのみ互換性があります。後にコスト削減されたi386SXは、より狭い16ビットデータバスを持ち、i387の32ビットバスとインターフェースできません。i386SXには、SXのより狭い16ビットデータバスと互換性のある独自のコプロセッサ80387SXが必要です。387SXコプロセッサには、低消費電力バージョンも提供されていました。[ 21 ]
さらに、ノートパソコンで使用されるi386SLと組み合わせるために、Intel はi387SL (N80387SL) をリリースしました。[ 24 ]「Intel387 SL モバイル数学コプロセッサ」として販売されたこのコプロセッサには、バッテリー寿命を大幅に低下させることなく動作できる電力管理機能が含まれています。バッテリー節約のための電源ダウン機能は 2 つあります。1 つ目は、CPU が「ストップクロック」モードに入るとコプロセッサのクロックを停止します。387SL は、クロックが停止しているときに約 25 マイクロアンペアを消費します。2 つ目は、CPU が動作しているときに自動的に動作し、命令を実行していないときに 387SL を「アイドルモード」にします。アクティブ状態では、387SL は通常 387SX よりも 30% 少ないバッテリー電力 (約 100 mA) を消費します。アイドルモードでは、4 mA を消費し、アクティブモードと比較して 96% の電力削減となります。 16~25MHzの範囲で動作し、BIOSやハードウェアの再構成は不要です。[ 25 ]当初は189米ドルで販売されていました。[ 26 ]

1991年に発表されたi487SX(P23N)は、Intel i486SXマシン用の浮動小数点ユニットコプロセッサとして販売されました。実際には、完全なi486DX実装が含まれていました。i486SXシステムにインストールされると、i487はメインCPUを無効にし、すべてのCPU操作を引き継ぎました。i487のマニュアルには、i486SXがないとユニットが機能しないと記載されていますが、独立したテスト(および後のIntelの承認)により、そうではないことが明らかになりました。[ 27 ] [ 28 ] [ 29 ]
i487は、通常の168ピン486ソケットへの挿入を防ぐために、接続されていない(物理的なキーイング)ピンを備えた特別な169ピンソケットを使用していた。少なくとも2つの情報源は、このソケットは、同様のプロセッサ交換であるi486 OverDriveのアップグレードソケットであるSocket 1と同じであると主張している。[ 30 ] [ 29 ]
i486DX/i487SXのFPU命令セットは387と変わりませんでしたが、統合によってバス利用率が向上しました。オンチップアルゴリズムも改良されました。
コンピュータ支援設計用途向けに販売されている386から486へのアップグレードパッケージであるRapidCADには、互換性のために80387ソケットにインストールされるダミーFPU(RapidCAD-2)も含まれています。これは、メインプロセッサ(RapidCAD-1、486DX)にデフォルトで統合FPUが搭載されているためです。
1995年に発売されたNexGen社のNx586プロセッサ向けFPUであるNx587は、CPUとは別に製造された最後のx87コプロセッサだった。
精度制御ビットは、次の浮動小数点命令の結果にのみ影響します: FADD、FADDP、FIADD、FSUB、FSUBP、FISUB、FSUBR、FSUBRP、FISUBR、FMUL、FMULP、FIMUL、FDIV、FDIVP、FIDIV、FDIVR、FDIVRP、FIDIVR、および FSQRT。