Compare commits
41 commits
2d4129e160
...
aff998973b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aff998973b | ||
|
|
ac7018d5f3 | ||
|
|
96963429a4 | ||
|
|
b378ae91bc | ||
|
|
a5dea4fa65 | ||
|
|
1173472992 | ||
|
|
3f0a741ab1 | ||
|
|
ec5ba51d91 | ||
|
|
a07c276fe1 | ||
|
|
a891db7c3d | ||
|
|
9e400ba36f | ||
|
|
058163c96c | ||
|
|
21aaed63da | ||
|
|
7324245340 | ||
|
|
9dd486ce67 | ||
|
|
0a222cbcd2 | ||
|
|
453d1fda34 | ||
|
|
4de9bdc5fe | ||
|
|
a8b1ad7ea8 | ||
|
|
4519450d48 | ||
|
|
539d06eeb6 | ||
|
|
4169f41b05 | ||
|
|
3652624db8 | ||
|
|
b5b7e2cf81 | ||
|
|
7ed7cdbcd6 | ||
|
|
2c18b40773 | ||
|
|
f289b2b161 | ||
|
|
2f0192665e | ||
|
|
585b3dcde1 | ||
|
|
6a9068ee30 | ||
|
|
876884e783 | ||
|
|
028050cf04 | ||
|
|
1f787ffc39 | ||
|
|
148dc7b480 | ||
|
|
612a203ab2 | ||
|
|
5e927199c5 | ||
|
|
ac99ea96da | ||
|
|
d1b7824443 | ||
|
|
34fa39eae8 | ||
|
|
9ace6742d7 | ||
|
|
79f29abcba |
283
dist/dev.eden_emu.eden.svg
vendored
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
BIN
dist/eden.bmp
vendored
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 256 KiB |
BIN
dist/eden.ico
vendored
|
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 335 KiB |
BIN
dist/qt_themes/default/icons/256x256/eden.png
vendored
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 35 KiB |
|
|
@ -334,7 +334,7 @@ pacman -Syuu --needed --noconfirm $packages
|
||||||
<summary>HaikuOS</summary>
|
<summary>HaikuOS</summary>
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel
|
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel
|
||||||
```
|
```
|
||||||
|
|
||||||
[Caveats](./Caveats.md#haikuos).
|
[Caveats](./Caveats.md#haikuos).
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ This contains documentation created by developers. This contains build instructi
|
||||||
- **[Dynarmic](./dynarmic)**
|
- **[Dynarmic](./dynarmic)**
|
||||||
- **[Cross compilation](./CrossCompile.md)**
|
- **[Cross compilation](./CrossCompile.md)**
|
||||||
- **[Driver Bugs](./DriverBugs.md)**
|
- **[Driver Bugs](./DriverBugs.md)**
|
||||||
|
- **[Building Older Commits](./build/OlderCommits.md)**
|
||||||
|
|
||||||
## Policies
|
## Policies
|
||||||
|
|
||||||
|
|
|
||||||
40
docs/build/OlderCommits.md
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Building Older Commits
|
||||||
|
|
||||||
|
Bisecting and debugging older versions of Eden can be difficult, as many of our submodules have been deleted or removed. However, work has been done to make this process as simple as possible for users.
|
||||||
|
|
||||||
|
## Script
|
||||||
|
|
||||||
|
Copy the following script and store it in `fix.sh`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
git -C externals/discord-rpc checkout 0d8b2d6a37c6e47d62b37caa14708bf747c883bb
|
||||||
|
git add externals/discord-rpc
|
||||||
|
|
||||||
|
git -C externals/dynarmic checkout 05b7ba50588d1004e23ef91f1bda8be234be68f4
|
||||||
|
git add externals/dynarmic
|
||||||
|
|
||||||
|
git -C externals/mbedtls checkout ce4f81f4a926a0e0dcadd0128e016baba416e8ea
|
||||||
|
git add externals/mbedtls
|
||||||
|
|
||||||
|
git -C externals/oboe checkout e4f06f2143eb0173bf4a2bd15aae5e8cc3179405
|
||||||
|
git add externals/oboe
|
||||||
|
|
||||||
|
git -C externals/sirit checkout b870b062998244231a4f08004d3b25151732c5c5
|
||||||
|
git add externals/sirit
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run `chmod +x fix.sh`
|
||||||
|
|
||||||
|
## Submodules
|
||||||
|
|
||||||
|
To check out submodules successfully, use this order of operations:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git submodule update --init --recursive --depth 1 --jobs 8 --progress
|
||||||
|
./fix.sh
|
||||||
|
git submodule update --init --recursive --depth 1 --jobs 8 --progress
|
||||||
|
```
|
||||||
|
|
||||||
|
And you should be good to go! If you check out a different commit that changes submodule commits, run the above command list again.
|
||||||
|
|
@ -56,7 +56,7 @@ Use this when you need to connect to a multiplayer room for LDN functionality in
|
||||||
- Multiplayer Options Configured in Eden Settings
|
- Multiplayer Options Configured in Eden Settings
|
||||||
- Network Access
|
- Network Access
|
||||||
|
|
||||||
## Steps
|
### Steps
|
||||||
There are 2 primary methods that you can use to connect to an existing room, depending on how the room is hosted.
|
There are 2 primary methods that you can use to connect to an existing room, depending on how the room is hosted.
|
||||||
|
|
||||||
- Joining a Public Lobby
|
- Joining a Public Lobby
|
||||||
|
|
@ -70,7 +70,7 @@ There are 2 primary methods that you can use to connect to an existing room, dep
|
||||||
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
### Joining a Public Lobby
|
## Joining a Public Lobby
|
||||||
1. Open Eden and navigate to *Multiplayer → Browse Public Game Lobby*.
|
1. Open Eden and navigate to *Multiplayer → Browse Public Game Lobby*.
|
||||||
2. The **Public Room Browser** will now open and display a list of publicly accessible rooms. Find one you want to connect to and double click it.
|
2. The **Public Room Browser** will now open and display a list of publicly accessible rooms. Find one you want to connect to and double click it.
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ If the hoster has not made the lobby public, or you don't want to find it in the
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Hosting a Multiplayer Room
|
## Hosting a Multiplayer Room
|
||||||
Use this guide for when you want to host a multiplayer lobby to play with others in Eden. In order to have someone access the room from outside your local network, see the *Access Your Multiplayer Room Externally* section for next steps.
|
Use this guide for when you want to host a multiplayer lobby to play with others in Eden. In order to have someone access the room from outside your local network, see the *Access Your Multiplayer Room Externally* section for next steps.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Hosting-a-Multiplayer-Room-2c357c2edaf6819481dbe8a99926cea2) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Hosting-a-Multiplayer-Room-2c357c2edaf6819481dbe8a99926cea2) for a version of this guide with images & visual elements.**
|
||||||
|
|
@ -100,7 +100,7 @@ Use this guide for when you want to host a multiplayer lobby to play with others
|
||||||
- Network Access
|
- Network Access
|
||||||
- Ability to allow programs through the firewall on your device.
|
- Ability to allow programs through the firewall on your device.
|
||||||
|
|
||||||
## Steps
|
### Steps
|
||||||
1. Open Eden and navigate to *Emulation → Multiplayer → Create Room.*
|
1. Open Eden and navigate to *Emulation → Multiplayer → Create Room.*
|
||||||
2. Fill out the following information in the popup dialog box.
|
2. Fill out the following information in the popup dialog box.
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ Use this guide for when you want to host a multiplayer lobby to play with others
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Access Your Multiplayer Room Externally
|
## Access Your Multiplayer Room Externally
|
||||||
Quite often the person with whom you want to play is located off of your internal network (LAN). If you want to host a room and play with them you will need to get your devices to communicate with each other. This guide will go over your options on how to do this so that you can play together.
|
Quite often the person with whom you want to play is located off of your internal network (LAN). If you want to host a room and play with them you will need to get your devices to communicate with each other. This guide will go over your options on how to do this so that you can play together.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Access-Your-Multiplayer-Room-Externally-2c357c2edaf681c0ab2ce2ee624d809d) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Access-Your-Multiplayer-Room-Externally-2c357c2edaf681c0ab2ce2ee624d809d) for a version of this guide with images & visual elements.**
|
||||||
|
|
@ -129,9 +129,9 @@ Quite often the person with whom you want to play is located off of your interna
|
||||||
- Eden set up and Functioning
|
- Eden set up and Functioning
|
||||||
- Network Access
|
- Network Access
|
||||||
|
|
||||||
## Options
|
### Options
|
||||||
|
|
||||||
### Port Forwarding
|
#### Port Forwarding
|
||||||
|
|
||||||
- **Difficulty Level**: High
|
- **Difficulty Level**: High
|
||||||
|
|
||||||
|
|
@ -148,8 +148,9 @@ The process works by creating a static mapping—often called a “port-forward
|
||||||
|
|
||||||
For our purposes we would pick the port we want to expose (*e.g. 24872*) and we would access our router's configuration and create a port-forward rule to send the traffic from an external connection to your local machine over our specified port (*24872)*. The exact way to do so, varies greatly by router manufacturer - and sometimes require contacting your ISP to do so depending on your agreement. You can look up your router on [*portforward.com*](https://portforward.com/router.htm) which may have instructions on how to do so for your specific equipment. If it is not there, you will have to use Google/ChatGPT to determine the steps for your equipment.
|
For our purposes we would pick the port we want to expose (*e.g. 24872*) and we would access our router's configuration and create a port-forward rule to send the traffic from an external connection to your local machine over our specified port (*24872)*. The exact way to do so, varies greatly by router manufacturer - and sometimes require contacting your ISP to do so depending on your agreement. You can look up your router on [*portforward.com*](https://portforward.com/router.htm) which may have instructions on how to do so for your specific equipment. If it is not there, you will have to use Google/ChatGPT to determine the steps for your equipment.
|
||||||
|
|
||||||
|
Remember you can't have one port open for multiple devices at the same time - you must only host from one device (or do more convoluted networking which we will not cover here).
|
||||||
|
|
||||||
### Use a Tunnelling Service
|
#### Use a Tunnelling Service
|
||||||
- **Difficulty Level**: Easy
|
- **Difficulty Level**: Easy
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
|
|
@ -167,7 +168,7 @@ For our purposes we would spawn the listener for the port that way chose when ho
|
||||||
- [*Playit.GG*](https://playit.gg/)
|
- [*Playit.GG*](https://playit.gg/)
|
||||||
|
|
||||||
|
|
||||||
### Use a VPN Service
|
#### Use a VPN Service
|
||||||
|
|
||||||
- **Difficulty**: Easy
|
- **Difficulty**: Easy
|
||||||
|
|
||||||
|
|
@ -189,7 +190,7 @@ The VPN solution is a good compromise between the tunnelling solution and port f
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Finding the Server Information for a Multiplayer Room
|
## Finding the Server Information for a Multiplayer Room
|
||||||
Use this guide when you need to determine the connection information for the Public Multiplayer Lobby you are connected to.
|
Use this guide when you need to determine the connection information for the Public Multiplayer Lobby you are connected to.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Finding-the-Server-Information-for-a-Multiplayer-Room-2c557c2edaf6809e94e8ed3429b9eb26) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Finding-the-Server-Information-for-a-Multiplayer-Room-2c557c2edaf6809e94e8ed3429b9eb26) for a version of this guide with images & visual elements.**
|
||||||
|
|
@ -198,7 +199,7 @@ Use this guide when you need to determine the connection information for the Pub
|
||||||
- Eden set up and configured
|
- Eden set up and configured
|
||||||
- Internet Access
|
- Internet Access
|
||||||
|
|
||||||
## Steps
|
### Steps
|
||||||
|
|
||||||
### Method 1: Grabbing the Address from the Log File
|
### Method 1: Grabbing the Address from the Log File
|
||||||
1. Open Eden and Connect to the room you want to identify.
|
1. Open Eden and Connect to the room you want to identify.
|
||||||
|
|
@ -222,7 +223,7 @@ Use this guide when you need to determine the connection information for the Pub
|
||||||
2. Open the terminal supported by your operating system.
|
2. Open the terminal supported by your operating system.
|
||||||
3. Run one of the following commands, replacing *<Name>* with the name of the server from step 1.
|
3. Run one of the following commands, replacing *<Name>* with the name of the server from step 1.
|
||||||
|
|
||||||
### PowerShell Command [Windows Users]
|
#### PowerShell Command [Windows Users]
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# Calls the API to get the address and port information
|
# Calls the API to get the address and port information
|
||||||
|
|
@ -235,7 +236,7 @@ Use this guide when you need to determine the connection information for the Pub
|
||||||
#}
|
#}
|
||||||
```
|
```
|
||||||
|
|
||||||
### CURL Command [MacOS/Linux Users] **Requires jq*
|
#### CURL Command [MacOS/Linux Users] **Requires jq*
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Calls the API to get the address and port information
|
# Calls the API to get the address and port information
|
||||||
|
|
@ -252,7 +253,7 @@ Use this guide when you need to determine the connection information for the Pub
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Multiplayer for Local Co-Op Games
|
## Multiplayer for Local Co-Op Games
|
||||||
Use this guide when you want to play with a friend on a different system for games that only support local co-op.
|
Use this guide when you want to play with a friend on a different system for games that only support local co-op.
|
||||||
|
|
||||||
**Click [Here](https://evilperson1337.notion.site/Multiplayer-for-Local-Co-Op-Games-2c657c2edaf680c59975ec6b52022a2d) for a version of this guide with images & visual elements.**
|
**Click [Here](https://evilperson1337.notion.site/Multiplayer-for-Local-Co-Op-Games-2c657c2edaf680c59975ec6b52022a2d) for a version of this guide with images & visual elements.**
|
||||||
|
|
@ -271,7 +272,7 @@ In either situation at its core, we are emulating an input device on the host ma
|
||||||
- Parsec is free to use for personal, non-commercial use. For instructions on how to set up an account and install the client you should refer to the Parsec documentation on it's site.
|
- Parsec is free to use for personal, non-commercial use. For instructions on how to set up an account and install the client you should refer to the Parsec documentation on it's site.
|
||||||
- Parsec client installed on your machine and remote (friend's) machine
|
- Parsec client installed on your machine and remote (friend's) machine
|
||||||
|
|
||||||
## Steps
|
### Steps
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
|
|
||||||
|
|
@ -294,3 +295,22 @@ This guide will assume you are the one hosting the game and go over things *Pars
|
||||||
10. Set up the remote player's controller.
|
10. Set up the remote player's controller.
|
||||||
11. Hit **OK** to apply the changes.
|
11. Hit **OK** to apply the changes.
|
||||||
12. Launch the game you want to play and enter the co-op mode. How this works depends on the game, so you will have to look in the menus or online to find out.
|
12. Launch the game you want to play and enter the co-op mode. How this works depends on the game, so you will have to look in the menus or online to find out.
|
||||||
|
|
||||||
|
## Metaserver troubleshooting
|
||||||
|
|
||||||
|
If you can't connect to the metaserver, it's likely your ISP is blocking the requests.
|
||||||
|
|
||||||
|
### Linux and Steamdeck
|
||||||
|
|
||||||
|
Most Linux systems and Steamdeck should allow to modify the base `/etc/hosts` file, this should fix the DNS lookup issue; hence add the following to said file:
|
||||||
|
```
|
||||||
|
28.165.181.135 api.ynet-fun.xyz api.ynet-fun.xyz
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zapret
|
||||||
|
|
||||||
|
In `lists/list-general.txt` add the following:
|
||||||
|
```
|
||||||
|
api.ynet-fun.xyz
|
||||||
|
ynet-fun.xyz
|
||||||
|
```
|
||||||
|
|
|
||||||
9
externals/CMakeLists.txt
vendored
|
|
@ -62,6 +62,12 @@ endif()
|
||||||
# unordered_dense
|
# unordered_dense
|
||||||
AddJsonPackage(unordered-dense)
|
AddJsonPackage(unordered-dense)
|
||||||
|
|
||||||
|
# httplib
|
||||||
|
if (IOS)
|
||||||
|
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
||||||
|
endif()
|
||||||
|
AddJsonPackage(httplib)
|
||||||
|
|
||||||
if (YUZU_STATIC_ROOM)
|
if (YUZU_STATIC_ROOM)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
@ -227,9 +233,6 @@ if (VulkanMemoryAllocator_ADDED)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# httplib
|
|
||||||
AddJsonPackage(httplib)
|
|
||||||
|
|
||||||
# cpp-jwt
|
# cpp-jwt
|
||||||
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
||||||
AddJsonPackage(cpp-jwt)
|
AddJsonPackage(cpp-jwt)
|
||||||
|
|
|
||||||
3
externals/cpmfile.json
vendored
|
|
@ -36,7 +36,8 @@
|
||||||
"0002-fix-zstd.patch"
|
"0002-fix-zstd.patch"
|
||||||
],
|
],
|
||||||
"options": [
|
"options": [
|
||||||
"HTTPLIB_REQUIRE_OPENSSL ON"
|
"HTTPLIB_REQUIRE_OPENSSL ON",
|
||||||
|
"HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES ON"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"cpp-jwt": {
|
"cpp-jwt": {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ if (ENABLE_UNITY_BUILD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Dynarmic
|
# Dynarmic
|
||||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 AND NOT YUZU_STATIC_ROOM)
|
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64) AND NOT YUZU_STATIC_ROOM)
|
||||||
add_subdirectory(dynarmic)
|
add_subdirectory(dynarmic)
|
||||||
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 67 KiB |
|
|
@ -1 +1 @@
|
||||||
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#43fcfcff</color></resources>
|
<?xml version='1.0' encoding='utf-8'?><resources><color name='ic_launcher_background'>#1F143C</color></resources>
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,8 @@ add_library(
|
||||||
zstd_compression.cpp
|
zstd_compression.cpp
|
||||||
zstd_compression.h
|
zstd_compression.h
|
||||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||||
fs/symlink.h fs/symlink.cpp)
|
fs/symlink.h fs/symlink.cpp
|
||||||
|
httplib.h)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(common PRIVATE windows/timer_resolution.cpp
|
target_sources(common PRIVATE windows/timer_resolution.cpp
|
||||||
|
|
@ -244,7 +245,7 @@ else()
|
||||||
target_link_libraries(common PUBLIC Boost::headers)
|
target_link_libraries(common PUBLIC Boost::headers)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(common PUBLIC Boost::filesystem Boost::context)
|
target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib)
|
||||||
|
|
||||||
if (lz4_ADDED)
|
if (lz4_ADDED)
|
||||||
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
||||||
|
|
|
||||||
20
src/common/httplib.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES 1
|
||||||
|
#define CPPHTTPLIB_OPENSSL_SUPPORT 1
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#ifndef __clang__
|
||||||
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#include <httplib.h>
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef INVALID_SOCKET
|
||||||
|
|
@ -287,8 +287,6 @@ struct Values {
|
||||||
true,
|
true,
|
||||||
&use_custom_cpu_ticks};
|
&use_custom_cpu_ticks};
|
||||||
|
|
||||||
SwitchableSetting<bool> vtable_bouncing{linkage, true, "vtable_bouncing", Category::Cpu};
|
|
||||||
|
|
||||||
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
|
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug};
|
Setting<bool> cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer",
|
Setting<bool> cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer",
|
||||||
|
|
|
||||||
|
|
@ -1246,7 +1246,7 @@ if (HAS_NCE)
|
||||||
target_link_libraries(core PRIVATE merry::oaknut)
|
target_link_libraries(core PRIVATE merry::oaknut)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
|
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64)
|
||||||
target_sources(core PRIVATE
|
target_sources(core PRIVATE
|
||||||
arm/dynarmic/arm_dynarmic.h
|
arm/dynarmic/arm_dynarmic.h
|
||||||
arm/dynarmic/arm_dynarmic_64.cpp
|
arm/dynarmic/arm_dynarmic_64.cpp
|
||||||
|
|
@ -1269,7 +1269,6 @@ endif()
|
||||||
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
||||||
|
|
||||||
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
target_compile_definitions(core PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,10 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
|
||||||
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
_mm_lfence();
|
_mm_lfence();
|
||||||
#elif defined(ARCHITECTURE_x86_64)
|
|
||||||
asm volatile("mfence\n\tlfence\n\t" : : : "memory");
|
|
||||||
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
||||||
_Memory_barrier();
|
_Memory_barrier();
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
|
||||||
asm volatile("dsb sy\n\t" : : : "memory");
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture
|
__sync_synchronize();
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
@ -78,14 +74,10 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
|
||||||
[](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
|
[](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
|
||||||
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
#elif defined(ARCHITECTURE_x86_64)
|
|
||||||
asm volatile("mfence\n\t" : : : "memory");
|
|
||||||
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
#elif defined(_MSC_VER) && defined(ARCHITECTURE_arm64)
|
||||||
_Memory_barrier();
|
_Memory_barrier();
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
|
||||||
asm volatile("dmb sy\n\t" : : : "memory");
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported architecture
|
__sync_synchronize();
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
|
@ -103,26 +103,12 @@ void PhysicalCore::RunThread(Kernel::KThread* thread) {
|
||||||
const bool data_abort = True(hr & Core::HaltReason::DataAbort);
|
const bool data_abort = True(hr & Core::HaltReason::DataAbort);
|
||||||
const bool interrupt = True(hr & Core::HaltReason::BreakLoop);
|
const bool interrupt = True(hr & Core::HaltReason::BreakLoop);
|
||||||
|
|
||||||
bool may_abort = true; // Ignore aborting virtual functions (for debugging)
|
|
||||||
if (prefetch_abort && ::Settings::values.vtable_bouncing) {
|
|
||||||
auto& lock = m_kernel.GlobalSchedulerContext().SchedulerLock();
|
|
||||||
lock.Lock();
|
|
||||||
Kernel::Svc::ThreadContext ctx;
|
|
||||||
interface->GetContext(ctx);
|
|
||||||
LOG_WARNING(Core_ARM, "vtable bouncing {:016X}", ctx.lr);
|
|
||||||
ctx.pc = ctx.lr;
|
|
||||||
ctx.r[0] = 0;
|
|
||||||
interface->SetContext(ctx);
|
|
||||||
lock.Unlock();
|
|
||||||
may_abort = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since scheduling may occur here, we cannot use any cached
|
// Since scheduling may occur here, we cannot use any cached
|
||||||
// state after returning from calls we make.
|
// state after returning from calls we make.
|
||||||
|
|
||||||
// Notify the debugger and go to sleep if a breakpoint was hit,
|
// Notify the debugger and go to sleep if a breakpoint was hit,
|
||||||
// or if the thread is unable to continue for any reason.
|
// or if the thread is unable to continue for any reason.
|
||||||
if (breakpoint || (prefetch_abort && may_abort)) {
|
if (breakpoint || prefetch_abort) {
|
||||||
if (breakpoint) {
|
if (breakpoint) {
|
||||||
interface->RewindBreakpointInstruction();
|
interface->RewindBreakpointInstruction();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,7 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#include "common/httplib.h"
|
||||||
#include <httplib.h>
|
|
||||||
#undef INVALID_SOCKET
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
@ -104,8 +101,6 @@ std::vector<u8> TryLoadFromDisk(const std::filesystem::path& path) {
|
||||||
|
|
||||||
std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem::path& cache_path) {
|
std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem::path& cache_path) {
|
||||||
LOG_INFO(Service_BCAT, "Downloading image: https://eden-emu.dev{}", url_path);
|
LOG_INFO(Service_BCAT, "Downloading image: https://eden-emu.dev{}", url_path);
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
||||||
try {
|
try {
|
||||||
httplib::Client cli("https://eden-emu.dev");
|
httplib::Client cli("https://eden-emu.dev");
|
||||||
cli.set_follow_location(true);
|
cli.set_follow_location(true);
|
||||||
|
|
@ -129,8 +124,6 @@ std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_WARNING(Service_BCAT, "Failed to download: {}", url_path);
|
LOG_WARNING(Service_BCAT, "Failed to download: {}", url_path);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,8 +226,6 @@ void WriteCachedJson(std::string_view json) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> DownloadReleasesJson() {
|
std::optional<std::string> DownloadReleasesJson() {
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
||||||
try {
|
try {
|
||||||
httplib::SSLClient cli{"api.github.com", 443};
|
httplib::SSLClient cli{"api.github.com", 443};
|
||||||
cli.set_connection_timeout(10);
|
cli.set_connection_timeout(10);
|
||||||
|
|
@ -256,7 +247,6 @@ std::optional<std::string> DownloadReleasesJson() {
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_WARNING(Service_BCAT, " failed to download releases");
|
LOG_WARNING(Service_BCAT, " failed to download releases");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
||||||
find_package(oaknut 2.0.1 CONFIG)
|
find_package(oaknut 2.0.1 CONFIG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("riscv" IN_LIST ARCHITECTURE)
|
if ("riscv64" IN_LIST ARCHITECTURE)
|
||||||
find_package(biscuit 0.9.1 REQUIRED)
|
find_package(biscuit 0.9.1 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,7 @@ add_library(dynarmic STATIC
|
||||||
backend/block_range_information.h
|
backend/block_range_information.h
|
||||||
backend/exception_handler.h
|
backend/exception_handler.h
|
||||||
common/always_false.h
|
common/always_false.h
|
||||||
common/assert.cpp
|
|
||||||
common/assert.h
|
|
||||||
common/cast_util.h
|
common/cast_util.h
|
||||||
common/common_types.h
|
|
||||||
common/crypto/aes.cpp
|
common/crypto/aes.cpp
|
||||||
common/crypto/aes.h
|
common/crypto/aes.h
|
||||||
common/crypto/crc32.cpp
|
common/crypto/crc32.cpp
|
||||||
|
|
@ -258,7 +255,7 @@ if ("arm64" IN_LIST ARCHITECTURE)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("riscv" IN_LIST ARCHITECTURE)
|
if ("riscv64" IN_LIST ARCHITECTURE)
|
||||||
target_link_libraries(dynarmic PRIVATE biscuit::biscuit)
|
target_link_libraries(dynarmic PRIVATE biscuit::biscuit)
|
||||||
|
|
||||||
target_sources(dynarmic PRIVATE
|
target_sources(dynarmic PRIVATE
|
||||||
|
|
@ -281,6 +278,7 @@ if ("riscv" IN_LIST ARCHITECTURE)
|
||||||
backend/riscv64/emit_riscv64_vector.cpp
|
backend/riscv64/emit_riscv64_vector.cpp
|
||||||
backend/riscv64/emit_riscv64.cpp
|
backend/riscv64/emit_riscv64.cpp
|
||||||
backend/riscv64/emit_riscv64.h
|
backend/riscv64/emit_riscv64.h
|
||||||
|
backend/riscv64/exclusive_monitor.cpp
|
||||||
backend/riscv64/reg_alloc.cpp
|
backend/riscv64/reg_alloc.cpp
|
||||||
backend/riscv64/reg_alloc.h
|
backend/riscv64/reg_alloc.h
|
||||||
backend/riscv64/stack_layout.h
|
backend/riscv64/stack_layout.h
|
||||||
|
|
@ -289,9 +287,12 @@ if ("riscv" IN_LIST ARCHITECTURE)
|
||||||
backend/riscv64/a32_address_space.h
|
backend/riscv64/a32_address_space.h
|
||||||
backend/riscv64/a32_core.h
|
backend/riscv64/a32_core.h
|
||||||
backend/riscv64/a32_interface.cpp
|
backend/riscv64/a32_interface.cpp
|
||||||
|
backend/riscv64/a64_interface.cpp
|
||||||
backend/riscv64/code_block.h
|
backend/riscv64/code_block.h
|
||||||
|
|
||||||
|
common/spin_lock_riscv64.cpp
|
||||||
)
|
)
|
||||||
message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
|
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
@ -359,7 +360,7 @@ set_target_properties(dynarmic PROPERTIES
|
||||||
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
|
|
||||||
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
|
||||||
target_link_libraries(dynarmic PUBLIC fmt::fmt)
|
target_link_libraries(dynarmic PUBLIC fmt::fmt common)
|
||||||
|
|
||||||
if (BOOST_NO_HEADERS)
|
if (BOOST_NO_HEADERS)
|
||||||
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
|
target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||||
|
|
||||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||||
for (size_t i = 0; i < RSBCount; i++) {
|
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +266,7 @@ void A32AddressSpace::EmitPrelude() {
|
||||||
|
|
||||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||||
for (size_t i = 0; i < RSBCount; i++) {
|
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_address_space.h"
|
#include "dynarmic/backend/arm64/a32_address_space.h"
|
||||||
#include "dynarmic/backend/arm64/a32_core.h"
|
#include "dynarmic/backend/arm64/a32_core.h"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||||
|
|
||||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||||
for (size_t i = 0; i < RSBCount; i++) {
|
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -441,7 +441,7 @@ void A64AddressSpace::EmitPrelude() {
|
||||||
|
|
||||||
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
|
||||||
code.LDR(Xscratch0, l_return_to_dispatcher);
|
code.LDR(Xscratch0, l_return_to_dispatcher);
|
||||||
for (size_t i = 0; i < RSBCount; i++) {
|
for (std::size_t i = 0; i < RSBCount; i++) {
|
||||||
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a64_address_space.h"
|
#include "dynarmic/backend/arm64/a64_address_space.h"
|
||||||
#include "dynarmic/backend/arm64/a64_core.h"
|
#include "dynarmic/backend/arm64/a64_core.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,22 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
static constexpr size_t gpr_size = 8;
|
static constexpr std::size_t gpr_size = 8;
|
||||||
static constexpr size_t fpr_size = 16;
|
static constexpr std::size_t fpr_size = 16;
|
||||||
|
|
||||||
struct FrameInfo {
|
struct FrameInfo {
|
||||||
std::vector<int> gprs;
|
std::vector<int> gprs;
|
||||||
std::vector<int> fprs;
|
std::vector<int> fprs;
|
||||||
size_t frame_size;
|
std::size_t frame_size;
|
||||||
size_t gprs_size;
|
std::size_t gprs_size;
|
||||||
size_t fprs_size;
|
std::size_t fprs_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<int> ListToIndexes(u32 list) {
|
static std::vector<int> ListToIndexes(u32 list) {
|
||||||
|
|
@ -39,15 +39,15 @@ static std::vector<int> ListToIndexes(u32 list) {
|
||||||
return indexes;
|
return indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) {
|
static FrameInfo CalculateFrameInfo(RegisterList rl, std::size_t frame_size) {
|
||||||
const auto gprs = ListToIndexes(static_cast<u32>(rl));
|
const auto gprs = ListToIndexes(static_cast<u32>(rl));
|
||||||
const auto fprs = ListToIndexes(static_cast<u32>(rl >> 32));
|
const auto fprs = ListToIndexes(static_cast<u32>(rl >> 32));
|
||||||
|
|
||||||
const size_t num_gprs = gprs.size();
|
const std::size_t num_gprs = gprs.size();
|
||||||
const size_t num_fprs = fprs.size();
|
const std::size_t num_fprs = fprs.size();
|
||||||
|
|
||||||
const size_t gprs_size = (num_gprs + 1) / 2 * 16;
|
const std::size_t gprs_size = (num_gprs + 1) / 2 * 16;
|
||||||
const size_t fprs_size = num_fprs * 16;
|
const std::size_t fprs_size = num_fprs * 16;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
gprs,
|
gprs,
|
||||||
|
|
@ -60,16 +60,16 @@ static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) {
|
||||||
|
|
||||||
#define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \
|
#define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \
|
||||||
if (frame_info.TYPE##s.size() > 0) { \
|
if (frame_info.TYPE##s.size() > 0) { \
|
||||||
for (size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \
|
for (std::size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \
|
||||||
code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \
|
code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \
|
||||||
} \
|
} \
|
||||||
if (frame_info.TYPE##s.size() % 2 == 1) { \
|
if (frame_info.TYPE##s.size() % 2 == 1) { \
|
||||||
const size_t i = frame_info.TYPE##s.size() - 1; \
|
const std::size_t i = frame_info.TYPE##s.size() - 1; \
|
||||||
code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \
|
code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) {
|
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
|
||||||
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
||||||
|
|
||||||
code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
|
code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
|
||||||
|
|
@ -80,7 +80,7 @@ void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t fram
|
||||||
code.SUB(SP, SP, frame_info.frame_size);
|
code.SUB(SP, SP, frame_info.frame_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) {
|
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
|
||||||
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
|
||||||
|
|
||||||
code.ADD(SP, SP, frame_info.frame_size);
|
code.ADD(SP, SP, frame_info.frame_size);
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <stdexcept>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/common/always_false.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
|
|
@ -29,7 +26,7 @@ constexpr oaknut::XReg Xpagetable{24};
|
||||||
constexpr oaknut::XReg Xscratch0{16}, Xscratch1{17}, Xscratch2{30};
|
constexpr oaknut::XReg Xscratch0{16}, Xscratch1{17}, Xscratch2{30};
|
||||||
constexpr oaknut::WReg Wscratch0{16}, Wscratch1{17}, Wscratch2{30};
|
constexpr oaknut::WReg Wscratch0{16}, Wscratch1{17}, Wscratch2{30};
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
constexpr auto Rscratch0() {
|
constexpr auto Rscratch0() {
|
||||||
if constexpr (bitsize == 32) {
|
if constexpr (bitsize == 32) {
|
||||||
return Wscratch0;
|
return Wscratch0;
|
||||||
|
|
@ -40,7 +37,7 @@ constexpr auto Rscratch0() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
constexpr auto Rscratch1() {
|
constexpr auto Rscratch1() {
|
||||||
if constexpr (bitsize == 32) {
|
if constexpr (bitsize == 32) {
|
||||||
return Wscratch1;
|
return Wscratch1;
|
||||||
|
|
@ -70,7 +67,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
|
||||||
constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'7ff80000;
|
constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'7ff80000;
|
||||||
constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff;
|
constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff;
|
||||||
|
|
||||||
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space);
|
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
|
||||||
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space);
|
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
AddressSpace::AddressSpace(size_t code_cache_size)
|
AddressSpace::AddressSpace(std::size_t code_cache_size)
|
||||||
: ir_block{IR::LocationDescriptor{0}}
|
: ir_block{IR::LocationDescriptor{0}}
|
||||||
, code_cache_size(code_cache_size)
|
, code_cache_size(code_cache_size)
|
||||||
, mem(code_cache_size)
|
, mem(code_cache_size)
|
||||||
|
|
@ -102,8 +102,8 @@ void AddressSpace::ClearCache() {
|
||||||
code.set_offset(prelude_info.end_of_prelude);
|
code.set_offset(prelude_info.end_of_prelude);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AddressSpace::GetRemainingSize() {
|
std::size_t AddressSpace::GetRemainingSize() {
|
||||||
return code_cache_size - static_cast<size_t>(code.offset());
|
return code_cache_size - static_cast<std::size_t>(code.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EmittedBlockInfo AddressSpace::Emit(IR::Block block) {
|
EmittedBlockInfo AddressSpace::Emit(IR::Block block) {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <oaknut/code_block.hpp>
|
#include <oaknut/code_block.hpp>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
class AddressSpace {
|
class AddressSpace {
|
||||||
public:
|
public:
|
||||||
explicit AddressSpace(size_t code_cache_size);
|
explicit AddressSpace(std::size_t code_cache_size);
|
||||||
virtual ~AddressSpace();
|
virtual ~AddressSpace();
|
||||||
|
|
||||||
virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0;
|
virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0;
|
||||||
|
|
@ -60,7 +60,7 @@ protected:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetRemainingSize();
|
std::size_t GetRemainingSize();
|
||||||
EmittedBlockInfo Emit(IR::Block ir_block);
|
EmittedBlockInfo Emit(IR::Block ir_block);
|
||||||
void Link(EmittedBlockInfo& block);
|
void Link(EmittedBlockInfo& block);
|
||||||
void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr, const std::vector<BlockRelocation>& block_relocations_list);
|
void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr, const std::vector<BlockRelocation>& block_relocations_list);
|
||||||
|
|
@ -69,7 +69,7 @@ protected:
|
||||||
FakeCall FastmemCallback(u64 host_pc);
|
FakeCall FastmemCallback(u64 host_pc);
|
||||||
|
|
||||||
IR::Block ir_block;
|
IR::Block ir_block;
|
||||||
const size_t code_cache_size;
|
const std::size_t code_cache_size;
|
||||||
oaknut::CodeBlock mem;
|
oaknut::CodeBlock mem;
|
||||||
oaknut::CodeGenerator code;
|
oaknut::CodeGenerator code;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/mcl/function_info.hpp"
|
#include "dynarmic/mcl/function_info.hpp"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ void EmitIR<IR::Opcode::NZCVFromPackedFlags>(oaknut::CodeGenerator&, EmitContext
|
||||||
ctx.reg_alloc.DefineAsExisting(inst, args[0]);
|
ctx.reg_alloc.DefineAsExisting(inst, args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, size_t cycles_to_add) {
|
static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, std::size_t cycles_to_add) {
|
||||||
if (!ctx.conf.enable_cycle_counting) {
|
if (!ctx.conf.enable_cycle_counting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/fastmem.h"
|
#include "dynarmic/backend/arm64/fastmem.h"
|
||||||
|
|
@ -103,7 +103,7 @@ struct BlockRelocation {
|
||||||
|
|
||||||
struct EmittedBlockInfo {
|
struct EmittedBlockInfo {
|
||||||
CodePtr entry_point;
|
CodePtr entry_point;
|
||||||
size_t size;
|
std::size_t size;
|
||||||
std::vector<Relocation> relocations;
|
std::vector<Relocation> relocations;
|
||||||
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
|
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
|
||||||
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
|
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
|
||||||
|
|
@ -127,9 +127,9 @@ struct EmitConfig {
|
||||||
|
|
||||||
// Page table
|
// Page table
|
||||||
u64 page_table_pointer;
|
u64 page_table_pointer;
|
||||||
size_t page_table_address_space_bits;
|
std::size_t page_table_address_space_bits;
|
||||||
int page_table_pointer_mask_bits;
|
int page_table_pointer_mask_bits;
|
||||||
size_t page_table_log2_stride;
|
std::size_t page_table_log2_stride;
|
||||||
bool silently_mirror_page_table;
|
bool silently_mirror_page_table;
|
||||||
bool absolute_offset_page_table;
|
bool absolute_offset_page_table;
|
||||||
u8 detect_misaligned_access_via_page_table;
|
u8 detect_misaligned_access_via_page_table;
|
||||||
|
|
@ -138,7 +138,7 @@ struct EmitConfig {
|
||||||
// Fastmem
|
// Fastmem
|
||||||
std::optional<u64> fastmem_pointer;
|
std::optional<u64> fastmem_pointer;
|
||||||
bool recompile_on_fastmem_failure;
|
bool recompile_on_fastmem_failure;
|
||||||
size_t fastmem_address_space_bits;
|
std::size_t fastmem_address_space_bits;
|
||||||
bool silently_mirror_fastmem;
|
bool silently_mirror_fastmem;
|
||||||
|
|
||||||
// Timing
|
// Timing
|
||||||
|
|
@ -156,9 +156,9 @@ struct EmitConfig {
|
||||||
void (*emit_check_memory_abort)(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, oaknut::Label& end);
|
void (*emit_check_memory_abort)(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, oaknut::Label& end);
|
||||||
|
|
||||||
// State offsets
|
// State offsets
|
||||||
size_t state_nzcv_offset;
|
std::size_t state_nzcv_offset;
|
||||||
size_t state_fpsr_offset;
|
std::size_t state_fpsr_offset;
|
||||||
size_t state_exclusive_state_offset;
|
std::size_t state_exclusive_state_offset;
|
||||||
|
|
||||||
// A32 specific
|
// A32 specific
|
||||||
std::array<std::shared_ptr<A32::Coprocessor>, 16> coprocessors{};
|
std::array<std::shared_ptr<A32::Coprocessor>, 16> coprocessors{};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -45,7 +45,7 @@ static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A3
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -72,7 +72,7 @@ template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||||
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -115,7 +115,7 @@ void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(oaknut::CodeGenerator& code, Emit
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const auto opc = static_cast<unsigned>(coproc_info[2]);
|
const auto opc = static_cast<unsigned>(coproc_info[2]);
|
||||||
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -158,7 +158,7 @@ template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
|
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
const auto opc1 = static_cast<unsigned>(coproc_info[2]);
|
||||||
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -199,7 +199,7 @@ void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitCo
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const unsigned opc = coproc_info[2];
|
const unsigned opc = coproc_info[2];
|
||||||
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -243,7 +243,7 @@ void EmitIR<IR::Opcode::A32CoprocLoadWords>(oaknut::CodeGenerator& code, EmitCon
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const bool long_transfer = coproc_info[2] != 0;
|
const bool long_transfer = coproc_info[2] != 0;
|
||||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
@ -274,7 +274,7 @@ void EmitIR<IR::Opcode::A32CoprocStoreWords>(oaknut::CodeGenerator& code, EmitCo
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
|
||||||
const size_t coproc_num = coproc_info[0];
|
const std::size_t coproc_num = coproc_info[0];
|
||||||
const bool two = coproc_info[1] != 0;
|
const bool two = coproc_info[1] != 0;
|
||||||
const bool long_transfer = coproc_info[2] != 0;
|
const bool long_transfer = coproc_info[2] != 0;
|
||||||
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitCRC(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit_fn) {
|
static void EmitCRC(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit_fn) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/a32_jitstate.h"
|
|
||||||
#include "dynarmic/backend/arm64/abi.h"
|
#include "dynarmic/backend/arm64/abi.h"
|
||||||
#include "dynarmic/backend/arm64/emit_arm64.h"
|
#include "dynarmic/backend/arm64/emit_arm64.h"
|
||||||
#include "dynarmic/backend/arm64/emit_context.h"
|
#include "dynarmic/backend/arm64/emit_context.h"
|
||||||
|
|
@ -24,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
@ -35,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
||||||
emit(Rresult, Roperand);
|
emit(Rresult, Roperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
@ -868,7 +867,7 @@ void EmitIR<IR::Opcode::RotateRightMasked64>(oaknut::CodeGenerator& code, EmitCo
|
||||||
[&](auto& Xresult, auto& Xoperand, auto& Xshift) { code.ROR(Xresult, Xoperand, Xshift); });
|
[&](auto& Xresult, auto& Xoperand, auto& Xshift) { code.ROR(Xresult, Xoperand, Xshift); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
||||||
static_assert(bitsize == 32 || bitsize == 64);
|
static_assert(bitsize == 32 || bitsize == 64);
|
||||||
if constexpr (bitsize == 32) {
|
if constexpr (bitsize == 32) {
|
||||||
|
|
@ -882,7 +881,7 @@ static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, bool sub>
|
template<std::size_t bitsize, bool sub>
|
||||||
static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||||
|
|
@ -1102,7 +1101,7 @@ void EmitIR<IR::Opcode::SignedDiv64>(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
[&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); });
|
[&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
static bool IsValidBitImm(u64 imm) {
|
static bool IsValidBitImm(u64 imm) {
|
||||||
static_assert(bitsize == 32 || bitsize == 64);
|
static_assert(bitsize == 32 || bitsize == 64);
|
||||||
if constexpr (bitsize == 32) {
|
if constexpr (bitsize == 32) {
|
||||||
|
|
@ -1112,7 +1111,7 @@ static bool IsValidBitImm(u64 imm) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
||||||
static_assert(bitsize == 32 || bitsize == 64);
|
static_assert(bitsize == 32 || bitsize == 64);
|
||||||
if constexpr (bitsize == 32) {
|
if constexpr (bitsize == 32) {
|
||||||
|
|
@ -1126,7 +1125,7 @@ static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t>
|
template<std::size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t>
|
||||||
static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn1 emit_without_flags, EmitFn2 emit_with_flags = nullptr) {
|
static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn1 emit_without_flags, EmitFn2 emit_with_flags = nullptr) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Rresult = ctx.reg_alloc.WriteReg<bitsize>(inst);
|
auto Rresult = ctx.reg_alloc.WriteReg<bitsize>(inst);
|
||||||
|
|
@ -1168,7 +1167,7 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
|
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||||
|
|
@ -34,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
||||||
emit(Vresult, Voperand);
|
emit(Vresult, Voperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||||
|
|
@ -46,7 +46,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
||||||
emit(Vresult, Va, Vb);
|
emit(Vresult, Va, Vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize, typename EmitFn>
|
template<std::size_t bitsize, typename EmitFn>
|
||||||
static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
|
||||||
|
|
@ -59,7 +59,7 @@ static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
||||||
emit(Vresult, Va, Vb, Vc);
|
emit(Vresult, Va, Vb, Vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn>
|
template<std::size_t bitsize_from, std::size_t bitsize_to, typename EmitFn>
|
||||||
static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
||||||
|
|
@ -73,12 +73,12 @@ static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
||||||
emit(Vto, Vfrom);
|
emit(Vto, Vfrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize_from, size_t bitsize_to, bool is_signed>
|
template<std::size_t bitsize_from, std::size_t bitsize_to, bool is_signed>
|
||||||
static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Rto = ctx.reg_alloc.WriteReg<std::max<size_t>(bitsize_to, 32)>(inst);
|
auto Rto = ctx.reg_alloc.WriteReg<std::max<std::size_t>(bitsize_to, 32)>(inst);
|
||||||
auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]);
|
auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]);
|
||||||
const size_t fbits = args[1].GetImmediateU8();
|
const std::size_t fbits = args[1].GetImmediateU8();
|
||||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||||
RegAlloc::Realize(Rto, Vfrom);
|
RegAlloc::Realize(Rto, Vfrom);
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -158,12 +158,12 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn>
|
template<std::size_t bitsize_from, std::size_t bitsize_to, typename EmitFn>
|
||||||
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst);
|
||||||
auto Rfrom = ctx.reg_alloc.ReadReg<std::max<size_t>(bitsize_from, 32)>(args[0]);
|
auto Rfrom = ctx.reg_alloc.ReadReg<std::max<std::size_t>(bitsize_from, 32)>(args[0]);
|
||||||
const size_t fbits = args[1].GetImmediateU8();
|
const std::size_t fbits = args[1].GetImmediateU8();
|
||||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||||
RegAlloc::Realize(Vto, Rfrom);
|
RegAlloc::Realize(Vto, Rfrom);
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -212,7 +212,7 @@ void EmitIR<IR::Opcode::FPAdd64>(oaknut::CodeGenerator& code, EmitContext& ctx,
|
||||||
EmitThreeOp<64>(code, ctx, inst, [&](auto& Dresult, auto& Da, auto& Db) { code.FADD(Dresult, Da, Db); });
|
EmitThreeOp<64>(code, ctx, inst, [&](auto& Dresult, auto& Da, auto& Db) { code.FADD(Dresult, Da, Db); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
void EmitCompare(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitCompare(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto flags = ctx.reg_alloc.WriteFlags(inst);
|
auto flags = ctx.reg_alloc.WriteFlags(inst);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
|
|
@ -23,7 +24,6 @@
|
||||||
#include "dynarmic/ir/acc_type.h"
|
#include "dynarmic/ir/acc_type.h"
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
#include "dynarmic/ir/microinstruction.h"
|
#include "dynarmic/ir/microinstruction.h"
|
||||||
#include "dynarmic/ir/opcodes.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace {
|
||||||
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
|
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
LinkTarget ReadMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::ReadMemory8;
|
return LinkTarget::ReadMemory8;
|
||||||
|
|
@ -51,7 +51,7 @@ LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
LinkTarget WriteMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::WriteMemory8;
|
return LinkTarget::WriteMemory8;
|
||||||
|
|
@ -67,7 +67,7 @@ LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
LinkTarget WrappedReadMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::WrappedReadMemory8;
|
return LinkTarget::WrappedReadMemory8;
|
||||||
|
|
@ -83,7 +83,7 @@ LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
LinkTarget WrappedWriteMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::WrappedWriteMemory8;
|
return LinkTarget::WrappedWriteMemory8;
|
||||||
|
|
@ -99,7 +99,7 @@ LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
LinkTarget ExclusiveReadMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::ExclusiveReadMemory8;
|
return LinkTarget::ExclusiveReadMemory8;
|
||||||
|
|
@ -115,7 +115,7 @@ LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
LinkTarget ExclusiveWriteMemoryLinkTarget(std::size_t bitsize) {
|
||||||
switch (bitsize) {
|
switch (bitsize) {
|
||||||
case 8:
|
case 8:
|
||||||
return LinkTarget::ExclusiveWriteMemory8;
|
return LinkTarget::ExclusiveWriteMemory8;
|
||||||
|
|
@ -131,7 +131,7 @@ LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||||
|
|
@ -150,7 +150,7 @@ void CallbackOnlyEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
ctx.reg_alloc.PrepareForCall({}, args[1]);
|
||||||
|
|
@ -171,7 +171,7 @@ void CallbackOnlyEmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||||
|
|
@ -186,7 +186,7 @@ void CallbackOnlyEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
ctx.reg_alloc.PrepareForCall({}, args[1], args[2]);
|
||||||
|
|
@ -209,13 +209,13 @@ void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitConte
|
||||||
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
ctx.reg_alloc.DefineAsRegister(inst, X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t page_table_const_bits = 12;
|
constexpr std::size_t page_table_const_bits = 12;
|
||||||
constexpr size_t page_table_const_size = 1 << page_table_const_bits;
|
constexpr std::size_t page_table_const_size = 1 << page_table_const_bits;
|
||||||
constexpr size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
|
constexpr std::size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
|
||||||
|
|
||||||
// This function may use Xscratch0 as a scratch register
|
// This function may use Xscratch0 as a scratch register
|
||||||
// Trashes NZCV
|
// Trashes NZCV
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||||
static_assert(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64 || bitsize == 128);
|
static_assert(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64 || bitsize == 128);
|
||||||
|
|
||||||
|
|
@ -253,10 +253,10 @@ void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oa
|
||||||
// May use Xscratch1 as scratch register
|
// May use Xscratch1 as scratch register
|
||||||
// Address to read/write = [ret0 + ret1], ret0 is always Xscratch0 and ret1 is either Xaddr or Xscratch1
|
// Address to read/write = [ret0 + ret1], ret0 is always Xscratch0 and ret1 is either Xaddr or Xscratch1
|
||||||
// Trashes NZCV
|
// Trashes NZCV
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||||
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
|
const std::size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
|
||||||
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
const std::size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
|
||||||
|
|
||||||
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);
|
||||||
|
|
||||||
|
|
@ -408,7 +408,7 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
|
||||||
return fastmem_location;
|
return fastmem_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||||
|
|
@ -448,7 +448,7 @@ void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx
|
||||||
code.l(*end);
|
code.l(*end);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void InlinePageTableEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void InlinePageTableEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||||
|
|
@ -511,7 +511,7 @@ inline bool ShouldExt32(EmitContext& ctx) {
|
||||||
// May use Xscratch0 as scratch register
|
// May use Xscratch0 as scratch register
|
||||||
// Address to read/write = [ret0 + ret1], ret0 is always Xfastmem and ret1 is either Xaddr or Xscratch0
|
// Address to read/write = [ret0 + ret1], ret0 is always Xfastmem and ret1 is either Xaddr or Xscratch0
|
||||||
// Trashes NZCV
|
// Trashes NZCV
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
std::pair<oaknut::XReg, oaknut::XReg> FastmemEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
std::pair<oaknut::XReg, oaknut::XReg> FastmemEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
|
||||||
if (ctx.conf.fastmem_address_space_bits == 64 || ShouldExt32(ctx)) {
|
if (ctx.conf.fastmem_address_space_bits == 64 || ShouldExt32(ctx)) {
|
||||||
return std::make_pair(Xfastmem, Xaddr);
|
return std::make_pair(Xfastmem, Xaddr);
|
||||||
|
|
@ -527,7 +527,7 @@ std::pair<oaknut::XReg, oaknut::XReg> FastmemEmitVAddrLookup(oaknut::CodeGenerat
|
||||||
return std::make_pair(Xfastmem, Xaddr);
|
return std::make_pair(Xfastmem, Xaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||||
|
|
@ -577,7 +577,7 @@ void FastmemEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::In
|
||||||
code.l(*end);
|
code.l(*end);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, DoNotFastmemMarker marker) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
auto Xaddr = ctx.reg_alloc.ReadX(args[1]);
|
||||||
|
|
@ -633,7 +633,7 @@ void FastmemEmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::I
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||||
FastmemEmitReadMemory<bitsize>(code, ctx, inst, *marker);
|
FastmemEmitReadMemory<bitsize>(code, ctx, inst, *marker);
|
||||||
|
|
@ -644,12 +644,12 @@ void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
CallbackOnlyEmitExclusiveReadMemory<bitsize>(code, ctx, inst);
|
CallbackOnlyEmitExclusiveReadMemory<bitsize>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||||
FastmemEmitWriteMemory<bitsize>(code, ctx, inst, *marker);
|
FastmemEmitWriteMemory<bitsize>(code, ctx, inst, *marker);
|
||||||
|
|
@ -660,7 +660,7 @@ void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
CallbackOnlyEmitExclusiveWriteMemory<bitsize>(code, ctx, inst);
|
CallbackOnlyEmitExclusiveWriteMemory<bitsize>(code, ctx, inst);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include <cstddef>
|
||||||
|
|
||||||
namespace oaknut {
|
namespace oaknut {
|
||||||
struct CodeGenerator;
|
struct CodeGenerator;
|
||||||
|
|
@ -23,13 +23,13 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
struct EmitContext;
|
struct EmitContext;
|
||||||
enum class LinkTarget;
|
enum class LinkTarget;
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
void EmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
void EmitExclusiveReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
void EmitWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
template<size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
void EmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst);
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -66,7 +66,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const size_t N = args[1].GetImmediateU8();
|
const std::size_t N = args[1].GetImmediateU8();
|
||||||
ASSERT(N >= 1 && N <= 32);
|
ASSERT(N >= 1 && N <= 32);
|
||||||
|
|
||||||
if (N == 32) {
|
if (N == 32) {
|
||||||
|
|
@ -112,7 +112,7 @@ void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitCon
|
||||||
RegAlloc::Realize(Wresult, Woperand);
|
RegAlloc::Realize(Wresult, Woperand);
|
||||||
ctx.reg_alloc.SpillFlags();
|
ctx.reg_alloc.SpillFlags();
|
||||||
|
|
||||||
const size_t N = args[1].GetImmediateU8();
|
const std::size_t N = args[1].GetImmediateU8();
|
||||||
ASSERT(N <= 31);
|
ASSERT(N <= 31);
|
||||||
const u32 saturated_value = (1u << N) - 1;
|
const u32 saturated_value = (1u << N) - 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
||||||
emit(Qresult, Qoperand);
|
emit(Qresult, Qoperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -50,7 +50,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
EmitTwoOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -58,7 +58,7 @@ static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext&
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -73,7 +73,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||||
if constexpr (size == 16) {
|
if constexpr (size == 16) {
|
||||||
|
|
@ -88,7 +88,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOpArrangedNarrow<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
EmitTwoOpArrangedNarrow<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -96,7 +96,7 @@ static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitCo
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -111,7 +111,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext&
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -137,7 +137,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
|
||||||
emit(Qresult, Qa, Qb);
|
emit(Qresult, Qa, Qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -154,7 +154,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
EmitThreeOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -162,7 +162,7 @@ static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContex
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -179,7 +179,7 @@ static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOpArrangedWiden<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
EmitThreeOpArrangedWiden<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -187,7 +187,7 @@ static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitC
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||||
if constexpr (size == 8) {
|
if constexpr (size == 8) {
|
||||||
|
|
@ -202,7 +202,7 @@ static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qaccumulator = ctx.reg_alloc.ReadWriteQ(args[1], inst); // NB: Swapped
|
auto Qaccumulator = ctx.reg_alloc.ReadWriteQ(args[1], inst); // NB: Swapped
|
||||||
|
|
@ -223,7 +223,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
||||||
|
|
@ -244,7 +244,7 @@ static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitImmShift<size>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
|
EmitImmShift<size>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
|
||||||
ctx.fpsr.Load();
|
ctx.fpsr.Load();
|
||||||
|
|
@ -252,7 +252,7 @@ static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteVec<size>(inst);
|
auto Vresult = ctx.reg_alloc.WriteVec<size>(inst);
|
||||||
|
|
@ -272,13 +272,13 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitGetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitGetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ASSERT(args[1].IsImmediate());
|
ASSERT(args[1].IsImmediate());
|
||||||
const u8 index = args[1].GetImmediateU8();
|
const u8 index = args[1].GetImmediateU8();
|
||||||
|
|
||||||
auto Rresult = ctx.reg_alloc.WriteReg<std::max<size_t>(32, size)>(inst);
|
auto Rresult = ctx.reg_alloc.WriteReg<std::max<std::size_t>(32, size)>(inst);
|
||||||
auto Qvalue = ctx.reg_alloc.ReadQ(args[0]);
|
auto Qvalue = ctx.reg_alloc.ReadQ(args[0]);
|
||||||
RegAlloc::Realize(Rresult, Qvalue);
|
RegAlloc::Realize(Rresult, Qvalue);
|
||||||
|
|
||||||
|
|
@ -307,14 +307,14 @@ void EmitIR<IR::Opcode::VectorGetElement64>(oaknut::CodeGenerator& code, EmitCon
|
||||||
EmitGetElement<64>(code, ctx, inst, [&](auto& Xresult, auto& Qvalue, u8 index) { code.UMOV(Xresult, Qvalue->Delem()[index]); });
|
EmitGetElement<64>(code, ctx, inst, [&](auto& Xresult, auto& Qvalue, u8 index) { code.UMOV(Xresult, Qvalue->Delem()[index]); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitSetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitSetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ASSERT(args[1].IsImmediate());
|
ASSERT(args[1].IsImmediate());
|
||||||
const u8 index = args[1].GetImmediateU8();
|
const u8 index = args[1].GetImmediateU8();
|
||||||
|
|
||||||
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[2]);
|
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[2]);
|
||||||
RegAlloc::Realize(Qvector, Rvalue);
|
RegAlloc::Realize(Qvector, Rvalue);
|
||||||
|
|
||||||
// TODO: fpr source
|
// TODO: fpr source
|
||||||
|
|
@ -432,11 +432,11 @@ void EmitIR<IR::Opcode::VectorArithmeticVShift64>(oaknut::CodeGenerator& code, E
|
||||||
EmitThreeOpArranged<64>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { code.SSHL(Vresult, Va, Vb); });
|
EmitThreeOpArranged<64>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { code.SSHL(Vresult, Va, Vb); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitBroadcast(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitBroadcast(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
||||||
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[0]);
|
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[0]);
|
||||||
RegAlloc::Realize(Qvector, Rvalue);
|
RegAlloc::Realize(Qvector, Rvalue);
|
||||||
|
|
||||||
// TODO: fpr source
|
// TODO: fpr source
|
||||||
|
|
@ -479,7 +479,7 @@ void EmitIR<IR::Opcode::VectorBroadcast64>(oaknut::CodeGenerator& code, EmitCont
|
||||||
EmitBroadcast<64>(code, ctx, inst, [&](auto& Qvector, auto& Xvalue) { code.DUP(Qvector->D2(), Xvalue); });
|
EmitBroadcast<64>(code, ctx, inst, [&](auto& Qvector, auto& Xvalue) { code.DUP(Qvector->D2(), Xvalue); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitBroadcastElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitBroadcastElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
auto Qvector = ctx.reg_alloc.WriteQ(inst);
|
||||||
|
|
@ -1612,17 +1612,17 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||||
|
|
||||||
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||||
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
||||||
|
|
||||||
auto Dresult = is_defaults_zero ? ctx.reg_alloc.WriteD(inst) : ctx.reg_alloc.ReadWriteD(args[0], inst);
|
auto Dresult = is_defaults_zero ? ctx.reg_alloc.WriteD(inst) : ctx.reg_alloc.ReadWriteD(args[0], inst);
|
||||||
auto Dindices = ctx.reg_alloc.ReadD(args[2]);
|
auto Dindices = ctx.reg_alloc.ReadD(args[2]);
|
||||||
std::vector<RAReg<oaknut::DReg>> Dtable;
|
std::vector<RAReg<oaknut::DReg>> Dtable;
|
||||||
for (size_t i = 0; i < table_size; i++) {
|
for (std::size_t i = 0; i < table_size; i++) {
|
||||||
Dtable.emplace_back(ctx.reg_alloc.ReadD(table[i]));
|
Dtable.emplace_back(ctx.reg_alloc.ReadD(table[i]));
|
||||||
}
|
}
|
||||||
RegAlloc::Realize(Dresult, Dindices);
|
RegAlloc::Realize(Dresult, Dindices);
|
||||||
for (size_t i = 0; i < table_size; i++) {
|
for (std::size_t i = 0; i < table_size; i++) {
|
||||||
RegAlloc::Realize(Dtable[i]);
|
RegAlloc::Realize(Dtable[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1679,17 +1679,17 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
|
||||||
|
|
||||||
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
|
||||||
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
const bool is_defaults_zero = inst->GetArg(0).IsZero();
|
||||||
|
|
||||||
auto Qresult = is_defaults_zero ? ctx.reg_alloc.WriteQ(inst) : ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
auto Qresult = is_defaults_zero ? ctx.reg_alloc.WriteQ(inst) : ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||||
auto Qindices = ctx.reg_alloc.ReadQ(args[2]);
|
auto Qindices = ctx.reg_alloc.ReadQ(args[2]);
|
||||||
std::vector<RAReg<oaknut::QReg>> Qtable;
|
std::vector<RAReg<oaknut::QReg>> Qtable;
|
||||||
for (size_t i = 0; i < table_size; i++) {
|
for (std::size_t i = 0; i < table_size; i++) {
|
||||||
Qtable.emplace_back(ctx.reg_alloc.ReadQ(table[i]));
|
Qtable.emplace_back(ctx.reg_alloc.ReadQ(table[i]));
|
||||||
}
|
}
|
||||||
RegAlloc::Realize(Qresult, Qindices);
|
RegAlloc::Realize(Qresult, Qindices);
|
||||||
for (size_t i = 0; i < table_size; i++) {
|
for (std::size_t i = 0; i < table_size; i++) {
|
||||||
RegAlloc::Realize(Qtable[i]);
|
RegAlloc::Realize(Qtable[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
using A64FullVectorWidth = std::integral_constant<size_t, 128>;
|
using A64FullVectorWidth = std::integral_constant<std::size_t, 128>;
|
||||||
|
|
||||||
// Array alias that always sizes itself according to the given type T
|
// Array alias that always sizes itself according to the given type T
|
||||||
// relative to the size of a vector register. e.g. T = u32 would result
|
// relative to the size of a vector register. e.g. T = u32 would result
|
||||||
|
|
@ -65,7 +65,7 @@ static void EmitTwoOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
||||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa); });
|
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qa) {
|
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qa) {
|
||||||
if constexpr (size == 16) {
|
if constexpr (size == 16) {
|
||||||
|
|
@ -93,7 +93,7 @@ static void EmitThreeOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
|
||||||
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa, Qb); });
|
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa, Qb); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
|
||||||
if constexpr (size == 16) {
|
if constexpr (size == 16) {
|
||||||
|
|
@ -108,7 +108,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qresult = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
auto Qresult = ctx.reg_alloc.ReadWriteQ(args[0], inst);
|
||||||
|
|
@ -131,7 +131,7 @@ static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
||||||
|
|
@ -153,12 +153,12 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t fsize, bool is_signed>
|
template<std::size_t fsize, bool is_signed>
|
||||||
void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
auto Qto = ctx.reg_alloc.WriteQ(inst);
|
||||||
auto Qfrom = ctx.reg_alloc.ReadQ(args[0]);
|
auto Qfrom = ctx.reg_alloc.ReadQ(args[0]);
|
||||||
const size_t fbits = args[1].GetImmediateU8();
|
const std::size_t fbits = args[1].GetImmediateU8();
|
||||||
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
|
||||||
const bool fpcr_controlled = inst->GetArg(3).GetU1();
|
const bool fpcr_controlled = inst->GetArg(3).GetU1();
|
||||||
RegAlloc::Realize(Qto, Qfrom);
|
RegAlloc::Realize(Qto, Qfrom);
|
||||||
|
|
@ -272,7 +272,7 @@ static void EmitTwoOpFallbackWithoutRegAlloc(oaknut::CodeGenerator& code, EmitCo
|
||||||
ABI_PopRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size);
|
ABI_PopRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t fpcr_controlled_arg_index = 1, typename Lambda>
|
template<std::size_t fpcr_controlled_arg_index = 1, typename Lambda>
|
||||||
static void EmitTwoOpFallback(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
static void EmitTwoOpFallback(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qarg1 = ctx.reg_alloc.ReadQ(args[0]);
|
auto Qarg1 = ctx.reg_alloc.ReadQ(args[0]);
|
||||||
|
|
@ -562,7 +562,7 @@ void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(oaknut::CodeGenerator& code, E
|
||||||
/// TODO: we have space for a 5th parameter? :)
|
/// TODO: we have space for a 5th parameter? :)
|
||||||
template<typename FPT, FP::RoundingMode rounding_mode, bool exact>
|
template<typename FPT, FP::RoundingMode rounding_mode, bool exact>
|
||||||
static void EmitIRVectorRoundInt16Thunk(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
static void EmitIRVectorRoundInt16Thunk(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
|
||||||
for (size_t i = 0; i < output.size(); ++i)
|
for (std::size_t i = 0; i < output.size(); ++i)
|
||||||
output[i] = FPT(FP::FPRoundInt<FPT>(input[i], fpcr, rounding_mode, exact, fpsr));
|
output[i] = FPT(FP::FPRoundInt<FPT>(input[i], fpcr, rounding_mode, exact, fpsr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
template<size_t size, typename EmitFn>
|
template<std::size_t size, typename EmitFn>
|
||||||
static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
auto Qresult = ctx.reg_alloc.WriteQ(inst);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ void ExclusiveMonitor::Unlock() {
|
||||||
lock.Unlock();
|
lock.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) {
|
bool ExclusiveMonitor::CheckAndClear(std::size_t processor_id, VAddr address) {
|
||||||
const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
|
const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
|
||||||
|
|
||||||
Lock();
|
Lock();
|
||||||
|
|
@ -52,7 +52,7 @@ void ExclusiveMonitor::Clear() {
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExclusiveMonitor::ClearProcessor(size_t processor_id) {
|
void ExclusiveMonitor::ClearProcessor(std::size_t processor_id) {
|
||||||
Lock();
|
Lock();
|
||||||
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
|
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/backend/exception_handler.h"
|
#include "dynarmic/backend/exception_handler.h"
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||||
|
|
||||||
constexpr size_t xmrx(size_t x) noexcept {
|
constexpr std::size_t xmrx(std::size_t x) noexcept {
|
||||||
x ^= x >> 32;
|
x ^= x >> 32;
|
||||||
x *= 0xff51afd7ed558ccd;
|
x *= 0xff51afd7ed558ccd;
|
||||||
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
||||||
|
|
@ -29,7 +29,7 @@ constexpr size_t xmrx(size_t x) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DoNotFastmemMarkerHash {
|
struct DoNotFastmemMarkerHash {
|
||||||
[[nodiscard]] size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
[[nodiscard]] std::size_t operator()(const DoNotFastmemMarker& value) const noexcept {
|
||||||
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
|
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2022 MerryMage
|
* Copyright (c) 2022 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -13,7 +16,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset)
|
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, std::size_t state_fpsr_offset)
|
||||||
: code{code}, state_fpsr_offset{state_fpsr_offset} {}
|
: code{code}, state_fpsr_offset{state_fpsr_offset} {}
|
||||||
|
|
||||||
void FpsrManager::Spill() {
|
void FpsrManager::Spill() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include <cstddef>
|
||||||
|
|
||||||
namespace oaknut {
|
namespace oaknut {
|
||||||
struct CodeGenerator;
|
struct CodeGenerator;
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
class FpsrManager {
|
class FpsrManager {
|
||||||
public:
|
public:
|
||||||
explicit FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset);
|
explicit FpsrManager(oaknut::CodeGenerator& code, std::size_t state_fpsr_offset);
|
||||||
|
|
||||||
void Spill();
|
void Spill();
|
||||||
void Load();
|
void Load();
|
||||||
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
oaknut::CodeGenerator& code;
|
oaknut::CodeGenerator& code;
|
||||||
size_t state_fpsr_offset;
|
std::size_t state_fpsr_offset;
|
||||||
bool fpsr_loaded = false;
|
bool fpsr_loaded = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/abi.h"
|
#include "dynarmic/backend/arm64/abi.h"
|
||||||
#include "dynarmic/backend/arm64/emit_context.h"
|
#include "dynarmic/backend/arm64/emit_context.h"
|
||||||
|
|
@ -27,8 +27,8 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
constexpr size_t spill_offset = offsetof(StackLayout, spill);
|
constexpr std::size_t spill_offset = offsetof(StackLayout, spill);
|
||||||
constexpr size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type);
|
constexpr std::size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type);
|
||||||
|
|
||||||
static bool IsValuelessType(IR::Type type) {
|
static bool IsValuelessType(IR::Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -131,7 +131,7 @@ void HostLocInfo::UpdateUses() {
|
||||||
|
|
||||||
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
|
||||||
ArgumentInfo ret = {Argument{}, Argument{}, Argument{}, Argument{}};
|
ArgumentInfo ret = {Argument{}, Argument{}, Argument{}, Argument{}};
|
||||||
for (size_t i = 0; i < inst->NumArgs(); i++) {
|
for (std::size_t i = 0; i < inst->NumArgs(); i++) {
|
||||||
const IR::Value arg = inst->GetArg(i);
|
const IR::Value arg = inst->GetArg(i);
|
||||||
ret[i].value = arg;
|
ret[i].value = arg;
|
||||||
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
|
||||||
|
|
@ -245,7 +245,7 @@ void RegAlloc::AssertNoMoreUses() const {
|
||||||
void RegAlloc::EmitVerboseDebuggingOutput() {
|
void RegAlloc::EmitVerboseDebuggingOutput() {
|
||||||
code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
|
code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
|
||||||
|
|
||||||
const auto do_location = [&](HostLocInfo& info, HostLocType type, size_t index) {
|
const auto do_location = [&](HostLocInfo& info, HostLocType type, std::size_t index) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
for (const IR::Inst* value : info.values) {
|
for (const IR::Inst* value : info.values) {
|
||||||
code.MOV(X0, SP);
|
code.MOV(X0, SP);
|
||||||
|
|
@ -257,14 +257,14 @@ void RegAlloc::EmitVerboseDebuggingOutput() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < gprs.size(); i++) {
|
for (std::size_t i = 0; i < gprs.size(); i++) {
|
||||||
do_location(gprs[i], HostLocType::X, i);
|
do_location(gprs[i], HostLocType::X, i);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < fprs.size(); i++) {
|
for (std::size_t i = 0; i < fprs.size(); i++) {
|
||||||
do_location(fprs[i], HostLocType::Q, i);
|
do_location(fprs[i], HostLocType::Q, i);
|
||||||
}
|
}
|
||||||
do_location(flags, HostLocType::Nzcv, 0);
|
do_location(flags, HostLocType::Nzcv, 0);
|
||||||
for (size_t i = 0; i < spills.size(); i++) {
|
for (std::size_t i = 0; i < spills.size(); i++) {
|
||||||
do_location(spills[i], HostLocType::Spill, i);
|
do_location(spills[i], HostLocType::Spill, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -576,13 +576,13 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
|
||||||
HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
|
HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
|
||||||
switch (host_loc.kind) {
|
switch (host_loc.kind) {
|
||||||
case HostLoc::Kind::Gpr:
|
case HostLoc::Kind::Gpr:
|
||||||
return gprs[static_cast<size_t>(host_loc.index)];
|
return gprs[static_cast<std::size_t>(host_loc.index)];
|
||||||
case HostLoc::Kind::Fpr:
|
case HostLoc::Kind::Fpr:
|
||||||
return fprs[static_cast<size_t>(host_loc.index)];
|
return fprs[static_cast<std::size_t>(host_loc.index)];
|
||||||
case HostLoc::Kind::Flags:
|
case HostLoc::Kind::Flags:
|
||||||
return flags;
|
return flags;
|
||||||
case HostLoc::Kind::Spill:
|
case HostLoc::Kind::Spill:
|
||||||
return spills[static_cast<size_t>(host_loc.index)];
|
return spills[static_cast<std::size_t>(host_loc.index)];
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||||
#include <oaknut/oaknut.hpp>
|
#include <oaknut/oaknut.hpp>
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
@ -141,11 +141,11 @@ private:
|
||||||
|
|
||||||
struct HostLocInfo final {
|
struct HostLocInfo final {
|
||||||
std::vector<const IR::Inst*> values;
|
std::vector<const IR::Inst*> values;
|
||||||
size_t locked = 0;
|
std::size_t locked = 0;
|
||||||
bool realized = false;
|
bool realized = false;
|
||||||
size_t uses_this_inst = 0;
|
std::size_t uses_this_inst = 0;
|
||||||
size_t accumulated_uses = 0;
|
std::size_t accumulated_uses = 0;
|
||||||
size_t expected_uses = 0;
|
std::size_t expected_uses = 0;
|
||||||
|
|
||||||
bool Contains(const IR::Inst*) const;
|
bool Contains(const IR::Inst*) const;
|
||||||
void SetupScratchLocation();
|
void SetupScratchLocation();
|
||||||
|
|
@ -179,7 +179,7 @@ public:
|
||||||
auto ReadH(Argument& arg) { return RAReg<oaknut::HReg>{*this, RWType::Read, arg.value, nullptr}; }
|
auto ReadH(Argument& arg) { return RAReg<oaknut::HReg>{*this, RWType::Read, arg.value, nullptr}; }
|
||||||
auto ReadB(Argument& arg) { return RAReg<oaknut::BReg>{*this, RWType::Read, arg.value, nullptr}; }
|
auto ReadB(Argument& arg) { return RAReg<oaknut::BReg>{*this, RWType::Read, arg.value, nullptr}; }
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto ReadReg(Argument& arg) {
|
auto ReadReg(Argument& arg) {
|
||||||
if constexpr (size == 64) {
|
if constexpr (size == 64) {
|
||||||
return ReadX(arg);
|
return ReadX(arg);
|
||||||
|
|
@ -190,7 +190,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto ReadVec(Argument& arg) {
|
auto ReadVec(Argument& arg) {
|
||||||
if constexpr (size == 128) {
|
if constexpr (size == 128) {
|
||||||
return ReadQ(arg);
|
return ReadQ(arg);
|
||||||
|
|
@ -218,7 +218,7 @@ public:
|
||||||
|
|
||||||
auto WriteFlags(IR::Inst* inst) { return RAReg<FlagsTag>{*this, RWType::Write, {}, inst}; }
|
auto WriteFlags(IR::Inst* inst) { return RAReg<FlagsTag>{*this, RWType::Write, {}, inst}; }
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto WriteReg(IR::Inst* inst) {
|
auto WriteReg(IR::Inst* inst) {
|
||||||
if constexpr (size == 64) {
|
if constexpr (size == 64) {
|
||||||
return WriteX(inst);
|
return WriteX(inst);
|
||||||
|
|
@ -229,7 +229,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto WriteVec(IR::Inst* inst) {
|
auto WriteVec(IR::Inst* inst) {
|
||||||
if constexpr (size == 128) {
|
if constexpr (size == 128) {
|
||||||
return WriteQ(inst);
|
return WriteQ(inst);
|
||||||
|
|
@ -255,7 +255,7 @@ public:
|
||||||
auto ReadWriteH(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::HReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
auto ReadWriteH(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::HReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
||||||
auto ReadWriteB(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::BReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
auto ReadWriteB(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::BReg>{*this, RWType::ReadWrite, arg.value, inst}; }
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto ReadWriteReg(Argument& arg, const IR::Inst* inst) {
|
auto ReadWriteReg(Argument& arg, const IR::Inst* inst) {
|
||||||
if constexpr (size == 64) {
|
if constexpr (size == 64) {
|
||||||
return ReadWriteX(arg, inst);
|
return ReadWriteX(arg, inst);
|
||||||
|
|
@ -266,7 +266,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t size>
|
template<std::size_t size>
|
||||||
auto ReadWriteVec(Argument& arg, const IR::Inst* inst) {
|
auto ReadWriteVec(Argument& arg, const IR::Inst* inst) {
|
||||||
if constexpr (size == 128) {
|
if constexpr (size == 128) {
|
||||||
return ReadWriteQ(arg, inst);
|
return ReadWriteQ(arg, inst);
|
||||||
|
|
@ -335,7 +335,7 @@ private:
|
||||||
HostLocInfo flags;
|
HostLocInfo flags;
|
||||||
std::array<HostLocInfo, SpillCount> spills;
|
std::array<HostLocInfo, SpillCount> spills;
|
||||||
|
|
||||||
mutable size_t alloc_candidate_index = 0;
|
mutable std::size_t alloc_candidate_index = 0;
|
||||||
ankerl::unordered_dense::set<const IR::Inst*> defined_insts;
|
ankerl::unordered_dense::set<const IR::Inst*> defined_insts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
|
|
@ -19,14 +19,14 @@ namespace Dynarmic::Backend::Arm64 {
|
||||||
# pragma warning(disable : 4324) // Structure was padded due to alignment specifier
|
# pragma warning(disable : 4324) // Structure was padded due to alignment specifier
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr size_t SpillCount = 64;
|
constexpr std::size_t SpillCount = 64;
|
||||||
|
|
||||||
struct alignas(16) RSBEntry {
|
struct alignas(16) RSBEntry {
|
||||||
u64 target;
|
u64 target;
|
||||||
u64 code_ptr;
|
u64 code_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr size_t RSBCount = 8;
|
constexpr std::size_t RSBCount = 8;
|
||||||
constexpr u64 RSBIndexMask = (RSBCount - 1) * sizeof(RSBEntry);
|
constexpr u64 RSBIndexMask = (RSBCount - 1) * sizeof(RSBEntry);
|
||||||
|
|
||||||
struct alignas(16) StackLayout {
|
struct alignas(16) StackLayout {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2023 MerryMage
|
* Copyright (c) 2023 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -51,7 +54,7 @@ void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx) {
|
||||||
code.ADD(SP, SP, sizeof(RegisterData));
|
code.ADD(SP, SP, sizeof(RegisterData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type) {
|
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type) {
|
||||||
fmt::print("dynarmic debug: %{:05} = ", inst_index);
|
fmt::print("dynarmic debug: %{:05} = ", inst_index);
|
||||||
|
|
||||||
Vector value = [&]() -> Vector {
|
Vector value = [&]() -> Vector {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/arm64/stack_layout.h"
|
#include "dynarmic/backend/arm64/stack_layout.h"
|
||||||
|
|
||||||
|
|
@ -54,6 +54,6 @@ struct alignas(16) RegisterData {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx);
|
void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx);
|
||||||
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type);
|
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type);
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
namespace Dynarmic::Backend {
|
namespace Dynarmic::Backend {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
@ -43,6 +43,7 @@ struct FakeCall {
|
||||||
};
|
};
|
||||||
#elif defined(ARCHITECTURE_riscv64)
|
#elif defined(ARCHITECTURE_riscv64)
|
||||||
struct FakeCall {
|
struct FakeCall {
|
||||||
|
u64 call_sepc;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
# error "Invalid architecture"
|
# error "Invalid architecture"
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/exception_handler.h"
|
#include "dynarmic/backend/exception_handler.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
@ -16,9 +17,9 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
#include "dynarmic/backend/exception_handler.h"
|
#include "dynarmic/backend/exception_handler.h"
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/context.h"
|
#include "dynarmic/common/context.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#if defined(ARCHITECTURE_x86_64)
|
||||||
# include "dynarmic/backend/x64/block_of_code.h"
|
# include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
#elif defined(ARCHITECTURE_arm64)
|
||||||
|
|
@ -140,7 +141,15 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
|
||||||
}
|
}
|
||||||
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
|
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
|
||||||
#elif defined(ARCHITECTURE_riscv64)
|
#elif defined(ARCHITECTURE_riscv64)
|
||||||
UNREACHABLE();
|
{
|
||||||
|
std::shared_lock guard(sig_handler->code_block_infos_mutex);
|
||||||
|
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_SEPC); iter != sig_handler->code_block_infos.end()) {
|
||||||
|
FakeCall fc = iter->second.cb(CTX_SEPC);
|
||||||
|
CTX_SEPC = fc.call_sepc;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_SEPC);
|
||||||
#else
|
#else
|
||||||
# error "Invalid architecture"
|
# error "Invalid architecture"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/riscv64/abi.h"
|
#include "dynarmic/backend/riscv64/abi.h"
|
||||||
#include "dynarmic/backend/riscv64/emit_riscv64.h"
|
#include "dynarmic/backend/riscv64/emit_riscv64.h"
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
#include "dynarmic/backend/riscv64/a32_address_space.h"
|
||||||
#include "dynarmic/backend/riscv64/a32_core.h"
|
#include "dynarmic/backend/riscv64/a32_core.h"
|
||||||
|
|
@ -42,7 +42,7 @@ struct Jit::Impl final {
|
||||||
HaltReason Step() {
|
HaltReason Step() {
|
||||||
ASSERT(!jit_interface->is_executing);
|
ASSERT(!jit_interface->is_executing);
|
||||||
jit_interface->is_executing = true;
|
jit_interface->is_executing = true;
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
RequestCacheInvalidation();
|
RequestCacheInvalidation();
|
||||||
jit_interface->is_executing = false;
|
jit_interface->is_executing = false;
|
||||||
return HaltReason{};
|
return HaltReason{};
|
||||||
|
|
@ -108,6 +108,10 @@ struct Jit::Impl final {
|
||||||
current_state.exclusive_state = false;
|
current_state.exclusive_state = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Disassemble() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RequestCacheInvalidation() {
|
void RequestCacheInvalidation() {
|
||||||
// UNREACHABLE();
|
// UNREACHABLE();
|
||||||
|
|
@ -198,4 +202,8 @@ void Jit::ClearExclusiveState() {
|
||||||
impl->ClearExclusiveState();
|
impl->ClearExclusiveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Jit::Disassemble() const {
|
||||||
|
return impl->Disassemble();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // namespace Dynarmic::A32
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#include "dynarmic/backend/riscv64/a32_jitstate.h"
|
#include "dynarmic/backend/riscv64/a32_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::RV64 {
|
namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
|
|
|
||||||
295
src/dynarmic/src/dynarmic/backend/riscv64/a64_interface.cpp
Normal file
|
|
@ -0,0 +1,295 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <boost/icl/interval_set.hpp>
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
|
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||||
|
#include "dynarmic/interface/A64/config.h"
|
||||||
|
#include "dynarmic/backend/riscv64/a32_core.h"
|
||||||
|
#include "dynarmic/common/atomic.h"
|
||||||
|
#include "dynarmic/ir/opt_passes.h"
|
||||||
|
#include "dynarmic/interface/A64/a64.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::A64 {
|
||||||
|
|
||||||
|
using namespace Dynarmic::Backend::RV64;
|
||||||
|
using CodePtr = std::uint32_t*;
|
||||||
|
|
||||||
|
struct Jit::Impl final {
|
||||||
|
Impl(Jit* jit_interface, A64::UserConfig conf)
|
||||||
|
: conf(conf)
|
||||||
|
//, current_address_space(conf)
|
||||||
|
, jit_interface(jit_interface) {}
|
||||||
|
|
||||||
|
HaltReason Run() {
|
||||||
|
ASSERT(false);
|
||||||
|
return HaltReason{};
|
||||||
|
}
|
||||||
|
|
||||||
|
HaltReason Step() {
|
||||||
|
ASSERT(false);
|
||||||
|
return HaltReason{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearCache() {
|
||||||
|
std::unique_lock lock{invalidation_mutex};
|
||||||
|
invalidate_entire_cache = true;
|
||||||
|
HaltExecution(HaltReason::CacheInvalidation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InvalidateCacheRange(u64 start_address, size_t length) {
|
||||||
|
std::unique_lock lock{invalidation_mutex};
|
||||||
|
const auto end_address = u64(start_address + length - 1);
|
||||||
|
invalid_cache_ranges.add(boost::icl::discrete_interval<u64>::closed(start_address, end_address));
|
||||||
|
HaltExecution(HaltReason::CacheInvalidation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
ASSERT(!is_executing);
|
||||||
|
//jit_state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void HaltExecution(HaltReason hr) {
|
||||||
|
//Atomic::Or(&jit_state.halt_reason, u32(hr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearHalt(HaltReason hr) {
|
||||||
|
//Atomic::And(&jit_state.halt_reason, ~u32(hr));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetSP() const {
|
||||||
|
return 0;//jit_state.sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSP(u64 value) {
|
||||||
|
//jit_state.sp = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetPC() const {
|
||||||
|
return 0;//jit_state.pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPC(u64 value) {
|
||||||
|
//jit_state.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetRegister(size_t index) const {
|
||||||
|
return 0;//index == 31 ? GetSP() : jit_state.regs.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRegister(size_t index, u64 value) {
|
||||||
|
if (index == 31)
|
||||||
|
return SetSP(value);
|
||||||
|
//jit_state.regs.at(index) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<u64, 31> GetRegisters() const {
|
||||||
|
return {};//jit_state.regs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRegisters(const std::array<u64, 31>& value) {
|
||||||
|
//jit_state.regs = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector GetVector(size_t index) const {
|
||||||
|
//return {jit_state.vec.at(index * 2), jit_state.vec.at(index * 2 + 1)};
|
||||||
|
return Vector{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetVector(size_t index, Vector value) {
|
||||||
|
//jit_state.vec.at(index * 2) = value[0];
|
||||||
|
//jit_state.vec.at(index * 2 + 1) = value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<Vector, 32> GetVectors() const {
|
||||||
|
std::array<Vector, 32> ret;
|
||||||
|
//static_assert(sizeof(ret) == sizeof(jit_state.vec));
|
||||||
|
//std::memcpy(ret.data(), jit_state.vec.data(), sizeof(jit_state.vec));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetVectors(const std::array<Vector, 32>& value) {
|
||||||
|
//static_assert(sizeof(value) == sizeof(jit_state.vec));
|
||||||
|
//std::memcpy(jit_state.vec.data(), value.data(), sizeof(jit_state.vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetFpcr() const {
|
||||||
|
return 0;//jit_state.fpcr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFpcr(u32 value) {
|
||||||
|
//jit_state.fpcr = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetFpsr() const {
|
||||||
|
return 0;//jit_state.fpsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFpsr(u32 value) {
|
||||||
|
//jit_state.fpsr = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetPstate() const {
|
||||||
|
return 0;//jit_state.pstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPstate(u32 value) {
|
||||||
|
//jit_state.pstate = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearExclusiveState() {
|
||||||
|
//jit_state.exclusive_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsExecuting() const {
|
||||||
|
return is_executing;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Disassemble() const {
|
||||||
|
// const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||||
|
// auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
|
||||||
|
// return Common::DisassemblePPC64(p, p + size);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RequestCacheInvalidation() {
|
||||||
|
// UNREACHABLE();
|
||||||
|
invalidate_entire_cache = false;
|
||||||
|
invalid_cache_ranges.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
A64::UserConfig conf;
|
||||||
|
//A64JitState jit_state{};
|
||||||
|
//A64AddressSpace current_address_space;
|
||||||
|
Jit* jit_interface;
|
||||||
|
volatile u32 halt_reason = 0;
|
||||||
|
bool is_executing = false;
|
||||||
|
|
||||||
|
boost::icl::interval_set<u64> invalid_cache_ranges;
|
||||||
|
bool invalidate_entire_cache = false;
|
||||||
|
std::mutex invalidation_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
Jit::Jit(UserConfig conf) : impl(std::make_unique<Jit::Impl>(this, conf)) {}
|
||||||
|
Jit::~Jit() = default;
|
||||||
|
|
||||||
|
HaltReason Jit::Run() {
|
||||||
|
return impl->Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
HaltReason Jit::Step() {
|
||||||
|
return impl->Step();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::ClearCache() {
|
||||||
|
impl->ClearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::InvalidateCacheRange(u64 start_address, size_t length) {
|
||||||
|
impl->InvalidateCacheRange(start_address, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::Reset() {
|
||||||
|
impl->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::HaltExecution(HaltReason hr) {
|
||||||
|
impl->HaltExecution(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::ClearHalt(HaltReason hr) {
|
||||||
|
impl->ClearHalt(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 Jit::GetSP() const {
|
||||||
|
return impl->GetSP();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetSP(u64 value) {
|
||||||
|
impl->SetSP(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 Jit::GetPC() const {
|
||||||
|
return impl->GetPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetPC(u64 value) {
|
||||||
|
impl->SetPC(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 Jit::GetRegister(size_t index) const {
|
||||||
|
return impl->GetRegister(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetRegister(size_t index, u64 value) {
|
||||||
|
impl->SetRegister(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<u64, 31> Jit::GetRegisters() const {
|
||||||
|
return impl->GetRegisters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetRegisters(const std::array<u64, 31>& value) {
|
||||||
|
impl->SetRegisters(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector Jit::GetVector(size_t index) const {
|
||||||
|
return impl->GetVector(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetVector(size_t index, Vector value) {
|
||||||
|
impl->SetVector(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<Vector, 32> Jit::GetVectors() const {
|
||||||
|
return impl->GetVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetVectors(const std::array<Vector, 32>& value) {
|
||||||
|
impl->SetVectors(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Jit::GetFpcr() const {
|
||||||
|
return impl->GetFpcr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetFpcr(u32 value) {
|
||||||
|
impl->SetFpcr(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Jit::GetFpsr() const {
|
||||||
|
return impl->GetFpsr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetFpsr(u32 value) {
|
||||||
|
impl->SetFpsr(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Jit::GetPstate() const {
|
||||||
|
return impl->GetPstate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::SetPstate(u32 value) {
|
||||||
|
impl->SetPstate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit::ClearExclusiveState() {
|
||||||
|
impl->ClearExclusiveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Jit::IsExecuting() const {
|
||||||
|
return impl->IsExecuting();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Jit::Disassemble() const {
|
||||||
|
return impl->Disassemble();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic::A64
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::RV64 {
|
namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
class CodeBlock {
|
class CodeBlock {
|
||||||
|
|
|
||||||
|
|
@ -35,17 +35,17 @@ void EmitIR<IR::Opcode::Identity>(biscuit::Assembler&, EmitContext& ctx, IR::Ins
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Breakpoint>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Breakpoint>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CallHostFunction>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CallHostFunction>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PushRSB>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PushRSB>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -56,12 +56,12 @@ void EmitIR<IR::Opcode::GetCarryFromOp>(biscuit::Assembler&, EmitContext& ctx, I
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetOverflowFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::GetOverflowFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetGEFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::GetGEFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -87,12 +87,12 @@ void EmitIR<IR::Opcode::GetNZFromOp>(biscuit::Assembler& as, EmitContext& ctx, I
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetUpperFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::GetUpperFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::GetLowerFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::GetLowerFromOp>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -109,7 +109,7 @@ void EmitIR<IR::Opcode::GetCFlagFromNZCV>(biscuit::Assembler& as, EmitContext& c
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::NZCVFromPackedFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::NZCVFromPackedFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitConfig& emit_conf) {
|
EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitConfig& emit_conf) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <biscuit/label.hpp>
|
#include <biscuit/label.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace biscuit {
|
namespace biscuit {
|
||||||
class Assembler;
|
class Assembler;
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx) {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -220,17 +220,17 @@ void EmitIR<IR::Opcode::A32GetRegister>(biscuit::Assembler& as, EmitContext& ctx
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -249,27 +249,27 @@ void EmitIR<IR::Opcode::A32SetRegister>(biscuit::Assembler& as, EmitContext& ctx
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetExtendedRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetExtendedRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetVector>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetCpsr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -284,17 +284,17 @@ void EmitIR<IR::Opcode::A32SetCpsrNZCV>(biscuit::Assembler& as, EmitContext& ctx
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetCpsrNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetCpsrNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetCpsrNZCVQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetCpsrNZCVQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetCpsrNZ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetCpsrNZ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -318,82 +318,82 @@ void EmitIR<IR::Opcode::A32SetCpsrNZC>(biscuit::Assembler& as, EmitContext& ctx,
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32OrQFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32OrQFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetGEFlags>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetGEFlagsCompressed>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetGEFlagsCompressed>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32BXWritePC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32BXWritePC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetFpscr>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32GetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32GetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32SetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32SetFpscrNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,37 +22,37 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocLoadWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocLoadWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CoprocStoreWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32CoprocStoreWords>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,87 +22,87 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A32ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,182 +22,182 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetCheckBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetCFlag>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetNZCVRaw>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetW>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetX>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetS>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetD>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetSP>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetFPCR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetFPSR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetPC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetPC>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64CallSupervisor>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExceptionRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64DataCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64DataCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64InstructionCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64InstructionCacheOperationRaised>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64DataSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64DataMemoryBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64InstructionSynchronizationBarrier>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetCNTFRQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetCNTFRQ>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetCNTPCT>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetCNTPCT>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetCTR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetCTR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetDCZID>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetDCZID>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64GetTPIDRRO>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64GetTPIDRRO>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64SetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64SetTPIDR>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,107 +22,107 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ClearExclusive>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveReadMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64WriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64WriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64WriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64WriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64WriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64WriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::A64ExclusiveWriteMemory128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32Castagnoli8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32Castagnoli8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32Castagnoli16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32Castagnoli16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32Castagnoli32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32Castagnoli32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32Castagnoli64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32Castagnoli64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32ISO8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32ISO8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32ISO16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32ISO16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32ISO32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32ISO32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CRC32ISO64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CRC32ISO64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AESDecryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AESDecryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AESEncryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AESEncryptSingleRound>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AESInverseMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AESInverseMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AESMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AESMixColumns>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SHA256Hash>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SHA256Hash>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SHA256MessageSchedule0>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SHA256MessageSchedule0>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SHA256MessageSchedule1>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SHA256MessageSchedule1>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -22,67 +22,67 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Pack2x32To1x64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Pack2x32To1x64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Pack2x64To1x128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Pack2x64To1x128>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LeastSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LeastSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LeastSignificantHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LeastSignificantHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LeastSignificantByte>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LeastSignificantByte>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MostSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MostSignificantWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MostSignificantBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MostSignificantBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::IsZero32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::IsZero32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::IsZero64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::IsZero64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::TestBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::TestBit>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ConditionalSelect32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ConditionalSelect32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ConditionalSelect64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ConditionalSelect64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -124,7 +124,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -153,72 +153,72 @@ void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ArithmeticShiftRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::BitRotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::BitRotateRight32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::BitRotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::BitRotateRight64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::RotateRightExtended>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::RotateRightExtended>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftLeftMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftLeftMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::LogicalShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ArithmeticShiftRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::RotateRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::RotateRightMasked32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::RotateRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::RotateRightMasked64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<size_t bitsize>
|
||||||
|
|
@ -264,7 +264,7 @@ static void AddImmWithFlags(biscuit::Assembler& as, biscuit::GPR rd, biscuit::GP
|
||||||
as.SLLI(Xscratch1, Xscratch1, 28);
|
as.SLLI(Xscratch1, Xscratch1, 28);
|
||||||
as.OR(flags, flags, Xscratch1);
|
as.OR(flags, flags, Xscratch1);
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,7 +279,7 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
|
||||||
auto Xa = ctx.reg_alloc.ReadX(args[0]);
|
auto Xa = ctx.reg_alloc.ReadX(args[0]);
|
||||||
|
|
||||||
if (overflow_inst) {
|
if (overflow_inst) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
} else if (nzcv_inst) {
|
} else if (nzcv_inst) {
|
||||||
if (args[1].IsImmediate()) {
|
if (args[1].IsImmediate()) {
|
||||||
const u64 imm = args[1].GetImmediateU64();
|
const u64 imm = args[1].GetImmediateU64();
|
||||||
|
|
@ -294,17 +294,17 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
|
||||||
AddImmWithFlags<bitsize>(as, *Xresult, *Xa, sub ? -imm : imm, *Xflags);
|
AddImmWithFlags<bitsize>(as, *Xresult, *Xa, sub ? -imm : imm, *Xflags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (args[1].IsImmediate()) {
|
if (args[1].IsImmediate()) {
|
||||||
const u64 imm = args[1].GetImmediateU64();
|
const u64 imm = args[1].GetImmediateU64();
|
||||||
|
|
||||||
if (args[2].IsImmediate()) {
|
if (args[2].IsImmediate()) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
} else {
|
} else {
|
||||||
auto Xnzcv = ctx.reg_alloc.ReadX(args[2]);
|
auto Xnzcv = ctx.reg_alloc.ReadX(args[2]);
|
||||||
RegAlloc::Realize(Xresult, Xa, Xnzcv);
|
RegAlloc::Realize(Xresult, Xa, Xnzcv);
|
||||||
|
|
@ -317,7 +317,7 @@ static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst)
|
||||||
as.ADDW(Xresult, Xa, Xscratch0);
|
as.ADDW(Xresult, Xa, Xscratch0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +329,7 @@ void EmitIR<IR::Opcode::Add32>(biscuit::Assembler& as, EmitContext& ctx, IR::Ins
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Add64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Add64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -339,237 +339,237 @@ void EmitIR<IR::Opcode::Sub32>(biscuit::Assembler& as, EmitContext& ctx, IR::Ins
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Sub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Sub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Mul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Mul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Mul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Mul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::And32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::And32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::And64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::And64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AndNot32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AndNot32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::AndNot64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::AndNot64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Eor32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Eor32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Eor64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Eor64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Or32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Or32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Or64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Or64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Not32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Not32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::Not64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::Not64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendByteToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendHalfToWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendByteToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendHalfToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendWordToLong>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ZeroExtendLongToQuad>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ByteReverseWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ByteReverseWord>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ByteReverseHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ByteReverseHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ByteReverseDual>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ByteReverseDual>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CountLeadingZeros32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CountLeadingZeros32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::CountLeadingZeros64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::CountLeadingZeros64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ExtractRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ExtractRegister32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ExtractRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ExtractRegister64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ReplicateBit32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ReplicateBit32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ReplicateBit64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::ReplicateBit64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MaxSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MaxSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MaxSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MaxSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MaxUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MaxUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MaxUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MaxUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MinSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MinSigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MinSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MinSigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MinUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MinUnsigned32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MinUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::MinUnsigned64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,442 +22,442 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPCompare32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPCompare32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPCompare64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPCompare64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipExponent16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipExponent16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipExponent32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipExponent32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipExponent64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipExponent64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToHalf>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPDoubleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPDoubleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPHalfToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPHalfToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedS32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedS64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedU32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPSingleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPSingleToFixedU64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS16ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS16ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS32ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS32ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedU64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedU64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS64ToDouble>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPFixedS64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPFixedS64ToSingle>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,172 +22,172 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingAddSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedHalvingSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedHalvingSubAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedAddU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedAddS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedSubU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedSubS8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedAddU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedAddS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedSubU16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSaturatedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSaturatedSubS16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAbsDiffSumU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedAbsDiffSumU8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSelect>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::PackedSelect>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,112 +22,112 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturation>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::SignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,337 +22,337 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorAbs16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorAbs32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorAbs64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorDiv32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorDiv64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorEqual16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorEqual16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorFromHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorFromHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorFromSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorFromSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorFromSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorFromUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorGreater32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorGreater32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorGreater64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorGreater64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorGreaterEqual32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorGreaterEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorGreaterEqual64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMax32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMax64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMaxNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMaxNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMin32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMin64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMinNumeric32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMinNumeric64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMul32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMul64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMulAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMulAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMulAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMulX32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorMulX64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorNeg16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorNeg32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorNeg64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorPairedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorPairedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorPairedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorPairedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorPairedAddLower32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorPairedAddLower64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorPairedAddLower64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRoundInt16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRoundInt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRoundInt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtEstimate64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorRSqrtStepFused64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorSqrt32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorSqrt64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToHalf32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToSignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToSignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::FPVectorToUnsignedFixed64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -19,82 +22,82 @@ namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorSignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorSignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedAdd64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub8>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub16>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub32>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
void EmitIR<IR::Opcode::VectorUnsignedSaturatedSub64>(biscuit::Assembler&, EmitContext&, IR::Inst*) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::RV64
|
} // namespace Dynarmic::Backend::RV64
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "dynarmic/interface/exclusive_monitor.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
|
||||||
|
ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count)
|
||||||
|
: exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {}
|
||||||
|
|
||||||
|
size_t ExclusiveMonitor::GetProcessorCount() const {
|
||||||
|
return exclusive_addresses.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExclusiveMonitor::Lock() {
|
||||||
|
lock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExclusiveMonitor::Unlock() {
|
||||||
|
lock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) {
|
||||||
|
const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
|
||||||
|
|
||||||
|
Lock();
|
||||||
|
if (exclusive_addresses[processor_id] != masked_address) {
|
||||||
|
Unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (VAddr& other_address : exclusive_addresses) {
|
||||||
|
if (other_address == masked_address) {
|
||||||
|
other_address = INVALID_EXCLUSIVE_ADDRESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExclusiveMonitor::Clear() {
|
||||||
|
Lock();
|
||||||
|
std::fill(exclusive_addresses.begin(), exclusive_addresses.end(), INVALID_EXCLUSIVE_ADDRESS);
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExclusiveMonitor::ClearProcessor(size_t processor_id) {
|
||||||
|
Lock();
|
||||||
|
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/common/always_false.h"
|
#include "dynarmic/common/always_false.h"
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ u32 RegAlloc::GenerateImmediate(const IR::Value& value) {
|
||||||
|
|
||||||
return new_location_index;
|
return new_location_index;
|
||||||
} else if constexpr (kind == HostLoc::Kind::Fpr) {
|
} else if constexpr (kind == HostLoc::Kind::Fpr) {
|
||||||
UNIMPLEMENTED();
|
ASSERT(false && "Unimplemented instruction");
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
#include <biscuit/assembler.hpp>
|
#include <biscuit/assembler.hpp>
|
||||||
#include <biscuit/registers.hpp>
|
#include <biscuit/registers.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
#include "dynarmic/mcl/is_instance_of_template.hpp"
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::RV64 {
|
namespace Dynarmic::Backend::RV64 {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/common/llvm_disassemble.h"
|
#include "dynarmic/common/llvm_disassemble.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -9,8 +9,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
|
@ -48,8 +49,8 @@ struct A32JitState {
|
||||||
// Exclusive state
|
// Exclusive state
|
||||||
u32 exclusive_state = 0;
|
u32 exclusive_state = 0;
|
||||||
|
|
||||||
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
|
static constexpr std::size_t RSBSize = 8; // MUST be a power of 2.
|
||||||
static constexpr size_t RSBPtrMask = RSBSize - 1;
|
static constexpr std::size_t RSBPtrMask = RSBSize - 1;
|
||||||
u32 rsb_ptr = 0;
|
u32 rsb_ptr = 0;
|
||||||
std::array<u64, RSBSize> rsb_location_descriptors;
|
std::array<u64, RSBSize> rsb_location_descriptors;
|
||||||
std::array<u64, RSBSize> rsb_codeptrs;
|
std::array<u64, RSBSize> rsb_codeptrs;
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/mcl/integer_of_size.hpp"
|
#include "dynarmic/mcl/integer_of_size.hpp"
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include "dynarmic/common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "dynarmic/common/fp/fpcr.h"
|
#include "dynarmic/common/fp/fpcr.h"
|
||||||
#include "dynarmic/common/llvm_disassemble.h"
|
#include "dynarmic/common/llvm_disassemble.h"
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/backend/x64/xbyak.h"
|
#include "dynarmic/backend/x64/xbyak.h"
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "dynarmic/backend/x64/hostloc.h"
|
#include "dynarmic/backend/x64/hostloc.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
|
||||||