Unverified Commit ce170f42 authored by Ge Jun's avatar Ge Jun Committed by GitHub

Merge pull request #924 from niukuo/arm64

adapt to Arm64
parents 869b27c6 c271e2e0
...@@ -113,8 +113,11 @@ use_cxx11() ...@@ -113,8 +113,11 @@ use_cxx11()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
#required by butil/crc32.cc to boost performance for 10x #required by butil/crc32.cc to boost performance for 10x
if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)) if((CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -msse4.2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -msse4.2")
elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64"))
# segmentation fault in libcontext
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-gcse")
endif() endif()
if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)) if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
......
// libcontext - a slightly more portable version of boost::context /*
// Copyright Martin Husemann 2013.
// Copyright Oliver Kowalke 2009. auto-generated file, do not modify!
// Copyright Sergue E. Leontiev 2013. libcontext - a slightly more portable version of boost::context
// Copyright Thomas Sailer 2013. Copyright Martin Husemann 2013.
// Minor modifications by Tomasz Wlostowski 2016. Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0. Copyright Sergue E. Leontiev 2013
// (See accompanying file LICENSE_1_0.txt or copy at Copyright Thomas Sailer 2013.
// http://www.boost.org/LICENSE_1_0.txt) Minor modifications by Tomasz Wlostowski 2016.
#include "bthread/context.h"
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#include "bthread/context.h"
#if defined(BTHREAD_CONTEXT_PLATFORM_windows_i386) && defined(BTHREAD_CONTEXT_COMPILER_gcc) #if defined(BTHREAD_CONTEXT_PLATFORM_windows_i386) && defined(BTHREAD_CONTEXT_COMPILER_gcc)
__asm ( __asm (
".text\n" ".text\n"
...@@ -562,7 +567,8 @@ __asm ( ...@@ -562,7 +567,8 @@ __asm (
" @ and as first arg in context function\n" " @ and as first arg in context function\n"
" mov a1, a3\n" " mov a1, a3\n"
" @ restore v1-V8,LR,PC\n" " @ restore v1-V8,LR,PC\n"
" pop {v1-v8,lr,pc}\n" " pop {v1-v8,lr}\n"
" pop {pc}\n"
".size bthread_jump_fcontext,.-bthread_jump_fcontext\n" ".size bthread_jump_fcontext,.-bthread_jump_fcontext\n"
"@ Mark that we don't need executable stack.\n" "@ Mark that we don't need executable stack.\n"
".section .note.GNU-stack,\"\",%progbits\n" ".section .note.GNU-stack,\"\",%progbits\n"
...@@ -600,3 +606,106 @@ __asm ( ...@@ -600,3 +606,106 @@ __asm (
); );
#endif #endif
#if defined(BTHREAD_CONTEXT_PLATFORM_linux_arm64) && defined(BTHREAD_CONTEXT_COMPILER_gcc)
__asm (
".cpu generic+fp+simd\n"
".text\n"
".align 2\n"
".global bthread_jump_fcontext\n"
".type bthread_jump_fcontext, %function\n"
"bthread_jump_fcontext:\n"
" # prepare stack for GP + FPU\n"
" sub sp, sp, #0xb0\n"
"# Because gcc may save integer registers in fp registers across a\n"
"# function call we cannot skip saving the fp registers.\n"
"#\n"
"# Do not reinstate this test unless you fully understand what you\n"
"# are doing.\n"
"#\n"
"# # test if fpu env should be preserved\n"
"# cmp w3, #0\n"
"# b.eq 1f\n"
" # save d8 - d15\n"
" stp d8, d9, [sp, #0x00]\n"
" stp d10, d11, [sp, #0x10]\n"
" stp d12, d13, [sp, #0x20]\n"
" stp d14, d15, [sp, #0x30]\n"
"1:\n"
" # save x19-x30\n"
" stp x19, x20, [sp, #0x40]\n"
" stp x21, x22, [sp, #0x50]\n"
" stp x23, x24, [sp, #0x60]\n"
" stp x25, x26, [sp, #0x70]\n"
" stp x27, x28, [sp, #0x80]\n"
" stp x29, x30, [sp, #0x90]\n"
" # save LR as PC\n"
" str x30, [sp, #0xa0]\n"
" # store RSP (pointing to context-data) in first argument (x0).\n"
" # STR cannot have sp as a target register\n"
" mov x4, sp\n"
" str x4, [x0]\n"
" # restore RSP (pointing to context-data) from A2 (x1)\n"
" mov sp, x1\n"
"# # test if fpu env should be preserved\n"
"# cmp w3, #0\n"
"# b.eq 2f\n"
" # load d8 - d15\n"
" ldp d8, d9, [sp, #0x00]\n"
" ldp d10, d11, [sp, #0x10]\n"
" ldp d12, d13, [sp, #0x20]\n"
" ldp d14, d15, [sp, #0x30]\n"
"2:\n"
" # load x19-x30\n"
" ldp x19, x20, [sp, #0x40]\n"
" ldp x21, x22, [sp, #0x50]\n"
" ldp x23, x24, [sp, #0x60]\n"
" ldp x25, x26, [sp, #0x70]\n"
" ldp x27, x28, [sp, #0x80]\n"
" ldp x29, x30, [sp, #0x90]\n"
" # use third arg as return value after jump\n"
" # and as first arg in context function\n"
" mov x0, x2\n"
" # load pc\n"
" ldr x4, [sp, #0xa0]\n"
" # restore stack from GP + FPU\n"
" add sp, sp, #0xb0\n"
" ret x4\n"
".size bthread_jump_fcontext,.-bthread_jump_fcontext\n"
"# Mark that we don't need executable stack.\n"
".section .note.GNU-stack,\"\",%progbits\n"
);
#endif
#if defined(BTHREAD_CONTEXT_PLATFORM_linux_arm64) && defined(BTHREAD_CONTEXT_COMPILER_gcc)
__asm (
".cpu generic+fp+simd\n"
".text\n"
".align 2\n"
".global bthread_make_fcontext\n"
".type bthread_make_fcontext, %function\n"
"bthread_make_fcontext:\n"
" # shift address in x0 (allocated stack) to lower 16 byte boundary\n"
" and x0, x0, ~0xF\n"
" # reserve space for context-data on context-stack\n"
" sub x0, x0, #0xb0\n"
" # third arg of bthread_make_fcontext() == address of context-function\n"
" # store address as a PC to jump in\n"
" str x2, [x0, #0xa0]\n"
" # save address of finish as return-address for context-function\n"
" # will be entered after context-function returns (LR register)\n"
" adr x1, finish\n"
" str x1, [x0, #0x98]\n"
" ret x30 \n"
"finish:\n"
" # exit code is zero\n"
" mov x0, #0\n"
" # exit application\n"
" bl _exit\n"
".size bthread_make_fcontext,.-bthread_make_fcontext\n"
"# Mark that we don't need executable stack.\n"
".section .note.GNU-stack,\"\",%progbits\n"
);
#endif
// libcontext - a slightly more portable version of boost::context /*
// Copyright Martin Husemann 2013.
// Copyright Oliver Kowalke 2009. libcontext - a slightly more portable version of boost::context
// Copyright Sergue E. Leontiev 2013.
// Copyright Thomas Sailer 2013. Copyright Martin Husemann 2013.
// Minor modifications by Tomasz Wlostowski 2016. Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0. Copyright Sergue E. Leontiev 2013.
// (See accompanying file LICENSE_1_0.txt or copy at Copyright Thomas Sailer 2013.
// http://www.boost.org/LICENSE_1_0.txt) Minor modifications by Tomasz Wlostowski 2016.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BTHREAD_CONTEXT_H #ifndef BTHREAD_CONTEXT_H
#define BTHREAD_CONTEXT_H #define BTHREAD_CONTEXT_H
...@@ -30,6 +36,9 @@ ...@@ -30,6 +36,9 @@
#elif __arm__ #elif __arm__
#define BTHREAD_CONTEXT_PLATFORM_linux_arm32 #define BTHREAD_CONTEXT_PLATFORM_linux_arm32
#define BTHREAD_CONTEXT_CALL_CONVENTION #define BTHREAD_CONTEXT_CALL_CONVENTION
#elif __aarch64__
#define BTHREAD_CONTEXT_PLATFORM_linux_arm64
#define BTHREAD_CONTEXT_CALL_CONVENTION
#endif #endif
#elif defined(__MINGW32__) || defined (__MINGW64__) #elif defined(__MINGW32__) || defined (__MINGW64__)
......
...@@ -23,9 +23,15 @@ ...@@ -23,9 +23,15 @@
#ifndef BTHREAD_PROCESSOR_H #ifndef BTHREAD_PROCESSOR_H
#define BTHREAD_PROCESSOR_H #define BTHREAD_PROCESSOR_H
#include "butil/build_config.h"
// Pause instruction to prevent excess processor bus usage, only works in GCC // Pause instruction to prevent excess processor bus usage, only works in GCC
# ifndef cpu_relax # ifndef cpu_relax
#if defined(ARCH_CPU_ARM_FAMILY)
# define cpu_relax() asm volatile("yield\n": : :"memory")
#else
# define cpu_relax() asm volatile("pause\n": : :"memory") # define cpu_relax() asm volatile("pause\n": : :"memory")
#endif
# endif # endif
// Compile read-write barrier // Compile read-write barrier
......
...@@ -132,7 +132,7 @@ static inline int FindMatchLength(const char* s1, ...@@ -132,7 +132,7 @@ static inline int FindMatchLength(const char* s1,
matched += 4; matched += 4;
} }
if (LittleEndian::IsLittleEndian() && s2 <= s2_limit - 4) { if (LittleEndian::IsLittleEndian() && s2 <= s2_limit - 4) {
uint32 x = UNALIGNED_LOAD32(s2) ^ UNALIGNED_LOAD32(s1 + matched); uint32_t x = UNALIGNED_LOAD32(s2) ^ UNALIGNED_LOAD32(s1 + matched);
int matching_bits = Bits::FindLSBSetNonZero(x); int matching_bits = Bits::FindLSBSetNonZero(x);
matched += matching_bits >> 3; matched += matching_bits >> 3;
} else { } else {
......
...@@ -114,13 +114,13 @@ namespace snappy { ...@@ -114,13 +114,13 @@ namespace snappy {
// See if that would be more efficient on platforms supporting it, // See if that would be more efficient on platforms supporting it,
// at least for copies. // at least for copies.
inline uint64_tUNALIGNED_LOAD64(const void *p) { inline uint64_t UNALIGNED_LOAD64(const void *p) {
uint64_tt; uint64_t t;
memcpy(&t, p, sizeof t); memcpy(&t, p, sizeof t);
return t; return t;
} }
inline void UNALIGNED_STORE64(void *p, uint64_tv) { inline void UNALIGNED_STORE64(void *p, uint64_t v) {
memcpy(p, &v, sizeof v); memcpy(p, &v, sizeof v);
} }
...@@ -141,8 +141,8 @@ inline uint32_t UNALIGNED_LOAD32(const void *p) { ...@@ -141,8 +141,8 @@ inline uint32_t UNALIGNED_LOAD32(const void *p) {
return t; return t;
} }
inline uint64_tUNALIGNED_LOAD64(const void *p) { inline uint64_t UNALIGNED_LOAD64(const void *p) {
uint64_tt; uint64_t t;
memcpy(&t, p, sizeof t); memcpy(&t, p, sizeof t);
return t; return t;
} }
...@@ -155,7 +155,7 @@ inline void UNALIGNED_STORE32(void *p, uint32_t v) { ...@@ -155,7 +155,7 @@ inline void UNALIGNED_STORE32(void *p, uint32_t v) {
memcpy(p, &v, sizeof v); memcpy(p, &v, sizeof v);
} }
inline void UNALIGNED_STORE64(void *p, uint64_tv) { inline void UNALIGNED_STORE64(void *p, uint64_t v) {
memcpy(p, &v, sizeof v); memcpy(p, &v, sizeof v);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment