From 743f51e1078df7bbc29f39a5dc5f4c60a97fccff Mon Sep 17 00:00:00 2001 From: Owen Yamauchi Date: Wed, 20 Mar 2013 08:42:09 -0700 Subject: [PATCH] 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. --- CMakeLists.txt | 2 +- hphp/CMakeLists.txt | 4 +- .../vm/translator/translator-asm-helpers.S | 107 ++++++++++++++++ hphp/runtime/vm/translator/translator-x64.cpp | 114 ++---------------- hphp/util/asm-x64.h | 10 -- 5 files changed, 121 insertions(+), 116 deletions(-) create mode 100644 hphp/runtime/vm/translator/translator-asm-helpers.S diff --git a/CMakeLists.txt b/CMakeLists.txt index 61bbd86bf..c26899158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/hphp/CMakeLists.txt b/hphp/CMakeLists.txt index 55fbc2622..c1d0d1f12 100644 --- a/hphp/CMakeLists.txt +++ b/hphp/CMakeLists.txt @@ -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) diff --git a/hphp/runtime/vm/translator/translator-asm-helpers.S b/hphp/runtime/vm/translator/translator-asm-helpers.S new file mode 100644 index 000000000..caef6b419 --- /dev/null +++ b/hphp/runtime/vm/translator/translator-asm-helpers.S @@ -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 \ No newline at end of file diff --git a/hphp/runtime/vm/translator/translator-x64.cpp b/hphp/runtime/vm/translator/translator-x64.cpp index 879eda9c4..f639fd175 100644 --- a/hphp/runtime/vm/translator/translator-x64.cpp +++ b/hphp/runtime/vm/translator/translator-x64.cpp @@ -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) { diff --git a/hphp/util/asm-x64.h b/hphp/util/asm-x64.h index 110b00f78..55783dd6f 100644 --- a/hphp/util/asm-x64.h +++ b/hphp/util/asm-x64.h @@ -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.