
2026/05/31 2:27
Intel 8087 フローティングポイントチップ内部のマイクロコード:レジスタ間交換
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
研究者らは、インテルの 1980 年製の 8087 フロートポイントチップを逆工程化することに成功し、これまで文書化されていなかったマイクロコードアーキテクチャを初めて解明しました。化学的に ROM の金属層を溶解させ、高度なニューラルネットワークを用いてトランジスタの配置をマッピングすることで、チームは内部 80 ビット形式(符号部の仮分数ビット 64 ビット、指数部 15 ビット、符号ビット)を発見し、マイクロ指令より 1,600 を超えるものを解読しました。このチップの中央にあるマイクロコード ROM は、トランジスタあたり 4 つの電圧レベルを持つ半アナログ技術を用いて、1,648 の 16 ビット指令を格納しています。そのアーキテクチャは、スタックシステム経由でアクセスされる 8 つのスタックレジスタ(ST)、2 つの内部一時レジスタ、および値の有効性、特別値(無限大/NaN)、ゼロ、または空とラベル付けするためのタグビットを採用し、パフォーマンス向上とエラー検出を最適化しています。当初は数学演算を最大 100 倍加速させる高速コプロセッサとして販売されたこの 8087 は、特別値を効率的に処理し、
arctan といった複雑な操作を実装する際、数百のマイクロコードステップ(例:FXCH 指令は 14 のマイクロ指令を使用)を利用します。チームは例外事象を 6 つの種類(無効な操作、非正規化された操作、ゼロ除算、オーバーフロー、アンダーフロー、精度損失)に分類し、これらが割り込みを引き起こすか、またはマスクされて NaN や無限大を設定できるようになっています。このブレイクスルーにより、数十年にわたる歴史的コンピューティングデータを検証する確認済みの回路図が提供され、オープンなマッピングは高精度なソフトウェアエミュレータとシミュレータの実現、陳腐化したシステムへの互換性レイヤーのサポート、そして希少な物理コンポーネントを必要とせずに初期プロセッサ設計を学ぶための教育リソースとしての活用が期待されています。本文
Intel 8087 チップのマイクロコード解析:FXCH 命令と例外処理の内側
はじめに
1980 年、インテルは浮動小数点演算を最大で 100 倍も高速化するコプロセッサ「8087 ファイニングポイントチップ」を発表しました。この規格は現在まで多くのプロセッサの標準となり続けています。
- 内部構造: 平方根や三角関数などの複雑な演算子は、低水準の 「マイクロコード」 によって実装されています。
- 本研究の目的: 「Opcode Collective(オペコードコレクティブ)」の一員として、8087 の特定の命令である 「FXCH(浮動小数点データ交換)」 命令に関するマイクロコードの詳細動作を解説します。
1. Intel 8087 チップの物理構造と内部回路
8087 チップは 40 ピンの DIP パッケージに搭載されており、中心にはマイクロコード ROM が配置されています。顕微鏡撮影により以下のブロックが確認されました。
- マイクロコード ROM(中央部)
- マイクロインストラクションを保持する主要な回路です。
- チップ全体の約半分以上の面積を占めています。
- マイクロコードエンジン(左側)
- マイクロコード ROM を順次読み出し、ジャンプやサブルーチン呼出を制御します。
- データパス(下半分)
- 実際に浮動小数点計算を実行する部分です。
- 回路は以下に分割されています:
- 指数部用: 16 ビットバス
- 有効数字(分数部)用: 64 ビットバス
データ保存とレジスタ構造
本稿では、赤色で強調された 「一時レジスタ」 と 「スタックレジスタ」 に焦点を当てます。
- 値の保持形式
- チップ内部では、全て 「80 ビット浮動小数点数」 形式で処理されます。
- 構成要素:有効数字 (64 ビット) + 指数部 (15 ビット) + 符号ビット。
- レジスタの役割
- 一時レジスタ: 2 つ(各々、指数部と分数部を持ち、2 つのタグビット装備)。
- スタックレジスタ: 8 つ(同上、各々 2 つのタグビット装備)。
- スタック制御回路
- スタック管理、トップ・オブ・スタック (現在の最上位要素) の追跡を行います。
アーキテクチャの特性
- スタックベース設計:
- コンパイラ設計や関数呼び出しを簡素化することを目的としていましたが、全ての命令が「スタックの最上部」を扱うという特徴があり、直感的でない場合があります。
- 例:
という番号指定ではなく、スタックの頂上からの位置で参照します(値が移動するため意味は変化します)。ST(3)
- タグビット(Tag bits)による状態管理:
- レジスタの状態を以下のタグで識別・最適化します。
:正常な浮動小数点数。有効
:無限大、NaN(非数)、非正規化値。特殊
:0 の値。ゼロ
:ポップされた直後などの未使用状態。空
- エラー検出: 無効な操作(例:空のレジスタを読み取る)を防止し、「Invalid Operation」例外を発生させます。
- レジスタの状態を以下のタグで識別・最適化します。
重要:8087 はこれら 2 つの独立したデータパス(指数部用、有効数字用)とタグビットを組み合わせることで、複雑な計算とエラー検出を実現しています。
2. FXCH 命令の実装(マイクロインストラクション構造)
FXCH 命令は「スタック最上位」と「指定されたスタック位置」の値を交換する単純な処理に見えますが、実際には 14 つのマイクロインストラクション で複雑に実装されています。
マイクロインストラクションの種類
8087 のマイクロコード ROM(計 1,648 個)はすべて 16 ビットで構成され、以下の機能を持ちます:
| 種類 | 説明 | 具体的な処理例 |
|---|---|---|
| 第 1 種 | データ転送演算 | レジスタ間の読み書き(ソース/ディスティネーション指定)。 |
| 第 2 種 | シフト演算 | バレルシフターによる値の左/右シフト。 |
| 第 3 種 | 加減算器利用 | 加算・減算に加え、ループ内での乗除も利用可能。 |
| 第 4 種 | 演算制御 | 加減算器の設定や丸めモードの指定など。 |
| ジャンプ類 | 分岐処理 | (固定先へ)、(近接先へ)等の条件分岐。 |
| その他 | 特殊処理 | サブルーチン復帰、例外発生、レジスタ更新など。 |
FXCH マイクロコードのフローチャート
FXCH 命令に対応する 14 ステップの詳細は以下の通りです。
#0200: ST(0) -> tmpA [スタック最上位を読み出す] #0201: nop [サイクルを待機] #0202: ST(i) -> tmpB [指定されたレジスタを読み出す] #0203: if !(empty) jmp #0210 [両方空でない場合、正常処理へジャンプ] #0204: set invalid exception [エラーパス:例外を発生させる] #0205: if (unmasked) jmp #0213 [例外がマスキされていないなら終了] -- エラー処理詳細 -- #0206: if !(tmpA empty) -> OK #0207: if tmpA empty -> NaN を tmpA に代入 #0208: if !(tmpB empty) -> OK #0209: if tmpB empty -> NaN を tmpB に代入 -- 正常処理 (ハッピーパス) -- #0210: tmpB -> ST(0) [入れ替え:tmpB の値を最上位に保存] #0211: nop [サイクルを待機] #0212: tmpA -> ST(i) [入れ替え:tmpA の値を指定位置に保存] #0213: RNI [ルーチン終了:次の命令へ進出] #0214 - #0216: nop [未使用]
動作原理の关键点
- 条件付きジャンプ: マイクロアドレス #0203 は、一時レジスタが「空」かどうか(タグビット確認)をチェックします。
- もし空なら、例外設定マイクロコードへ分岐。
- 条件フィールドの反転ビットにより、オフセット +6 を用いて #0210 へジャンプします。
- 相対オフセットの利点: マイクロアドレスを直接指定せず、オフセット(6 ビットで十分)を使用することで回路設計が簡潔になります。
- 例外の扱い:
- 空レジスタを検知 →
ラッチ設定。Invalid Exception - 例外がアンマスキ(無視できない)場合 → CPU インタラプトへ伝播し、処理中断。
- 例外がマスキされた場合 → 計算を継続。空のレジスタは NaN で置換されます。
- 空レジスタを検知 →
- 入れ替えの仕組み: 実際に値の交換は、読み出した
とtmpA
を逆順(対照的な位置)に書き込むことで行われます。tmpB
3. 例外処理システム
8087 は以下のように例外を分類し、ソフトウェア側で振る舞いを選べます。
異常の 6 大カテゴリ
- 無効な操作 (Invalid Operation)
- 例:負の数の平方根、空のレジスタへのアクセス。
- オーバーフロー (Overflow)
- 表現可能な最大値を超えた場合。
- アンダーフロー (Underflow)
- 表現可能な最小値を下回った場合。
- ゼロ除算 (Zero Divide)
- 0 を除数とした場合。
- 精度不足 (Precision)
- 浮動小数点数として正確に表せない場合(例:1/3)。
- 非正規化演算 (Denormalized Operation)
- 極めて小さい値の処理時。
ハンドリング方式
プログラマーは各例外に対して以下のいずれかを選択できます。
- インタラプト (CPU 停止・ソフトウェア処理)
- 例:回避策を実行、ログを記録、プログラムを終了させる。
- マスキング(継続実行)
- ハードウェアが自動的に値を置換します:
- オーバーフロー → 無限大 (
)Inf - 無効な操作 →
NaN - 精度不足 → 丸め処理
- オーバーフロー → 無限大 (
- ハードウェアが自動的に値を置換します:
マイクロコードとハードウェアの連携
- 検知:
コマンドでラッチが立つ。set invalid exception - 判断: 制御レジスタのマスキビットと、ステータスレジスタのフラグを組み合わせて、実際に CPU が停止すべきか判断します。
- 完了: RNI(次の命令実行)指令後、例外フリップフロップはステータスレジスタにコピーされ、プログラマーの確認可能となります。
4. マイクロコード ROM の抽出と解析
8087 のマイクロコード ROM は当時としては大容量であり、26,368 ビットのデータを格納していました(標準 ROM の 2 倍)。
- 特殊構造: トランジスタ 1 個あたり 2 ビットを格納可能にする設計。
- 半アナログ方式: 4 つの電圧レベルで情報を表現し、コンパレータにより変換。
リバースエンジニアリングのプロセス
- 画像取得: チップを開封し、金属層を溶解後に高解像度撮影。
- トランジスタマッピング:
- 回路の行や列がシャッフル・反転している場合があるため、回路図分析と対照。
- グリッド状の配置からビットパターンへの変換。
- 意味の割り当て:
- 特許には記載がないため、回路解析とパターンの組み合わせで推定。
- ハードウェアレベルでの完全な理解は進められています。
おわりに:今後の展望と謝辞
8087 のマイクロコードは当時の技術的限界において特殊ケースやハック(副作用ありのジャンプなど)が多く含まれています。私個人および「Opcode Collective」として、このリバースエンジニアリングを継続しており、詳細は以下のプラットフォームで報告します。
- Bluesky:
@righto.com - Mastodon:
[email protected] - GitHub リポジトリ: 8087 マイクロコードの解析データ。
この作業に協力した Smartest Blob および Gloriouscow へ感謝いたします。
脚注: 本稿の執筆には AI は一切使用されておりません(em ダッシュを含む)。