# 画面設計書 31-CPU検出画面

## 概要

本ドキュメントは、Zigコンパイラの `zig detect-cpu` コマンド（CPU検出画面）の設計仕様を定義する。このコマンドは、ホストマシンのCPU名と機能セット（Feature Set）を検出して標準出力に表示するデバッグ用コマンドである。

### 本画面の処理概要

CPU検出画面は、ZigコンパイラにおいてホストシステムのCPU情報を取得し、コンパイラが認識しているCPU機能を確認するためのデバッグツールである。ZigのネイティブCPU検出機能とLLVMのCPU検出機能を比較することで、両者の差異を調査・分析することができる。

**業務上の目的・背景**：
Zigコンパイラは、ターゲットアーキテクチャに応じた最適なコード生成を行うために、CPUの機能セット（SIMD命令、特殊命令など）を正確に把握する必要がある。しかし、ZigのCPU検出ロジックとLLVMのCPU検出ロジックは異なる実装を持つため、両者の検出結果に差異が生じる可能性がある。本コマンドは、開発者がこれらの差異を調査し、CPU機能検出に関するバグの特定やデバッグを行うために提供されている。特に、クロスコンパイル時の最適化問題やCPU機能の誤検出によるコンパイルエラーの診断に有用である。

**画面へのアクセス方法**：
ターミナル（コマンドライン）から `zig detect-cpu` コマンドを実行する。このコマンドはデバッグビルドでのみ利用可能であり、リリースビルドのZigコンパイラでは実行できない。

**主要な操作・処理内容**：
1. `zig detect-cpu`：Zigのネイティブ実装によるCPU機能検出を実行し、CPU名と有効/無効な機能一覧を出力
2. `zig detect-cpu --llvm`：LLVM APIを使用してCPU機能検出を実行し、結果を出力
3. `zig detect-cpu -h / --help`：コマンドのヘルプメッセージを表示

**画面遷移**：
- 遷移元：zig コマンド（エントリポイント）から直接アクセス
- 遷移先：なし（結果を標準出力に出力して終了）

**権限による表示制御**：
- デバッグビルド（`build_options.enable_debug_extensions = true`）でのみ利用可能
- リリースビルドではコマンド自体が存在しない（使用不可）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 71 | detect-cpu | 主機能 | ZigのCPU機能検出とLLVMの比較処理 |

## 画面種別

情報表示（デバッグ情報出力）

## URL/ルーティング

コマンドライン: `zig detect-cpu [options]`

## 入出力項目

### 入力（コマンドライン引数）

| 項目名 | 引数形式 | 必須 | 説明 | デフォルト値 |
|--------|----------|------|------|------------|
| help | `-h`, `--help` | No | ヘルプメッセージを表示して終了 | - |
| llvm | `--llvm` | No | LLVM APIを使用してCPU検出を実行 | false（Zig実装を使用） |

### 出力（標準出力）

| 出力項目 | 形式 | 説明 |
|----------|------|------|
| CPU名 | 文字列 | 検出されたCPUモデルのLLVM名（存在する場合） |
| 機能フラグ | `+/-{feature_name}` | 有効(+)/無効(-)なCPU機能のリスト |

## 表示項目

### 出力フォーマット

```
{cpu_llvm_name}
+{enabled_feature_1}
+{enabled_feature_2}
-{disabled_feature_1}
-{disabled_feature_2}
...
```

| 項目 | 説明 | 例 |
|------|------|-----|
| CPU名 | CPUモデルのLLVM名称 | `skylake`, `apple-m1` |
| +機能名 | 有効なCPU機能 | `+sse4.2`, `+avx2` |
| -機能名 | 無効なCPU機能 | `-avx512f`, `-amx-tile` |

## イベント仕様

### 1-コマンド実行（デフォルト）

1. ユーザーが `zig detect-cpu` を実行
2. `dev.check(.detect_cpu_command)` で開発チェックを実行
3. `std.zig.resolveTargetQueryOrFatal()` でホストターゲット情報を取得
4. `printCpu()` 関数でCPU情報を標準出力に書き出し
5. プログラムが正常終了（exit code 0）

### 2-LLVMモード実行

1. ユーザーが `zig detect-cpu --llvm` を実行
2. `build_options.have_llvm` をチェック（LLVMが利用可能か確認）
3. `llvm.GetHostCPUName()` でLLVMからCPU名を取得
4. `llvm.GetHostCPUFeatures()` でLLVMからCPU機能セットを取得
5. `detectNativeCpuWithLLVM()` でLLVM形式からZig形式に変換
6. `printCpu()` 関数で結果を標準出力に書き出し
7. プログラムが正常終了（exit code 0）

### 3-ヘルプ表示

1. ユーザーが `zig detect-cpu -h` または `zig detect-cpu --help` を実行
2. ヘルプメッセージを標準出力に表示
3. プログラムが正常終了（exit code 0）

## データベース更新仕様

### 操作別データベース影響一覧

本コマンドはデータベースを使用しない（読み取り専用の情報表示コマンド）。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベース操作なし |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 発生条件 |
|--------------|--------------|----------|
| ヘルプ | `Usage: zig detect-cpu [--llvm]...` | `-h` または `--help` オプション指定時 |
| エラー | `compiler does not use LLVM; cannot compare CPU features with LLVM` | `--llvm`指定時にLLVMが利用不可 |
| エラー | `LLVM could not figure out the host cpu name` | LLVMがCPU名を検出できない場合 |
| エラー | `LLVM could not figure out the host cpu feature set` | LLVMがCPU機能セットを検出できない場合 |
| エラー | `unrecognized parameter: '{s}'` | 不明なオプションが指定された場合 |
| エラー | `unexpected extra parameter: '{s}'` | 予期しない追加引数が指定された場合 |

## 例外処理

| 例外条件 | 処理内容 | 終了コード |
|---------|---------|-----------|
| LLVM未対応 | エラーメッセージを表示して終了 | 1 |
| CPU名検出失敗（LLVM） | エラーメッセージを表示して終了 | 1 |
| CPU機能検出失敗（LLVM） | エラーメッセージを表示して終了 | 1 |
| 不明な引数 | エラーメッセージを表示して終了 | 1 |
| 無効なLLVM機能フォーマット | `error.InvalidLlvmCpuFeaturesFormat` を返す | 1 |

## 備考

- 本コマンドはデバッグビルド限定で、`build_options.enable_debug_extensions` が `true` の場合のみ利用可能
- LLVMモードは `build_options.have_llvm` が `true` の場合のみ動作
- CPU機能名はLLVM形式で出力される（Zig内部の機能名とは異なる場合がある）
- 機能の依存関係は `populateDependencies()` によって自動的に解決される

---

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

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

### 推奨読解順序

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

CPU機能検出で使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Target.zig | `lib/std/Target.zig` | `Cpu` 構造体と `Feature.Set` の定義を確認。CPUモデルと機能セットの関係を理解する |
| 1-2 | bindings.zig | `src/codegen/llvm/bindings.zig` | LLVM APIの外部関数宣言（`GetHostCPUName`, `GetHostCPUFeatures`）を確認 |

**読解のコツ**: Zigでは `std.Target.Cpu` がCPU情報を表現する主要な構造体。`model`フィールドがCPUモデル、`features`フィールドが有効な機能セットを保持する。

#### Step 2: エントリーポイントを理解する

コマンドディスパッチ部分を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.zig | `src/main.zig` | 381-382行目のコマンドディスパッチ部分を確認 |

**主要処理フロー**:
1. **381行目**: `mem.eql(u8, cmd, "detect-cpu")` でコマンド名を判定
2. **382行目**: `cmdDetectCpu(io, cmd_args)` を呼び出し

#### Step 3: コマンド処理関数を理解する

`cmdDetectCpu` 関数の詳細処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | main.zig | `src/main.zig` | 6351-6399行目の `cmdDetectCpu` 関数を確認 |

**主要処理フロー**:
- **6352行目**: `dev.check(.detect_cpu_command)` - 開発モードチェック
- **6354-6363行目**: ヘルプメッセージ定義
- **6365行目**: `use_llvm` フラグ初期化（デフォルト false）
- **6367-6384行目**: コマンドライン引数パース
- **6386-6398行目**: CPU検出実行と出力

#### Step 4: LLVM連携処理を理解する

LLVMモード時の処理フローを追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | main.zig | `src/main.zig` | 6401-6462行目の `detectNativeCpuWithLLVM` 関数 |
| 4-2 | bindings.zig | `src/codegen/llvm/bindings.zig` | 341-345行目のLLVM API宣言 |

**主要処理フロー**:
- **6390-6393行目**: LLVM APIでCPU名と機能セットを取得
- **6406行目**: ベースラインCPU情報を初期化
- **6408-6425行目**: LLVM CPU名からZig CPUモデルへのマッピング
- **6427-6458行目**: LLVM機能文字列のパースと適用
- **6460行目**: 機能依存関係の解決

#### Step 5: 出力処理を理解する

CPU情報の出力処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | main.zig | `src/main.zig` | 6464-6482行目の `printCpu` 関数 |

**主要処理フロー**:
- **6468-6470行目**: CPUモデルのLLVM名を出力
- **6472-6478行目**: 全機能について有効/無効フラグを出力

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

```
main() [src/main.zig]
    |
    +-- mainArgs() [行番号: 256]
        |
        +-- コマンドディスパッチ [行番号: 381-382]
            |
            +-- cmdDetectCpu() [行番号: 6351-6399]
                |
                +-- [--llvm指定時]
                |   |
                |   +-- llvm.GetHostCPUName() [bindings.zig:341]
                |   +-- llvm.GetHostCPUFeatures() [bindings.zig:344]
                |   +-- detectNativeCpuWithLLVM() [行番号: 6401-6462]
                |       |
                |       +-- std.Target.Cpu.baseline() [lib/std]
                |       +-- arch.allCpuModels() [lib/std]
                |       +-- features.populateDependencies() [lib/std]
                |
                +-- [デフォルト]
                |   |
                |   +-- std.zig.resolveTargetQueryOrFatal() [lib/std]
                |
                +-- printCpu() [行番号: 6464-6482]
                    |
                    +-- stdout_bw.print() [CPU名出力]
                    +-- stdout_bw.print() [機能フラグ出力]
```

### データフロー図

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

コマンドライン引数     +--> cmdDetectCpu()
    |                 |        |
    +-- --llvm  ------+        |
    +-- -h/--help              |
                               v
                    +-------------------+
                    | 引数パース        |
                    +-------------------+
                               |
           +-------------------+-------------------+
           |                                       |
           v                                       v
  +-------------------+                 +-------------------+
  | LLVMモード         |                 | Zigモード          |
  |                   |                 |                   |
  | GetHostCPUName()  |                 | resolveTarget     |
  | GetHostCPUFeatures|                 | QueryOrFatal()    |
  +-------------------+                 +-------------------+
           |                                       |
           v                                       v
  +-------------------+                            |
  | detectNativeCpu   |                            |
  | WithLLVM()        |                            |
  +-------------------+                            |
           |                                       |
           +-------------------+-------------------+
                               |
                               v
                    +-------------------+
                    | printCpu()        |
                    +-------------------+
                               |
                               v
                    +-------------------+      標準出力
                    | CPU名              | ---> {cpu_llvm_name}
                    | 機能フラグリスト    | ---> +feature / -feature
                    +-------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.zig | `src/main.zig` | ソース | コマンドエントリポイント、`cmdDetectCpu`関数の実装 |
| bindings.zig | `src/codegen/llvm/bindings.zig` | ソース | LLVM C API のZigバインディング |
| llvm.zig | `src/codegen/llvm.zig` | ソース | LLVMコード生成バックエンド |
| Target.zig | `lib/std/Target.zig` | ソース（標準ライブラリ） | ターゲットCPU/OS/アーキテクチャの定義 |
| build_options.zig | `src/build_options.zig` | 生成ファイル | ビルド時オプション（`enable_debug_extensions`, `have_llvm`） |
