# 機能設計書 31-aarch64バックエンド

## 概要

本ドキュメントは、ZigコンパイラにおけるAArch64（ARM64）アーキテクチャ向けネイティブコード生成バックエンドの機能設計を記述する。

### 本機能の処理概要

aarch64バックエンドは、ZigコンパイラのAIR（Abstract IR）をARM64アーキテクチャ向けのマシンコードに変換する機能を提供する。この機能により、Apple Silicon（M1/M2/M3）、AWS Graviton、Raspberry Pi 4、スマートフォン等で動作するネイティブ実行可能ファイルやライブラリを生成できる。

**業務上の目的・背景**：ARM64アーキテクチャは、モバイルデバイス、組み込みシステム、最新のデスクトップ・サーバー環境で広く採用されている。ZigがARM64プラットフォームをネイティブにサポートすることで、これらの環境向けの高性能なソフトウェア開発が可能となる。特に、AppleのM1/M2/M3チップやAWSのGravitonプロセッサの普及により、ARM64向けのネイティブコード生成の重要性は高まっている。

**機能の利用シーン**：
- Apple Silicon搭載Mac向けアプリケーションのビルド
- AWS Gravitonインスタンス向けサーバーアプリケーションの開発
- Raspberry Pi 4やその他ARM64 Linux環境向けソフトウェアのクロスコンパイル
- Android（ARM64）向けネイティブライブラリの生成

**主要な処理内容**：
1. AIR命令のaarch64固有命令への変換（命令選択）
2. レジスタ割り当て（x0-x30、v0-v31の管理）
3. スタックフレームレイアウトの決定とプロローグ/エピローグ生成
4. 命令エンコーディング（32ビット固定長命令形式）
5. リロケーション情報の生成（NAV、UAV、グローバルシンボル参照）

**関連システム・外部連携**：ELFリンカ（Linux）、MachOリンカ（macOS）と連携し、生成されたマシンコードをオブジェクトファイルや実行可能ファイルに組み込む。

**権限による制御**：特になし（コンパイル時の処理）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 実行ファイルビルド画面 | 遷移先機能 | ARM64アーキテクチャ向けコード生成処理 |

## 機能種別

コード生成処理 / 計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| air | Air | Yes | 抽象中間表現（変換対象の命令列） | 有効なAIR構造であること |
| target | std.Target | Yes | ターゲットアーキテクチャ情報 | cpu.archがaarch64であること |
| nav_index | InternPool.Nav.Index | Yes | ナビゲーション識別子 | 有効なインデックスであること |
| pt | Zcu.PerThread | Yes | スレッド別コンパイル単位情報 | 有効なPerThread構造であること |

### 入力データソース

- Sema（意味解析）フェーズで生成されたAIR
- コンパイル設定から取得したターゲット情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| prologue | []const Instruction | 関数プロローグの命令列 |
| body | []const Instruction | 関数本体の命令列 |
| epilogue | []const Instruction | 関数エピローグの命令列 |
| literals | []const u32 | リテラルプール（定数データ） |
| nav_relocs | []const Reloc.Nav | ナビゲーションリロケーション |
| uav_relocs | []const Reloc.Uav | UAVリロケーション |
| global_relocs | []const Reloc.Global | グローバルシンボルリロケーション |

### 出力先

リンカ（ELF/MachO）への引き渡し、最終的にはオブジェクトファイルまたは実行可能ファイル

## 処理フロー

### 処理シーケンス

```
1. 命令選択フェーズ（Select.analyze）
   └─ AIR命令をaarch64 MIRに変換
2. レジスタ割り当て
   └─ 汎用レジスタ（x0-x30）およびベクトルレジスタ（v0-v31）の割り当て
3. スタックフレーム構築
   └─ ローカル変数、一時変数用スタック領域の確保
4. プロローグ生成
   └─ カリーセーブレジスタの保存、スタックポインタ調整
5. 本体コード生成
   └─ 各AIR命令に対応するaarch64命令の出力
6. エピローグ生成
   └─ カリーセーブレジスタの復元、関数リターン
7. 命令エンコーディング
   └─ 32ビット固定長形式への変換
8. リロケーション解決
   └─ シンボル参照の解決とリンカへの情報提供
```

### フローチャート

```mermaid
flowchart TD
    A[開始: AIR入力] --> B[命令選択]
    B --> C[レジスタ割り当て]
    C --> D[スタックフレーム構築]
    D --> E[プロローグ生成]
    E --> F[本体コード生成]
    F --> G[エピローグ生成]
    G --> H[命令エンコーディング]
    H --> I[リロケーション情報生成]
    I --> J[MIR出力]
    J --> K[終了: リンカへ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-1 | AAPCS準拠 | ARM Architecture Procedure Call Standard に従った呼び出し規約を使用 | 関数呼び出し時 |
| BR-31-2 | 16バイトスタックアライメント | スタックポインタは常に16バイト境界に整列 | 関数エントリ/関数呼び出し時 |
| BR-31-3 | レジスタ保存規則 | x19-x28、v8-v15はカリーセーブ | 関数プロローグ/エピローグ |

### 計算ロジック

- スタックサイズ: ローカル変数 + スピル領域 + 16バイトアライメント調整
- リテラルプールオフセット: PC相対アドレッシング、最大1MBオフセット

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

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OutOfRegisters | リソース枯渇 | 使用可能なレジスタ不足 | レジスタスピルを実行 |
| CodeGenFail | コード生成失敗 | サポートされていない命令パターン | エラーメッセージを生成 |
| LowerFail | 命令下降失敗 | MIR変換に失敗 | 詳細なエラー情報を報告 |

### リトライ仕様

リトライ機構は実装されていない（コンパイル時エラーとして報告）

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

該当なし

## パフォーマンス要件

- 命令選択: O(n)（AIR命令数に比例）
- コンパイル時間への影響を最小化するため、効率的なアルゴリズムを使用

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

- スタックオーバーフロー保護: プロローグでスタックプローブを挿入可能
- BTI（Branch Target Identification）サポート: 制御フロー整合性保護

## 備考

aarch64バックエンドはLLVMバックエンドの代替として開発されており、LLVMに依存しないセルフホスティングコンパイラを実現するための重要なコンポーネントである。

---

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

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

### 推奨読解順序

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

まず、MIR（Machine IR）の構造と命令エンコーディングを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Mir.zig | `src/codegen/aarch64/Mir.zig` | MIR構造体の定義、リロケーション型 |
| 1-2 | encoding.zig | `src/codegen/aarch64/encoding.zig` | Register型、Instruction型、エンコーディング仕様 |

**読解のコツ**: Mir.zigの`Reloc`構造体（11-38行目）は、シンボル参照の種類（Nav、Uav、Lazy、Global、Literal）を理解するのに重要。encoding.zigではAArch64のレジスタ命名規則（x0-x30、w0-w30、v0-v31）を確認する。

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

命令選択の起点となるSelect.zigを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Select.zig | `src/codegen/aarch64/Select.zig` | Select構造体、analyze関数 |

**主要処理フロー**:
1. **1-50行目**: Select構造体のフィールド定義（レジスタ追跡、命令バッファ、リロケーション）
2. **102-125行目**: deinit関数でのリソース解放
3. **127行目以降**: analyze関数でAIR命令のパターンマッチと変換

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

AArch64の32ビット固定長命令形式へのエンコーディングを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | encoding.zig | `src/codegen/aarch64/encoding.zig` | Instruction構造体、エンコード関数 |

**主要処理フロー**:
- **1-100行目**: Register型とサイズ指定（word/doubleword）
- **55-97行目**: Arrangement型（ベクトルレジスタのアレンジメント）

#### Step 4: MIR出力を理解する

生成されたMIRをバイナリとして出力する処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Mir.zig | `src/codegen/aarch64/Mir.zig` | emit関数（53-170行目） |

**主要処理フロー**:
- **53-91行目**: emit関数のエントリ、アライメント計算
- **93-161行目**: 各種リロケーションの処理（nav_relocs、uav_relocs、global_relocs）

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

```
codegen.zig (コード生成エントリ)
    │
    ├─ Select.zig
    │      ├─ analyze() - AIR → MIR変換
    │      ├─ emit() - 命令出力
    │      └─ merge() - ブランチマージ
    │
    ├─ Mir.zig
    │      ├─ emit() - バイナリ出力
    │      └─ emitReloc() - リロケーション処理
    │
    ├─ encoding.zig
    │      ├─ Register - レジスタ定義
    │      └─ Instruction - 命令エンコーディング
    │
    └─ abi.zig
           └─ 呼び出し規約定義
```

### データフロー図

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

AIR命令列 ───▶ Select.analyze() ───▶ MIR命令列
                     │
                     ▼
               レジスタ割り当て
                     │
                     ▼
              スタックフレーム構築
                     │
                     ▼
              Mir.emit() ───▶ バイナリコード + リロケーション
                                    │
                                    ▼
                              リンカ(ELF/MachO)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Select.zig | `src/codegen/aarch64/Select.zig` | ソース | 命令選択とAIR→MIR変換 |
| Mir.zig | `src/codegen/aarch64/Mir.zig` | ソース | MIR構造体定義とバイナリ出力 |
| encoding.zig | `src/codegen/aarch64/encoding.zig` | ソース | 命令エンコーディング |
| abi.zig | `src/codegen/aarch64/abi.zig` | ソース | 呼び出し規約（AAPCS） |
| Assemble.zig | `src/codegen/aarch64/Assemble.zig` | ソース | アセンブル処理 |
| Disassemble.zig | `src/codegen/aarch64/Disassemble.zig` | ソース | 逆アセンブル処理 |
