forked from FEX-Emu/FEX
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request FEX-Emu#3868 from bylaws/arm64ec-oldnew
ARM64EC frontend
- Loading branch information
Showing
11 changed files
with
929 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// SPDX-License-Identifier: MIT | ||
#pragma once | ||
|
||
#include <windef.h> | ||
#include <ntstatus.h> | ||
#include <winternl.h> | ||
|
||
extern "C" { | ||
void STDMETHODCALLTYPE ProcessInit(); | ||
void STDMETHODCALLTYPE ProcessTerm(); | ||
NTSTATUS STDMETHODCALLTYPE ThreadInit(); | ||
NTSTATUS STDMETHODCALLTYPE ThreadTerm(HANDLE Thread); | ||
NTSTATUS STDMETHODCALLTYPE ResetToConsistentState(EXCEPTION_POINTERS* Ptrs, ARM64_NT_CONTEXT* Context, BOOLEAN* Continue); | ||
void STDMETHODCALLTYPE BTCpu64FlushInstructionCache(const void* Address, SIZE_T Size); | ||
void STDMETHODCALLTYPE NotifyMemoryAlloc(void* Address, SIZE_T Size, ULONG Type, ULONG Prot); | ||
void STDMETHODCALLTYPE NotifyMemoryFree(void* Address, SIZE_T Size, ULONG FreeType); | ||
void STDMETHODCALLTYPE NotifyMemoryProtect(void* Address, SIZE_T Size, ULONG NewProt); | ||
void STDMETHODCALLTYPE NotifyUnmapViewOfSection(void* Address); | ||
BOOLEAN STDMETHODCALLTYPE BTCpu64IsProcessorFeaturePresent(UINT Feature); | ||
void STDMETHODCALLTYPE UpdateProcessorInformation(SYSTEM_CPU_INFORMATION* Info); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
add_library(arm64ecfex SHARED | ||
Module.cpp | ||
Module.S | ||
libarm64ecfex.def | ||
) | ||
patch_library_wine(arm64ecfex) | ||
|
||
target_include_directories(arm64ecfex PRIVATE | ||
"${CMAKE_SOURCE_DIR}/Source/Windows/include/" | ||
"${CMAKE_SOURCE_DIR}/Source/" | ||
"${CMAKE_SOURCE_DIR}/Source/Windows/" | ||
) | ||
|
||
target_link_libraries(arm64ecfex | ||
PRIVATE | ||
FEXCore | ||
FEXCore_Base | ||
Common | ||
CommonTools | ||
CommonWindows | ||
ntdll_ex | ||
ntdll | ||
) | ||
|
||
install(TARGETS arm64ecfex | ||
RUNTIME | ||
DESTINATION lib | ||
COMPONENT runtime) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
.text | ||
.balign 16 | ||
|
||
// __os_arm64x_x64_jump in ARM64EC docs | ||
// Expects target code address in x9 | ||
.globl DispatchJump | ||
DispatchJump: | ||
str lr, [sp, #-8]! // Push return address to stack, this will be popped by the x86 RET instr. | ||
b check_target_ec | ||
|
||
// __os_arm64x_dispatch_ret in ARM64EC docs | ||
// Expects target code address in lr | ||
.globl RetToEntryThunk | ||
RetToEntryThunk: | ||
mov x9, lr | ||
|
||
check_target_ec: | ||
// Check if target is in fact x86 code | ||
ldr x16, [x18, #0x60] // TEB->PEB | ||
ldr x16, [x16, #0x368] // PEB->EcCodeBitMap | ||
lsr x17, x9, #15 | ||
and x17, x17, #0x1fffffffffff8 | ||
ldr x16, [x16, x17] | ||
lsr x17, x9, #12 | ||
lsr x16, x16, x17 | ||
tbnz x16, #0, ExitFunctionEC | ||
b enter_jit | ||
|
||
// __os_arm64x_dispatch_call_no_redirect in ARM64EC docs | ||
// Expects target code address in x9, and to be called using a 'blr x16' instruction. | ||
.globl ExitToX64 | ||
ExitToX64: | ||
str lr, [sp, #-8]! // Push return address to stack, this will be popped by the x86 RET instr. | ||
|
||
enter_jit: | ||
ldr x17, [x18, #0x1788] // TEB->ChpeV2CpuAreaInfo | ||
ldr x16, [x17, #0x40] // ChpeV2CpuAreaInfo->EmulatorData[2] - DispatcherLoopTopEnterEC | ||
br x16 // DispatcherLoopTopEnterEC(RIP:x9, CPUArea:x17) | ||
|
||
// Invoked by KiUserEmulationDispatcher after e.g. an NtContinue to x86 code | ||
// Expects a CONTEXT pointer in x0 | ||
.global BeginSimulation | ||
BeginSimulation: | ||
bl "#SyncThreadContext" | ||
ldr x17, [x18, #0x1788] // TEB->ChpeV2CpuAreaInfo | ||
ldr x16, [x17, #0x48] // ChpeV2CpuAreaInfo->EmulatorData[3] - DispatcherLoopTopEnterECFillSRA | ||
br x16 // DispatcherLoopTopEnterECFillSRA(CPUArea:x17) | ||
|
||
// Called into by FEXCore | ||
// Expects the target code address in x9 | ||
.global ExitFunctionEC | ||
ExitFunctionEC: | ||
// Either return to an exit thunk (return to ARM64EC function) or call an entry thunk (call to ARM64EC function). | ||
// It is assumed that a 'blr x16' instruction is only ever used to call into x86 code from an exit thunk, and that all | ||
// exported ARM64EC functions have a 4-byte offset to their entry thunk immediately before their first instruction. | ||
mov x17, x9 | ||
mov w16, #0x200 | ||
movk w16, #0xd63f, lsl 16 // blr x16 | ||
ldursw x23, [x17, #-0x4] // Load either the entry thunk offset or the calling instruction. | ||
cmp w23, w16 | ||
beq ret_sp_aligned | ||
|
||
and x23, x23, #-0x4 | ||
add x17, x17, x23 // Resolve entry thunk address. | ||
|
||
mov x4, sp | ||
tbz x4, #3, ret_sp_misaligned | ||
ldr lr, [x4], #0x8 // Pop the return address into lr. | ||
mov sp, x4 | ||
|
||
ret_sp_aligned: | ||
br x17 | ||
|
||
ret_sp_misaligned: | ||
// In the case of the x64 caller leaving sp only 8-byte aligned, leave the return address on the stack to keep 16-byte | ||
// alignment and have the callee return to an x86 ret instruction. FEX can then return to the actual caller keeping | ||
// the misaligned RSP. | ||
adrp lr, X64ReturnInstr | ||
ldr lr, [lr, #:lo12:X64ReturnInstr] | ||
br x17 |
Oops, something went wrong.