Separate handwritten assembly helpers into a .S file
This feels like a cleaner approach. It separates code that's arch-specific by nature, lets us avoid all the ugly quote marks and \n sequences, and lets your editor do real syntax highlighting of asm.
Esse commit está contido em:
+1
-1
@@ -1,5 +1,5 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.4 FATAL_ERROR)
|
||||
PROJECT(hphp C CXX)
|
||||
PROJECT(hphp C CXX ASM)
|
||||
|
||||
IF("$ENV{HPHP_HOME}" STREQUAL "")
|
||||
message(FATAL_ERROR "You should set the HPHP_HOME environmental")
|
||||
|
||||
@@ -31,6 +31,8 @@ foreach (dir ${RECURSIVE_SOURCE_SUBDIRS})
|
||||
auto_sources(files "*.c" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
|
||||
list(APPEND C_SOURCES ${files})
|
||||
|
||||
auto_sources(files "*.S" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
|
||||
list(APPEND ASM_SOURCES ${files})
|
||||
endforeach(dir ${RECURSIVE_SOURCE_SUBDIRS})
|
||||
|
||||
# Disable hardware counters off of Linux
|
||||
@@ -80,7 +82,7 @@ add_custom_command(
|
||||
|
||||
ADD_LIBRARY(hphp_runtime_static STATIC
|
||||
hphp_repo_schema.h hphp_build_info.cpp
|
||||
${CXX_SOURCES} ${C_SOURCES})
|
||||
${CXX_SOURCES} ${C_SOURCES} ${ASM_SOURCES})
|
||||
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES OUTPUT_NAME "hphp_runtime")
|
||||
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES PREFIX "lib")
|
||||
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* enterTCHelper
|
||||
*
|
||||
* This helper routine is written in assembly to take care of the details
|
||||
* when transferring control between jitted code and the translator.
|
||||
* rdi / x0: Cell* vm_sp
|
||||
* rsi / x1: Cell* vm_fp
|
||||
* rdx / x2: unsigned char* start
|
||||
* rcx / x3: TReqInfo* infoPtr
|
||||
* r8 / x4: ActRec* firstAR
|
||||
* r9 / x5: uint8_t* targetCacheBase
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(__x86_64__)
|
||||
.byte 0
|
||||
.align 16
|
||||
.section .text
|
||||
.globl enterTCHelper
|
||||
enterTCHelper:
|
||||
// Prologue
|
||||
.cfi_startproc
|
||||
push %rbp
|
||||
.cfi_adjust_cfa_offset 8 // offset to previous frame relative to %rsp
|
||||
.cfi_offset rbp, -16 // Where to find previous value of rbp
|
||||
|
||||
// Set firstAR->m_savedRbp to point to this frame.
|
||||
mov %rsp, (%r8)
|
||||
|
||||
// Save infoPtr
|
||||
push %rcx
|
||||
.cfi_adjust_cfa_offset 8
|
||||
|
||||
// Set up special registers used for translated code.
|
||||
mov %rdi, %rbx // rVmSp
|
||||
mov %r9, %r12 // rVmTl
|
||||
mov %rsi, %rbp // rVmFp
|
||||
mov 0x30(%rcx), %r15 // rStashedAR saved across service requests
|
||||
|
||||
/*
|
||||
* The translated code we are about to enter does not follow the
|
||||
* standard prologue of pushing rbp at entry, so we are purposely 8
|
||||
* bytes short of 16-byte alignment before this call instruction so
|
||||
* that the return address being pushed will make the native stack
|
||||
* 16-byte aligned.
|
||||
*/
|
||||
|
||||
sub $0x100, %rsp // kReservedRSPScratchSpace
|
||||
|
||||
/*
|
||||
* If returning from a BIND_CALL request, push the return IP saved
|
||||
* in the ActRec pointed to by r15. The 0x1 in the cmp instruction
|
||||
* must be kept in sync with REQ_BIND_CALL in abi-x64.h.
|
||||
*/
|
||||
cmp $0x1, 0x0(%rcx)
|
||||
jne .LenterTCHelper$jumpToTC
|
||||
lea .LenterTCHelper$serviceReqLabel(%rip), %rax
|
||||
push %rax
|
||||
push 0x8(%r15)
|
||||
jmp *%rdx
|
||||
.LenterTCHelper$jumpToTC:
|
||||
// May need cfi_adjust_cfa_offset annotations: Task #1747813
|
||||
call *%rdx
|
||||
.LenterTCHelper$serviceReqLabel:
|
||||
|
||||
add $0x100, %rsp // kReservedRSPScratchSpace
|
||||
// Restore infoPtr into %rbx
|
||||
pop %rbx
|
||||
.cfi_adjust_cfa_offset -8
|
||||
|
||||
// Copy the values passed from jitted code into *infoPtr
|
||||
mov %rdi, 0x0(%rbx)
|
||||
test %rdi,%rdi
|
||||
jnz .LenterTCHelper$copyReqArgs
|
||||
.cfi_remember_state
|
||||
pop %rbp
|
||||
.cfi_restore rbp
|
||||
.cfi_adjust_cfa_offset -8
|
||||
ret
|
||||
|
||||
.LenterTCHelper$copyReqArgs:
|
||||
.cfi_restore_state
|
||||
mov %rsi, 0x8(%rbx)
|
||||
mov %rdx, 0x10(%rbx)
|
||||
mov %rcx, 0x18(%rbx)
|
||||
mov %r8, 0x20(%rbx)
|
||||
mov %r9, 0x28(%rbx)
|
||||
|
||||
// Service request "callee-saved". (Returnee-saved?)
|
||||
mov %r15, 0x30(%rbx)
|
||||
|
||||
// copy stub address into infoPtr->stubAddr
|
||||
mov %r10, 0x38(%rbx)
|
||||
|
||||
// Epilogue
|
||||
pop %rbp
|
||||
.cfi_restore rbp
|
||||
.cfi_adjust_cfa_offset -8
|
||||
ret
|
||||
.cfi_endproc
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#elif defined(__AARCH64_EL__)
|
||||
.globl enterTCHelper
|
||||
enterTCHelper:
|
||||
brk 0
|
||||
|
||||
#endif
|
||||
@@ -3159,114 +3159,26 @@ struct DepthGuard { bool depthOne() const { return false; } };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* enterTCHelper
|
||||
*
|
||||
* This helper routine is written in x64 assembly to take care of the details
|
||||
* when transferring control between jitted code and the translator.
|
||||
* rdi: Cell* vm_sp
|
||||
* rsi: Cell* vm_fp
|
||||
* rdx: unsigned char* start
|
||||
* rcx: TReqInfo* infoPtr
|
||||
* r8: ActRec* firstAR
|
||||
* r9: uint8_t* targetCacheBase
|
||||
* enterTCHelper is a handwritten assembly function that transfers control in
|
||||
* and out of the TC.
|
||||
*/
|
||||
static_assert(rVmSp == rbx &&
|
||||
rVmFp == rbp &&
|
||||
rVmTl == r12 &&
|
||||
rStashedAR == r15,
|
||||
"__enterTCHelper needs to be modified to use the correct ABI");
|
||||
"__enterTCHelper needs to be modified to use the correct ABI");
|
||||
static_assert(kReservedRSPScratchSpace == 0x100,
|
||||
"enterTCHelper needs to be updated for changes to "
|
||||
"kReservedRSPScratchSpace");
|
||||
static_assert(REQ_BIND_CALL == 0x1,
|
||||
"Update assembly test for REQ_BIND_CALL in __enterTCHelper");
|
||||
asm (
|
||||
".byte 0\n"
|
||||
".align 16\n"
|
||||
".section .text\n"
|
||||
".globl __enterTCHelper\n"
|
||||
"__enterTCHelper:\n"
|
||||
// Prologue
|
||||
".cfi_startproc\n"
|
||||
"push %rbp\n"
|
||||
".cfi_adjust_cfa_offset 8\n" // offset to previous frame relative to %rsp
|
||||
".cfi_offset rbp, -16\n" // Where to find previous value of rbp
|
||||
"Update assembly test for REQ_BIND_CALL in __enterTCHelper");
|
||||
extern "C" void enterTCHelper(Cell* vm_sp,
|
||||
Cell* vm_fp,
|
||||
TCA start,
|
||||
TReqInfo* infoPtr,
|
||||
ActRec* firstAR,
|
||||
void* targetCacheBase);
|
||||
|
||||
// Set firstAR->m_savedRbp to point to this frame.
|
||||
"mov %rsp, (%r8)\n"
|
||||
|
||||
// Save infoPtr
|
||||
"push %rcx\n"
|
||||
".cfi_adjust_cfa_offset 8\n"
|
||||
|
||||
// Set up special registers used for translated code.
|
||||
"mov %rdi, %rbx\n" // rVmSp
|
||||
"mov %r9, %r12\n" // rVmTl
|
||||
"mov %rsi, %rbp\n" // rVmFp
|
||||
"mov 0x30(%rcx), %r15\n" // rStashedAR saved across service requests
|
||||
|
||||
/*
|
||||
* The translated code we are about to enter does not follow the
|
||||
* standard prologue of pushing rbp at entry, so we are purposely 8
|
||||
* bytes short of 16-byte alignment before this call instruction so
|
||||
* that the return address being pushed will make the native stack
|
||||
* 16-byte aligned.
|
||||
*/
|
||||
|
||||
"sub $0x100, %rsp\n" // kReservedRSPScratchSpace
|
||||
|
||||
/*
|
||||
* If returning from a BIND_CALL request, push the return IP saved
|
||||
* in the ActRec pointed to by r15. The 0x1 in the cmp instruction
|
||||
* must be kept in sync with REQ_BIND_CALL in abi-x64.h.
|
||||
*/
|
||||
"cmp $0x1, 0x0(%rcx)\n"
|
||||
"jne .LenterTCHelper$jumpToTC\n"
|
||||
"lea .LenterTCHelper$serviceReqLabel(%rip), %rax\n"
|
||||
"push %rax\n"
|
||||
"push 0x8(%r15)\n"
|
||||
"jmp *%rdx\n"
|
||||
".LenterTCHelper$jumpToTC:\n"
|
||||
// May need cfi_adjust_cfa_offset annotations: Task #1747813
|
||||
"call *%rdx\n"
|
||||
".LenterTCHelper$serviceReqLabel:\n"
|
||||
|
||||
"add $0x100, %rsp\n" // kReservedRSPScratchSpace
|
||||
// Restore infoPtr into %rbx
|
||||
"pop %rbx\n"
|
||||
".cfi_adjust_cfa_offset -8\n"
|
||||
|
||||
// Copy the values passed from jitted code into *infoPtr
|
||||
"mov %rdi, 0x0(%rbx)\n"
|
||||
"test %rdi,%rdi\n"
|
||||
"jnz .LenterTCHelper$copyReqArgs\n"
|
||||
".cfi_remember_state\n"
|
||||
"pop %rbp\n"
|
||||
".cfi_restore rbp\n"
|
||||
".cfi_adjust_cfa_offset -8\n"
|
||||
"ret\n"
|
||||
|
||||
".LenterTCHelper$copyReqArgs:\n"
|
||||
".cfi_restore_state\n"
|
||||
"mov %rsi, 0x8(%rbx)\n"
|
||||
"mov %rdx, 0x10(%rbx)\n"
|
||||
"mov %rcx, 0x18(%rbx)\n"
|
||||
"mov %r8, 0x20(%rbx)\n"
|
||||
"mov %r9, 0x28(%rbx)\n"
|
||||
|
||||
// Service request "callee-saved". (Returnee-saved?)
|
||||
"mov %r15, 0x30(%rbx)\n"
|
||||
|
||||
// copy stub address into infoPtr->stubAddr
|
||||
"mov %r10, 0x38(%rbx)\n"
|
||||
|
||||
// Epilogue
|
||||
"pop %rbp\n"
|
||||
".cfi_restore rbp\n"
|
||||
".cfi_adjust_cfa_offset -8\n"
|
||||
"ret\n"
|
||||
".cfi_endproc\n"
|
||||
);
|
||||
|
||||
struct TReqInfo {
|
||||
uintptr_t requestNum;
|
||||
@@ -3279,12 +3191,6 @@ struct TReqInfo {
|
||||
TCA stubAddr;
|
||||
};
|
||||
|
||||
void enterTCHelper(Cell* vm_sp,
|
||||
Cell* vm_fp,
|
||||
TCA start,
|
||||
TReqInfo* infoPtr,
|
||||
ActRec* firstAR,
|
||||
void* targetCacheBase) asm ("__enterTCHelper");
|
||||
|
||||
void
|
||||
TranslatorX64::enterTC(SrcKey sk, TCA start) {
|
||||
|
||||
@@ -41,16 +41,6 @@
|
||||
* 2. The embedded assemblers from v8, the Sun JVM, etc.
|
||||
*/
|
||||
|
||||
#ifndef __x86_64__
|
||||
/*
|
||||
* Technically, you could use this to generate x86_64 instructions on some
|
||||
* other platform, e.g., in a cross-compiler.
|
||||
*
|
||||
* Most likely, you didn't mean to do this, though.
|
||||
*/
|
||||
#error Your architecture is unsupported.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some members cannot be const because their values aren't known in
|
||||
* an initialization list. Like the opposite of the "mutable" keyword.
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário