Skip to content

Commit

Permalink
Merge pull request FEX-Emu#3868 from bylaws/arm64ec-oldnew
Browse files Browse the repository at this point in the history
ARM64EC frontend
  • Loading branch information
Sonicadvance1 authored Jul 15, 2024
2 parents e65545a + f6f8d26 commit 6df51a5
Show file tree
Hide file tree
Showing 11 changed files with 929 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.14)
project(FEX)
project(FEX C CXX ASM)

INCLUDE (CheckIncludeFiles)
CHECK_INCLUDE_FILES ("gdb/jit-reader.h" HAVE_GDB_JIT_READER_H)
Expand Down
2 changes: 1 addition & 1 deletion External/jemalloc
Submodule jemalloc updated 1 files
+1 −1 src/pages.c
21 changes: 21 additions & 0 deletions Source/Windows/ARM64EC/BTInterface.h
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);
}
28 changes: 28 additions & 0 deletions Source/Windows/ARM64EC/CMakeLists.txt
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)
80 changes: 80 additions & 0 deletions Source/Windows/ARM64EC/Module.S
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
Loading

0 comments on commit 6df51a5

Please sign in to comment.