寄存器映射
This commit is contained in:
10
.claude/settings.local.json
Normal file
10
.claude/settings.local.json
Normal 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
182
CLAUDE.md
Normal 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`.
|
||||
80
src/ARMeilleure/CodeGen/Loong64/CallingConvention.cs
Normal file
80
src/ARMeilleure/CodeGen/Loong64/CallingConvention.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
src/ARMeilleure/CodeGen/Loong64/Loong64Register.cs
Normal file
73
src/ARMeilleure/CodeGen/Loong64/Loong64Register.cs
Normal 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,
|
||||
}
|
||||
}
|
||||
1610
src/ARMeilleure/CodeGen/Loong64/readme.md
Normal file
1610
src/ARMeilleure/CodeGen/Loong64/readme.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user