# 機能設計書 32-riscv64バックエンド

## 概要

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

### 本機能の処理概要

riscv64バックエンドは、ZigコンパイラのAIR（Abstract IR）をRISC-V 64bitアーキテクチャ向けのマシンコードに変換する機能を提供する。RISC-Vは、オープンソースで設計された命令セットアーキテクチャ（ISA）であり、学術研究、組み込みシステム、データセンター向けプロセッサなど幅広い用途で採用が進んでいる。

**業務上の目的・背景**：RISC-Vは特許やライセンス料なしで利用可能なオープンなISAであり、中国・欧州を中心に採用が急速に拡大している。SiFive、Alibaba、Western Digitalなど多くの企業がRISC-Vプロセッサを開発しており、ZigがRISC-Vをネイティブサポートすることで、これらの新興プラットフォーム向けのソフトウェア開発が可能となる。特にLinux on RISC-Vの成熟により、汎用ソフトウェア開発でのニーズが高まっている。

**機能の利用シーン**：
- RISC-V開発ボード（StarFive VisionFive、HiFive Unmatched等）向けアプリケーション開発
- RISC-Vシミュレータ上でのソフトウェアテスト
- 組み込みRISC-Vシステム向けファームウェア開発
- RISC-V Linux環境向けサーバーアプリケーションの開発

**主要な処理内容**：
1. AIR命令のRISC-V命令への変換（命令選択・下降）
2. レジスタ割り当て（x0-x31汎用レジスタ、f0-f31浮動小数点レジスタ）
3. スタックフレームレイアウトとプロローグ/エピローグ生成
4. 命令エンコーディング（R/I/S/B/U/J形式）
5. ベクトル拡張（RVV）サポート（vtype、avl管理）
6. リロケーション情報の生成

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし（コード生成バックエンド） |

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| mir_instructions | MultiArrayList(Mir.Inst) | MIR命令列 |
| frame_locs | MultiArrayList(Mir.FrameLoc) | フレーム位置情報 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 初期化フェーズ
   └─ レジスタマネージャ、スタック管理の初期化
2. 引数処理
   └─ 関数引数のレジスタ/スタック割り当て
3. AIR命令処理
   └─ 各AIR命令をMIR命令に変換
4. Lower（命令下降）
   └─ MIR命令を具体的なRISC-V命令に変換
5. Emit（出力）
   └─ バイナリコード生成とリロケーション
6. デバッグ情報生成
   └─ 行番号・列番号情報の出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: AIR入力] --> B[初期化]
    B --> C[引数処理]
    C --> D[AIR命令変換]
    D --> E{変換成功?}
    E -->|Yes| F[Lower処理]
    E -->|No| G[エラー報告]
    F --> H[Emit処理]
    H --> I[デバッグ情報生成]
    I --> J[MIR出力]
    J --> K[終了: ELFリンカへ]
    G --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-1 | RISC-V呼び出し規約 | RISC-V標準呼び出し規約に準拠 | 関数呼び出し時 |
| BR-32-2 | レジスタ保存規則 | s0-s11（x8-x9, x18-x27）はカリーセーブ | 関数プロローグ/エピローグ |
| BR-32-3 | スタックアライメント | スタックポインタは16バイト境界に整列 | 関数エントリ時 |
| BR-32-4 | ベクトル状態管理 | vtype/avlの明示的な設定が必要 | ベクトル命令使用時 |

### 計算ロジック

- 即値範囲: I形式は12ビット符号付き、U形式は20ビット上位
- 分岐オフセット: B形式は12ビット符号付き（2バイト境界）
- ジャンプオフセット: J形式は20ビット符号付き（2バイト境界）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OutOfRegisters | リソース枯渇 | 使用可能なレジスタ不足 | レジスタスピルを実行 |
| CodeGenError | コード生成失敗 | サポートされていない命令パターン | エラーメッセージを生成 |
| LowerFail | 命令下降失敗 | Lower変換に失敗 | 詳細なエラー情報を報告 |
| EmitFail | 出力失敗 | バイナリ生成に失敗 | 詳細なエラー情報を報告 |
| InvalidInstruction | 不正命令 | 無効な命令エンコーディング | コンパイラバグとして報告 |

### リトライ仕様

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

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

該当なし

## パフォーマンス要件

- 命令選択: O(n)（AIR命令数に比例）
- レジスタ割り当て: 線形時間アルゴリズム使用

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

- スタックオーバーフロー検出のためのガードページサポート
- 将来的なCFI（Control Flow Integrity）拡張への対応準備

## 備考

RISC-V拡張命令セット（M: 乗除算、A: アトミック、F/D: 浮動小数点、V: ベクトル）のサポートはターゲット設定で制御される。

---

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

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

### 推奨読解順序

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

まず、MIR（Machine IR）の構造とRISC-V固有の型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Mir.zig | `src/codegen/riscv64/Mir.zig` | MIR構造体、Inst定義 |
| 1-2 | bits.zig | `src/codegen/riscv64/bits.zig` | Register型、Memory型、VType型 |
| 1-3 | mnem.zig | `src/codegen/riscv64/mnem.zig` | Mnemonic列挙型（RISC-V命令名） |

**読解のコツ**: Mir.zigのInst.Data（13-93行目）は複数の命令形式（r_type、i_type、s_type、b_type、u_type、j_type）を定義している。RISC-Vの命令形式の基本知識があると理解しやすい。

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

コード生成の起点となるCodeGen.zigを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CodeGen.zig | `src/codegen/riscv64/CodeGen.zig` | 主要構造体、MCValue型 |

**主要処理フロー**:
1. **1-50行目**: インポートと基本型定義
2. **54-63行目**: legalizeFeatures関数（safe演算の展開設定）
3. **65-131行目**: 主要フィールド定義（pt、air、liveness、target等）
4. **157-200行目**: MCValue型（レジスタ、即値、メモリ等の値表現）

#### Step 3: 命令下降を理解する

AIR命令を具体的なRISC-V命令に変換するLower.zigを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Lower.zig | `src/codegen/riscv64/Lower.zig` | 命令変換ロジック |

**主要処理フロー**:
- MIR命令から具体的なRISC-V命令への変換
- 呼び出し規約、リンクモード、PICモードの考慮

#### Step 4: 命令出力を理解する

バイナリ出力とリロケーション処理を行うEmit.zigを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Emit.zig | `src/codegen/riscv64/Emit.zig` | バイナリ生成 |

**主要処理フロー**:
- エンコーディングルールの適用
- デバッグ情報の生成

#### Step 5: ABI定義を理解する

呼び出し規約とレジスタ管理を行うabi.zigを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | abi.zig | `src/codegen/riscv64/abi.zig` | RegisterManager、引数渡し規則 |

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

```
codegen.zig (コード生成エントリ)
    │
    ├─ CodeGen.zig
    │      ├─ 初期化・引数処理
    │      ├─ AIR命令変換
    │      └─ MCValue管理
    │
    ├─ Lower.zig
    │      └─ MIR → RISC-V命令変換
    │
    ├─ Emit.zig
    │      └─ バイナリ出力
    │
    ├─ Mir.zig
    │      └─ MIR構造定義
    │
    ├─ bits.zig
    │      ├─ Register
    │      ├─ Memory
    │      └─ VType（ベクトル用）
    │
    ├─ mnem.zig
    │      └─ Mnemonic（命令名）
    │
    ├─ encoding.zig
    │      └─ 命令エンコーディング
    │
    └─ abi.zig
           └─ 呼び出し規約
```

### データフロー図

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

AIR命令列 ───▶ CodeGen処理 ───▶ MIR命令列
                     │
                     ▼
              MCValue生成
                     │
                     ▼
              Lower処理 ───▶ RISC-V命令列
                     │
                     ▼
              Emit処理 ───▶ バイナリコード
                                    │
                                    ▼
                              ELFリンカ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CodeGen.zig | `src/codegen/riscv64/CodeGen.zig` | ソース | メインコード生成ロジック |
| Mir.zig | `src/codegen/riscv64/Mir.zig` | ソース | MIR構造体定義 |
| Lower.zig | `src/codegen/riscv64/Lower.zig` | ソース | 命令下降処理 |
| Emit.zig | `src/codegen/riscv64/Emit.zig` | ソース | バイナリ出力 |
| bits.zig | `src/codegen/riscv64/bits.zig` | ソース | 基本型定義（Register、Memory、VType） |
| mnem.zig | `src/codegen/riscv64/mnem.zig` | ソース | 命令ニーモニック定義 |
| encoding.zig | `src/codegen/riscv64/encoding.zig` | ソース | 命令エンコーディング |
| abi.zig | `src/codegen/riscv64/abi.zig` | ソース | 呼び出し規約とレジスタ管理 |
