# 機能設計書 30-x86_64バックエンド

## 概要

本ドキュメントは、Zigコンパイラのx86_64ネイティブバックエンド機能について記述する。この機能は、ZigのAIR（Abstract Intermediate Representation）を直接x86_64マシンコードに変換する、Zigで実装された純粋なコード生成バックエンドである。

### 本機能の処理概要

**業務上の目的・背景**：
LLVMは強力なコード生成能力を提供するが、巨大な依存関係であり、コンパイル時間やバイナリサイズの増大を招く。Zigのx86_64ネイティブバックエンドは、LLVMに依存せずに高速なコンパイルを実現し、インクリメンタルコンパイルをサポートする。開発時のイテレーション速度を重視するデバッグビルドに特に有効である。

**機能の利用シーン**：
- デバッグビルドでの高速コンパイル
- インクリメンタルコンパイル（-fincremental）の利用時
- LLVMなしのZigコンパイラビルド時
- 組み込みシステムや小さなバイナリが必要な場合

**主要な処理内容**：
1. AIRからMIR（Machine Intermediate Representation）への変換
2. レジスタ割り当て
3. 命令の合法化（Legalization）
4. 命令のエンコーディング
5. オブジェクトファイルの出力

**関連システム・外部連携**：
- リンカ（ELF、Mach-O、COFF形式のオブジェクト出力）

**権限による制御**：
本機能は特定の権限制御を持たない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 実行ファイルビルド画面 | 遷移先機能 | x86_64向けネイティブコード生成処理 |

## 機能種別

コード生成処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -fno-llvm | フラグ | No | LLVMを使用せずネイティブバックエンドを使用 | - |
| -target | 文字列 | No | ターゲット指定（x86_64-...） | x86_64アーキテクチャ |
| -fincremental | フラグ | No | インクリメンタルコンパイルを有効化 | - |

### 入力データソース

- AIR（Zig Abstract Intermediate Representation）
- ターゲット情報（x86_64固有の設定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| オブジェクトファイル | バイナリ | x86_64マシンコード（.o/.obj） |
| MIR（デバッグ用） | テキスト | Machine IR（デバッグログ時） |

### 出力先

- 指定された出力ディレクトリまたはキャッシュディレクトリ

## 処理フロー

### 処理シーケンス

```
1. AIRの取得
   └─ Semaから渡されたAIRを取得

2. 合法化（Legalization）
   └─ legalizeFeatures()で必要な変換を定義
   └─ ベクトル操作のスカラー化
   └─ 整数キャストの展開

3. コード生成（CodeGen）
   └─ AIR命令をMIR命令に変換
   └─ レジスタ割り当て
   └─ スタックフレーム構築

4. 低レベル変換（Lower）
   └─ MIR命令を具体的なx86_64命令に変換

5. エミット（Emit）
   └─ x86_64命令をバイナリにエンコード
   └─ リロケーション情報の生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[AIR取得]
    B --> C[合法化フィーチャー適用]
    C --> D[CodeGen: AIR→MIR変換]
    D --> E[レジスタ割り当て]
    E --> F[Lower: MIR→x86_64命令変換]
    F --> G[Emit: バイナリエンコード]
    G --> H[オブジェクトファイル出力]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ベクトルスカラー化 | 多くのベクトル操作をスカラー化して処理 | legalizeFeatures |
| BR-02 | パックド構造体展開 | パックド構造体のロード/ストアを展開 | legalizeFeatures |
| BR-03 | SysV ABI / Win64 ABI | OSに応じた呼び出し規約を使用 | 関数呼び出し時 |

### 計算ロジック

**合法化フィーチャー**:
```zig
pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features {
    return comptime &.initMany(&.{
        .scalarize_mul_sat,
        .scalarize_div_floor,
        .scalarize_mod,
        .scalarize_add_with_overflow,
        .scalarize_sub_with_overflow,
        .scalarize_mul_with_overflow,
        .scalarize_shl_with_overflow,
        .scalarize_shr,
        .expand_intcast_safe,
        .expand_packed_load,
        .expand_packed_store,
        // ... 他多数
    });
}
```

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OutOfRegisters | レジスタ不足 | レジスタ割り当て失敗 | コードを簡素化 |
| CodeGenError | コード生成エラー | サポートされない操作 | エラーメッセージを確認 |

### リトライ仕様

本機能にリトライ機構は存在しない。

## トランザクション仕様

本機能はトランザクションを使用しない。

## パフォーマンス要件

- LLVMより高速なコンパイル
- インクリメンタルコンパイルでの変更箇所のみ再生成
- デバッグビルドに最適化

## セキュリティ考慮事項

- スタックフレームの適切な構築
- 安全なメモリアクセスパターン

## 備考

- 現在開発中であり、全ての最適化が実装されているわけではない
- LLVMバックエンドと比較して生成コードの品質は劣る場合がある
- インクリメンタルコンパイルのサポートが主な利点

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

x86_64バックエンドの主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | bits.zig | `src/codegen/x86_64/bits.zig` | Register、Memory、Condition等の基本型 |
| 1-2 | Mir.zig | `src/codegen/x86_64/Mir.zig` | Machine IR命令の定義 |
| 1-3 | abi.zig | `src/codegen/x86_64/abi.zig` | SysV/Win64 ABIの定義、RegisterManager |

**読解のコツ**:
- Register enumがx86_64の全レジスタを定義
- Memory構造体がアドレッシングモードを表現
- MCValue unionが値の位置（レジスタ、メモリ、即値等）を表現

#### Step 2: 合法化フィーチャーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CodeGen.zig | `src/codegen/x86_64/CodeGen.zig` | legalizeFeatures関数（36-77行目） |

**主要処理フロー**:
- **36-77行目**: scalarize_*でベクトル操作をスカラー化
- **65-76行目**: expand_*でパックド構造体等を展開

#### Step 3: コード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CodeGen.zig | `src/codegen/x86_64/CodeGen.zig` | MCValue union（173-231行目） |

**主要処理フロー**:
- **173行目〜**: MCValue定義 - 値の位置を表現
- **232-266行目**: isModifiable, isBase, isMemory等のヘルパー関数

#### Step 4: 命令エンコーディングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Encoding.zig | `src/codegen/x86_64/Encoding.zig` | x86_64命令エンコーディング |
| 4-2 | encoder.zig | `src/codegen/x86_64/encoder.zig` | エンコーダユーティリティ |
| 4-3 | Emit.zig | `src/codegen/x86_64/Emit.zig` | バイナリ出力 |

### プログラム呼び出し階層図

```
Compilation
    │
    ├─ codegen選択
    │      │
    │      └─ x86_64ネイティブバックエンド（-fno-llvm時）
    │             │
    │             ├─ legalizeFeatures() [合法化フィーチャー取得]
    │             │
    │             ├─ CodeGen [AIR→MIR変換]
    │             │      ├─ レジスタ割り当て（RegisterManager）
    │             │      ├─ スタックフレーム構築
    │             │      └─ MIR命令生成
    │             │
    │             ├─ Lower [MIR→具体命令変換]
    │             │
    │             └─ Emit [バイナリエンコード]
    │                    ├─ Encoding [命令フォーマット]
    │                    └─ encoder [エンコードユーティリティ]
```

### データフロー図

```
[入力]                    [処理]                         [出力]

AIR ────────────────────▶ legalizeFeatures適用
                              │
                              ▼
                         CodeGen
                              │
                              ├─ MCValue割り当て
                              │   - register
                              │   - memory
                              │   - immediate
                              │   - load_frame
                              │   - etc.
                              │
                              ├─ RegisterManager
                              │   - レジスタ追跡
                              │   - スピル処理
                              │
                              └─ MIR命令生成
                                    │
                                    ▼
                              Lower
                                    │
                                    ▼
                              Emit ─────────────────────▶ オブジェクトファイル
                                                           x86_64マシンコード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CodeGen.zig | `src/codegen/x86_64/CodeGen.zig` | ソース | メインコード生成ロジック |
| Mir.zig | `src/codegen/x86_64/Mir.zig` | ソース | Machine IR定義 |
| Lower.zig | `src/codegen/x86_64/Lower.zig` | ソース | MIR→具体命令変換 |
| Emit.zig | `src/codegen/x86_64/Emit.zig` | ソース | バイナリエミット |
| Encoding.zig | `src/codegen/x86_64/Encoding.zig` | ソース | 命令エンコーディング定義 |
| encoder.zig | `src/codegen/x86_64/encoder.zig` | ソース | エンコーダユーティリティ |
| bits.zig | `src/codegen/x86_64/bits.zig` | ソース | レジスタ、メモリ、条件コード定義 |
| abi.zig | `src/codegen/x86_64/abi.zig` | ソース | ABI定義、RegisterManager |
| Disassembler.zig | `src/codegen/x86_64/Disassembler.zig` | ソース | 逆アセンブラ（デバッグ用） |

### MCValue（Machine Code Value）の種類

| 種類 | 説明 |
|------|------|
| none | ランタイムビットなし（void、空構造体等） |
| unreach | 到達不能コード |
| dead | 参照終了 |
| undef | 未定義値 |
| immediate | 即値（ポインタサイズ整数） |
| eflags | EFLAGSレジスタ（条件コード） |
| register | レジスタに格納 |
| register_pair | 2レジスタに分割格納 |
| register_triple | 3レジスタに分割格納 |
| register_quadruple | 4レジスタに分割格納 |
| register_offset | レジスタ + オフセット |
| memory | 固定アドレスのメモリ |
| indirect | レジスタ間接参照 |
| load_frame | フレームからのロード |
| lea_frame | フレームアドレスの取得 |
