寄存器映射

This commit is contained in:
2026-01-10 11:07:27 +08:00
parent e2143d43bc
commit ba99106348
5 changed files with 1955 additions and 0 deletions

View File

@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"Bash(dir:*)",
"Bash(wc:*)",
"Bash(for f in src/ARMeilleure/CodeGen/X86/*.cs)",
"Bash(done)"
]
}
}

182
CLAUDE.md Normal file
View File

@ -0,0 +1,182 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Ryujinx is an open-source Nintendo Switch emulator written in C#. This is a community fork (Ryubing/Ryujinx) focused on Quality of Life improvements for existing users. The emulator provides high-accuracy emulation of the Nintendo Switch's ARMv8 CPU and Maxwell GPU.
## Build Commands
### Building the Project
```bash
dotnet build -c Release -o build
```
### Code Style Enforcement
Run `dotnet format` before committing to ensure code style compliance:
```bash
dotnet format
```
### Running Tests
```bash
# Run all tests
dotnet test
# Run specific test project
dotnet test src/Ryujinx.Tests/Ryujinx.Tests.csproj
dotnet test src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj
dotnet test src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj
```
## Requirements
- .NET 9.0 SDK or higher (version 9.0.100 specified in `global.json`)
- Minimum 8GB RAM for optimal performance
## Architecture Overview
### Three-Layer Architecture
```
┌─────────────────────────────────────┐
│ UI Layer (Avalonia MVVM) │ src/Ryujinx (GUI)
│ Headless Mode (SDL2) │ src/Ryujinx.Headless.SDL2
└────────────────────┬────────────────┘
┌────────────────────┴────────────────┐
│ High-Level Emulation (HLE) │
│ - Ryujinx.HLE │ Horizon OS services emulation
│ - Ryujinx.Horizon │ System services implementation
└────────────────────┬────────────────┘
┌────────────────────┴────────────────┐
│ Core Emulation │
│ - ARMeilleure (CPU) │ ARM instruction translation
│ - Ryujinx.Graphics.Gpu │ Maxwell GPU emulation
│ - Ryujinx.Audio │ Audio engine
└────────────────────┬────────────────┘
┌────────────────────┴────────────────┐
│ Backend Implementations │
│ - OpenGL/Vulkan/Metal (Graphics) │
│ - OpenAL/SDL2/SoundIO (Audio) │
│ - SDL2 (Input) │
└─────────────────────────────────────┘
```
### Key Components
**ARMeilleure (src/ARMeilleure/)**
- CPU emulator that translates ARMv8 instructions to x86/ARM64/Loong64 machine code
- Translation pipeline: ARM decode → Custom IR → Optimizations → Code generation
- Supports Profiled Persistent Translation Cache (PPTC) for faster load times
- Code generation backends in `CodeGen/` for different architectures
**Ryujinx.HLE (src/Ryujinx.HLE/)**
- High-Level Emulation of Nintendo Switch OS (Horizon OS)
- `HOS/Services/` contains system service implementations (am, audio, fs, hid, etc.)
- `HOS/Kernel/` handles thread/process management
- `Loaders/` support ELF, NSO, NRO executable formats
- `Debugger/` provides GDB protocol support
**Graphics Stack**
- `Ryujinx.Graphics.Gpu/` - Main GPU emulation engine (Maxwell architecture)
- `Engine/` subdirectory contains graphics command processors (Compute, DMA, GPFifo, Threed, etc.)
- `Shader/` handles shader compilation and disk caching
- `Ryujinx.Graphics.GAL/` - Graphics Abstraction Layer (backend-agnostic interface)
- Backend implementations: OpenGL, Vulkan, Metal (via MoltenVK on macOS)
- `Ryujinx.Graphics.Shader/` - Shader translation to GLSL/SPIR-V
**Memory Management (src/Ryujinx.Memory/)**
- Three memory manager modes: checked (slowest), untuned, host (default/fastest)
- Balances emulation accuracy vs. performance
**UI (src/Ryujinx/)**
- Built with Avalonia (cross-platform XAML framework)
- MVVM pattern using CommunityToolkit.Mvvm
- UI structure: `UI/Views/`, `UI/ViewModels/`, `UI/Windows/`, `UI/Controls/`
- Locale management with auto-generated code (`Ryujinx.UI.LocaleGenerator`)
### Code Generation
Several components use source generators:
- `Ryujinx.HLE.Generators` - Generates HLE service stubs
- `Ryujinx.Horizon.Generators` - Generates Horizon OS bindings
- `Ryujinx.Horizon.Kernel.Generators` - Generates kernel syscalls
- `Ryujinx.UI.LocaleGenerator` - Generates locale string bindings
- `Spv.Generator` - Generates SPIR-V shader code for Vulkan
## Coding Guidelines
Follow the C# coding style defined in `.editorconfig` and `docs/coding-guidelines/coding-style.md`:
- **Braces**: Allman style (braces on new lines)
- **Indentation**: 4 spaces, no tabs
- **Fields**: `_camelCase` for private instance, `s_` prefix for static, `t_` for thread-static
- **Visibility**: Always specify explicitly (e.g., `private`, `public`)
- **var**: Only use when type is explicitly named on right-hand side
- **Imports**: At top of file, outside namespace declarations
- **Types**: Make internal/private types static or sealed unless derivation needed
- **Magic Numbers**: Define as named constants
Always run `dotnet format` before committing.
## Development Workflow
1. Create a branch off `master` (the main branch, not `main`)
2. Make changes and ensure `dotnet format` is run
3. Build with `dotnet build -c Release` and verify clean build
4. Run relevant tests
5. Submit PR against `master` branch
6. Two team members must review and approve before merge
7. CI runs automatically via GitHub Actions (`.github/workflows/`)
## Important Project Patterns
**Abstraction Layers**: The project uses abstraction layers extensively to support multiple backends:
- Graphics backends (OpenGL/Vulkan/Metal)
- Audio backends (OpenAL/SDL2/SoundIO)
- Input systems (SDL2)
- Memory management modes
**Translation Caching**: ARMeilleure uses a persistent translation cache that significantly improves load times after the third launch of a game.
**Disk Shader Caching**: Compiled shaders are cached to disk to avoid recompilation (`Ryujinx.Graphics.Gpu/Shader/DiskCache/`).
**Platform-Specific Code**: The codebase handles Windows, macOS, and Linux with platform-specific implementations where needed.
## Common File Locations
- **System Files**: User folder (accessible via GUI: File → Open Ryujinx Folder)
- **Logs**: `[Executable Folder]/Logs` - chronologically named
- **Configuration**: `Config.json` in Ryujinx data folder
- **Build Output**: `build/` directory after running build command
## Branches and Releases
- **master**: Main branch for stable releases (released monthly)
- **canary**: Automated builds for every commit on master (may be unstable)
- Current working branch is **Loong64** (architecture support feature branch)
## When Working With Specific Systems
**Adding/Modifying HLE Services**: Follow the service implementation guidelines at https://gist.github.com/gdkchan/84ba88cd50efbe58d1babfaa7cd7c455
**Graphics Work**: Understand the GPU command engine structure in `Ryujinx.Graphics.Gpu/Engine/` - each engine (Compute, DMA, Threed, Twod) handles specific GPU operations.
**CPU Instruction Support**: ARM instruction decoding happens in `ARMeilleure/Decoders/`, implementation in `Instructions/`, and code generation in `CodeGen/`.
**UI Changes**: Follow MVVM pattern - Views in `UI/Views/`, logic in `UI/ViewModels/`. Use FluentAvaloniaUI controls for consistency.
## Third-Party Dependencies
The project uses several key libraries:
- **LibHac**: Nintendo Switch filesystem support
- **Avalonia**: Cross-platform UI framework
- **Silk.NET**: Graphics API bindings
- **SDL2**: Audio/Input/Windowing
- **SharpZipLib**: Archive handling
Contributions using code from other projects must follow permissive licenses and be properly attributed in `distribution/legal/THIRDPARTY.md`.

View File

@ -0,0 +1,80 @@
using System;
namespace ARMeilleure.CodeGen.Loong64
{
static class CallingConvention
{
// 寄存器掩码 (32位整数每位代表一个寄存器)
private const int RegistersMask = unchecked((int)0xffffffff);
private const int ReservedRegsMask = (1 << (int)Loong64Register.zero) | (1 << (int)Loong64Register.ra) | (1 << (int)Loong64Register.tp) | (1 << (int)Loong64Register.sp) | (1 << (int)Loong64Register.r21) | (1 << (int)Loong64Register.fp);
public static int GetIntAvailableRegisters()
{
// 返回可用的通用寄存器掩码
return RegistersMask & ~ReservedRegsMask;
}
public static int GetVecAvailableRegisters()
{
// 返回可用的浮点/向量寄存器掩码
return RegistersMask;
}
public static int GetIntCallerSavedRegisters()
{
// 调用者保存的寄存器 (临时寄存器)
return (GetIntCalleeSavedRegisters() ^ RegistersMask) & ~ReservedRegsMask;
}
public static int GetIntCalleeSavedRegisters()
{
// 被调用者保存的寄存器 (需要保存/恢复)
return unchecked((int)0xff000000);
}
public static int GetArgumentsOnRegsCount()
{
return 8;
}
// 参数寄存器 (Loong64: A0-A7 用于参数)
public static int GetIntArgumentRegister(int index)
{
// index 0-7 → A0-A7 寄存器
if ((uint)index < (uint)GetArgumentsOnRegsCount())
{
return index;
}
throw new ArgumentOutOfRangeException(nameof(index));
}
public static int GetVecArgumentRegister(int index)
{
// index 0-7 → FA0-FA7 寄存器
if ((uint)index < (uint)GetArgumentsOnRegsCount())
{
return index;
}
throw new ArgumentOutOfRangeException(nameof(index));
}
// 返回值寄存器
public static int GetIntReturnRegister()
{
return (int)Loong64Register.a0; // 返回值放在 A0
}
public static int GetIntReturnRegisterHigh()
{
return (int)Loong64Register.a1; // 64位返回值高位
}
public static int GetVecReturnRegister()
{
return 0;
}
}
}

View File

@ -0,0 +1,73 @@
using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.Loong64
{
enum Loong64Register
{
zero = 0,
ra = 1,
tp = 2,
sp = 3,
a0 = 4,
a1 = 5,
a2 = 6,
a3 = 7,
a4 = 8,
a5 = 9,
a6 = 10,
a7 = 11,
t0 = 12,
t1 = 13,
t2 = 14,
t3 = 15,
t4 = 16,
t5 = 17,
t6 = 18,
t7 = 19,
t8 = 20,
r21 = 21,
fp = 22,
s0 = 23,
s1 = 24,
s2 = 25,
s3 = 26,
s4 = 27,
s5 = 28,
s6 = 29,
s7 = 30,
s8 = 31,
fa0 = 0,
fa1 = 1,
fa2 = 2,
fa3 = 3,
fa4 = 4,
fa5 = 5,
fa6 = 6,
fa7 = 7,
ft0 = 8,
ft1 = 9,
ft2 = 10,
ft3 = 11,
ft4 = 12,
ft5 = 13,
ft6 = 14,
ft7 = 15,
ft8 = 16,
ft9 = 17,
ft10 = 18,
ft11 = 19,
ft12 = 20,
ft13 = 21,
ft14 = 22,
ft15 = 23,
fs0 = 24,
fs1 = 25,
fs2 = 26,
fs3 = 27,
fs4 = 28,
fs5 = 29,
fs6 = 30,
fs7 = 31,
}
}

File diff suppressed because it is too large Load Diff