Difference between revisions of "Development:ARM64EC"

From FEX-Emu Wiki
Jump to navigation Jump to search
(Created page with "=== Building === These instructions expect you to be building on an ARM64 host. ==== Toolchain ==== Scripts and instructions to build an ARM64ec toolchain can be found here,...")
 
Line 3: Line 3:
  
 
==== Toolchain ====
 
==== Toolchain ====
Scripts and instructions to build an ARM64ec toolchain can be found here, with prebuilt binaries for ARM64/x86 hosts on the releases page. Once built/downloaded, add it to your environment with `export PATH="<path to toolchain>/bin:$PATH
+
Scripts and instructions to build an ARM64EC toolchain can be found here, with prebuilt binaries for ARM64/x86 hosts on the releases page. Once built/downloaded, add it to your environment with  
 
+
export PATH="<path to toolchain>/bin:$PATH"
"`, note the toolchain must come before all other path entries as it needs to override the host ar binary.
+
note the toolchain must come before all other path entries as it needs to override the host ar binary.
  
 
==== Wine ====
 
==== Wine ====
 
Upstream wine has various things missing for full FEX/ARM64EC support, while it can be used using my fork will give the best results for now.  
 
Upstream wine has various things missing for full FEX/ARM64EC support, while it can be used using my fork will give the best results for now.  
  
```
+
  ./configure --enable-archs=arm64ec,aarch64,i386 --with-mingw=clang
 
 
./configure --enable-archs=arm64ec,aarch64,i386 --with-mingw=clang  
 
 
 
make -j$(nproc)
 
  
sudo make install
+
make -j$(nproc)
  
```
+
sudo make install
  
 
==== FEX ====
 
==== FEX ====
 
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)  
 
FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)  
 +
mkdir build-arm64ec
  
 +
cd build-arm64ec
  
```
+
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/arm64ec-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 <path to fex>
 
 
mkdir build-arm64ec
 
 
 
cd build-arm64ec
 
 
 
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/arm64ec-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 <path to  
 
 
 
fex>`
 
 
 
ninja
 
 
 
sudo ninja install
 
 
 
cd ..
 
 
 
```
 
 
 
  
```
+
ninja
  
mkdir build-wow64
+
sudo ninja install
  
cd build-wow64
+
cd ..
  
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 <path to
+
mkdir build-wow64
  
fex>`
+
cd build-wow64
  
ninja
+
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 <path to fex>
  
sudo ninja install
+
ninja
  
cd ..
+
sudo ninja install
  
```
+
cd ..
  
 
==== dxvk/vkd3d-proton ====
 
==== dxvk/vkd3d-proton ====
Line 65: Line 46:
  
 
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file:  
 
Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file:  
 +
[binaries]
  
```
+
ar = 'arm64ec-w64-mingw32-ar'
 
 
[binaries]
 
 
 
ar = 'arm64ec-w64-mingw32-ar'
 
 
 
c = 'arm64ec-w64-mingw32-gcc'
 
 
 
cpp = 'arm64ec-w64-mingw32-g++'  
 
  
ld = 'arm64ec-w64-mingw32-ld'  
+
c = 'arm64ec-w64-mingw32-gcc'
  
windres = 'arm64ec-w64-mingw32-windres'  
+
cpp = 'arm64ec-w64-mingw32-g++'
  
strip = 'strip'  
+
ld = 'arm64ec-w64-mingw32-ld'
  
widl = 'arm64ec-w64-mingw32-widl'  
+
windres = 'arm64ec-w64-mingw32-windres'
  
pkgconfig = 'aarch64-linux-gnu-pkg-config'  
+
strip = 'strip'
  
 +
widl = 'arm64ec-w64-mingw32-widl'
  
[host_machine]
+
pkgconfig = 'aarch64-linux-gnu-pkg-config'
  
system = 'windows'
+
<br />
 +
[host_machine]
  
cpu_family = 'aarch64'  
+
system = 'windows'
  
cpu = 'aarch64'  
+
cpu_family = 'aarch64'
  
endian = 'little'  
+
cpu = 'aarch64'
  
```
+
endian = 'little'
  
 
=== Info ===
 
=== Info ===

Revision as of 21:42, 28 September 2024

Building

These instructions expect you to be building on an ARM64 host.

Toolchain

Scripts and instructions to build an ARM64EC toolchain can be found here, with prebuilt binaries for ARM64/x86 hosts on the releases page. Once built/downloaded, add it to your environment with

export PATH="<path to toolchain>/bin:$PATH"

note the toolchain must come before all other path entries as it needs to override the host ar binary.

Wine

Upstream wine has various things missing for full FEX/ARM64EC support, while it can be used using my fork will give the best results for now.

 ./configure --enable-archs=arm64ec,aarch64,i386 --with-mingw=clang
make -j$(nproc)
sudo make install

FEX

FEX must be built twice, once for the x86 (WOW64) emulation module and once for x86_64 emulation module (ARM64EC)

mkdir build-arm64ec
cd build-arm64ec
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/arm64ec-windows -DENABLE_LTO=False -DMINGW_TRIPLE=arm64ec-w64-mingw32 <path to fex>
ninja
sudo ninja install
cd ..
mkdir build-wow64
cd build-wow64
cmake -GNinja -DCMAKE_BUILD_TYPE=<desire build type> -DCMAKE_TOOLCHAIN_FILE=/data/Proton/FEX/toolchain_mingw.cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib/wine/aarch64-windows -DENABLE_LTO=False -DMINGW_TRIPLE=aarch64-w64-mingw32 <path to fex>
ninja
sudo ninja install
cd ..

dxvk/vkd3d-proton

Both can be built and installed as instructed on their respective github pages, except that a path to the following cross file should be passed to meson with --cross-file:

[binaries]
ar = 'arm64ec-w64-mingw32-ar'
c = 'arm64ec-w64-mingw32-gcc'
cpp = 'arm64ec-w64-mingw32-g++'
ld = 'arm64ec-w64-mingw32-ld'
windres = 'arm64ec-w64-mingw32-windres'
strip = 'strip'
widl = 'arm64ec-w64-mingw32-widl'
pkgconfig = 'aarch64-linux-gnu-pkg-config'

[host_machine]
system = 'windows'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

Info

Unlike Linux FEX, the Windows FEX modules purely handle CPU emulation, with syscall translation being done on either the wine side (WOW64) or ABI (ARM64EC). This is similarly the case for wine's unixcalls and as a result native ARM64 variants can be used for all .so libraries (Vulkan, wine, etc.) dropping the need for an x86 rootfs and FEX-side thunking.


WOW64 is fairly simple, every dll is compiled with both x86 and ARM64 variants and in an x86 process only the x86 variants are loaded (with ARM64 FEX and ntdll) the only thunking done is for {unix,sys}calls so almost all Windows code is emulated.


ARM64EC on the otherhand avoids duplicating dlls at all, instead choosing to introduce a new ARM64 ABI allowing for transparent compiler-aided interop with any existing x86_64 code. The following pages serve as a good introduction:

https://learn.microsoft.com/en-us/windows/arm/arm64ec

https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi

https://gitlab.winehq.org/wine/wine/-/wikis/ARM64EC-Toolchain


Of note is the fact that FEX needs to run in a very reduced Windows environment - due to how early it is loaded it can only depend on ntdll and not say the system CRT. This is worked around by implementing/stubbing the subset of the CRT/Windows APIs necessary for FEX to run/link purely ontop of ntdll (see Common/Windows/{WinAPI,CRT}).