feat/support_fiber #1

Closed
tqcq wants to merge 0 commits from feat/support_fiber into master
811 changed files with 108333 additions and 78618 deletions

View File

@ -1,78 +0,0 @@
# Generated from CLion C/C++ Code Style settings
BinPackParameters: false
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignArrayOfStructures: Left
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignOperands: DontAlign
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
# 函数和返回类型分两行,方便阅读
AlwaysBreakAfterReturnType: TopLevelDefinitions
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
BreakInheritanceList: BeforeColon
ColumnLimit: 120
CompactNamespaces: false
ContinuationIndentWidth: 4
EmptyLineBeforeAccessModifier: LogicalBlock
SeparateDefinitionBlocks: Always
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PointerAlignment: Right
ReflowComments: false
SortIncludes: CaseSensitive
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
PenaltyIndentedWhitespace: 1

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
*.gz filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text

View File

@ -23,9 +23,6 @@ concurrency:
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
build_arch: ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
env:
TILE_CMAKE_OPTIONS: |
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake \
@ -34,17 +31,38 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DNCNN_VULKAN=ON \
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: install-tools
run: |
apt-get update -y
apt-get install -y ninja-build
- name: build
- name: armeabi-v7a
run: |
mkdir build && cd build
cmake -GNinja .. ${{ env.TILE_CMAKE_OPTIONS}} -DCMAKE_ABI="${{matrix.build_arch}}" -DANDROID_ARM_NEON=ON
mkdir build-armeabi-v7a && cd build-armeabi-v7a
cmake .. ${{ env.TILE_CMAKE_OPTIONS}} -DCMAKE_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON
cmake --build . -j $(nproc)
- name: arm64-v8a
run: |
mkdir build-arm64-v8a && cd build-arm64-v8a
cmake .. ${{ env.TILE_CMAKE_OPTIONS}} -DCMAKE_ABI="arm64-v8a"
cmake --build . -j $(nproc)
- name: x86
run: |
mkdir build-x86 && cd build-x86
cmake .. ${{ env.TILE_CMAKE_OPTIONS}} -DCMAKE_ABI="x86"
cmake --build . -j $(nproc)
- name: x86_64
run: |
mkdir build-x86_64 && cd build-x86_64
cmake .. ${{ env.TILE_CMAKE_OPTIONS}} -DCMAKE_ABI="x86_64"
cmake --build . -j $(nproc)

View File

@ -40,19 +40,18 @@ jobs:
submodules: recursive
- name: install-tools
run: |
echo "H4sIANpBXGYCA72SX0vCUByG7/0UB7x2u+/bzG3lyP3h/Am608zU0rbAxEiopEQSZlDI3JK+zM7ZzlVfoQMjL4IgV3Z3OBx+z+95z1sEPBqm/j17nvLWaRyesNBLbuv8ckQbbhw9MNfjsyFQHAyIoylYB7x2Q8PJ+2uXTo7YqMNHtXRSp+48bT2md13qDtiinU0raHoZVDB20I4smwaENkQSJpYiYWRYexWiSLpGJNWSSZlYmMhg11aVKjAVwwJQRxgaKtY1QCzjQIdIByap4uxYKAIxvISgui1Avt1LWUho6w4bgXK6lBV137Eh/gebzVCCJaoZB2fU79DmlF2/sMFTuprH0ULUl3ab1JuJKlN/yAZLcRMH51mhk9kVb/aSlf9dfeM3n/WXWX1pu8V643V4QgjpKoEGPpSy5SXVNr94fL7IkdjfzxcAPj6m7gUNGut0hHkc9GgUpr5PvXnSn2Z75Pk1B9qOjQT9Z7a/ashGrMIHpPjh/tcEAAA=" | base64 -d | gzip -d | sudo tee /etc/apt/sources.list
sudo apt-get remove --purge man-db
sudo apt-get update -y
sudo apt-get install -y g++-aarch64-linux-gnu qemu-user-binfmt ninja-build
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
sudo apt-get install -y g++-aarch64-linux-gnu qemu-user-binfmt
- name: build
run: |
cd build
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
cmake --build . -j $(nproc)
- name: test
run: |-
cd build
sudo ln -sf /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1
export LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib
ctest --output-on-failure -j $(nproc)
ctest --output-on-failure -j$(nproc) --timeout 180

View File

@ -38,15 +38,14 @@ jobs:
- uses: actions/checkout@v4
- name: install-tools
run: |
echo "H4sIANpBXGYCA72SX0vCUByG7/0UB7x2u+/bzG3lyP3h/Am608zU0rbAxEiopEQSZlDI3JK+zM7ZzlVfoQMjL4IgV3Z3OBx+z+95z1sEPBqm/j17nvLWaRyesNBLbuv8ckQbbhw9MNfjsyFQHAyIoylYB7x2Q8PJ+2uXTo7YqMNHtXRSp+48bT2md13qDtiinU0raHoZVDB20I4smwaENkQSJpYiYWRYexWiSLpGJNWSSZlYmMhg11aVKjAVwwJQRxgaKtY1QCzjQIdIByap4uxYKAIxvISgui1Avt1LWUho6w4bgXK6lBV137Eh/gebzVCCJaoZB2fU79DmlF2/sMFTuprH0ULUl3ab1JuJKlN/yAZLcRMH51mhk9kVb/aSlf9dfeM3n/WXWX1pu8V643V4QgjpKoEGPpSy5SXVNr94fL7IkdjfzxcAPj6m7gUNGut0hHkc9GgUpr5PvXnSn2Z75Pk1B9qOjQT9Z7a/ashGrMIHpPjh/tcEAAA=" | base64 -d | gzip -d | sudo tee /etc/apt/sources.list
sudo apt-get remove --purge man-db
sudo apt-get update -y
sudo apt-get install -y g++-arm-linux-gnueabi qemu-user-binfmt ninja-build
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabi.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_TESTS=ON ..
sudo apt-get install -y g++-arm-linux-gnueabi qemu-user-binfmt
- name: build
run: |
cd build
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabi.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_TESTS=ON ..
cmake --build . -j $(nproc)
- name: test
run: |
@ -67,18 +66,15 @@ jobs:
- name: arm-gnu-toolchain
run: |
sudo apt-get update -y
sudo apt-get install -y g++-arm-linux-gnueabihf qemu-user-binfmt ninja-build
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabihf.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
sudo apt-get install -y cmake make g++-arm-linux-gnueabihf qemu-user-binfmt
- name: build
run: |
cd build
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabihf.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
cmake --build . -j $(nproc)
- name: test
run: |-
cd build
sudo ln -sf /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib/ld-linux-armhf.so.3
export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib/
ctest --output-on-failure -j $(nproc)
ctest --output-on-failure -j$(nproc) --timeout 180

View File

@ -37,17 +37,19 @@ jobs:
submodules: recursive
- name: install-tools
run: |
echo "H4sIANpBXGYCA72SX0vCUByG7/0UB7x2u+/bzG3lyP3h/Am608zU0rbAxEiopEQSZlDI3JK+zM7ZzlVfoQMjL4IgV3Z3OBx+z+95z1sEPBqm/j17nvLWaRyesNBLbuv8ckQbbhw9MNfjsyFQHAyIoylYB7x2Q8PJ+2uXTo7YqMNHtXRSp+48bT2md13qDtiinU0raHoZVDB20I4smwaENkQSJpYiYWRYexWiSLpGJNWSSZlYmMhg11aVKjAVwwJQRxgaKtY1QCzjQIdIByap4uxYKAIxvISgui1Avt1LWUho6w4bgXK6lBV137Eh/gebzVCCJaoZB2fU79DmlF2/sMFTuprH0ULUl3ab1JuJKlN/yAZLcRMH51mhk9kVb/aSlf9dfeM3n/WXWX1pu8V643V4QgjpKoEGPpSy5SXVNr94fL7IkdjfzxcAPj6m7gUNGut0hHkc9GgUpr5PvXnSn2Z75Pk1B9qOjQT9Z7a/ashGrMIHpPjh/tcEAAA=" | base64 -d | gzip -d | sudo tee /etc/apt/sources.list
sudo apt-get remove --purge man-db
sudo apt-get update -y
sudo apt-get install -y g++-mipsel-linux-gnu qemu-user-binfmt ninja-build
sudo apt-get install -y g++-mipsel-linux-gnu qemu-user-binfmt
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/mips-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/mips-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
- name: build
run: cmake --build build --target all -j $(nproc)
run: cmake --build build --target all -j `nproc`
- name: test
run: |-
cd build
sudo ln -sf /usr/mipsel-linux-gnu/lib/ld.so.1 /lib/ld.so.1
export LD_LIBRARY_PATH=/usr/mipsel-linux-gnu/lib/
ctest --output-on-failure -j $(nproc)
ctest --output-on-failure -j$(nproc) --timeout 180

View File

@ -38,17 +38,19 @@ jobs:
submodules: recursive
- name: install-tools
run: |
echo "H4sIANpBXGYCA72SX0vCUByG7/0UB7x2u+/bzG3lyP3h/Am608zU0rbAxEiopEQSZlDI3JK+zM7ZzlVfoQMjL4IgV3Z3OBx+z+95z1sEPBqm/j17nvLWaRyesNBLbuv8ckQbbhw9MNfjsyFQHAyIoylYB7x2Q8PJ+2uXTo7YqMNHtXRSp+48bT2md13qDtiinU0raHoZVDB20I4smwaENkQSJpYiYWRYexWiSLpGJNWSSZlYmMhg11aVKjAVwwJQRxgaKtY1QCzjQIdIByap4uxYKAIxvISgui1Avt1LWUho6w4bgXK6lBV137Eh/gebzVCCJaoZB2fU79DmlF2/sMFTuprH0ULUl3ab1JuJKlN/yAZLcRMH51mhk9kVb/aSlf9dfeM3n/WXWX1pu8V643V4QgjpKoEGPpSy5SXVNr94fL7IkdjfzxcAPj6m7gUNGut0hHkc9GgUpr5PvXnSn2Z75Pk1B9qOjQT9Z7a/ashGrMIHpPjh/tcEAAA=" | base64 -d | gzip -d | sudo tee /etc/apt/sources.list
sudo apt-get remove --purge man-db
sudo apt-get update -y
sudo apt-get install -y g++-mips64el-linux-gnuabi64 qemu-user-binfmt ninja-build
sudo apt-get install -y g++-mips64el-linux-gnuabi64 qemu-user-binfmt
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/mips64el-linux-gnuabi64.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/mips64el-linux-gnuabi64.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
- name: build
run: cmake --build build --target all -j $(nproc)
run: cmake --build build --target all -j `nproc`
- name: test
run: |-
cd build
sudo ln -sf /usr/mips64el-linux-gnuabi64/lib64/ld.so.1 /lib64/ld.so.1
export LD_LIBRARY_PATH=/usr/mips64el-linux-gnuabi64/lib
ctest --output-on-failure -j $(nproc)
ctest --output-on-failure -j$(nproc) --timeout 180

View File

@ -39,14 +39,16 @@ jobs:
submodules: recursive
- name: install-tools
run: |
echo "H4sIANpBXGYCA72SX0vCUByG7/0UB7x2u+/bzG3lyP3h/Am608zU0rbAxEiopEQSZlDI3JK+zM7ZzlVfoQMjL4IgV3Z3OBx+z+95z1sEPBqm/j17nvLWaRyesNBLbuv8ckQbbhw9MNfjsyFQHAyIoylYB7x2Q8PJ+2uXTo7YqMNHtXRSp+48bT2md13qDtiinU0raHoZVDB20I4smwaENkQSJpYiYWRYexWiSLpGJNWSSZlYmMhg11aVKjAVwwJQRxgaKtY1QCzjQIdIByap4uxYKAIxvISgui1Avt1LWUho6w4bgXK6lBV137Eh/gebzVCCJaoZB2fU79DmlF2/sMFTuprH0ULUl3ab1JuJKlN/yAZLcRMH51mhk9kVb/aSlf9dfeM3n/WXWX1pu8V643V4QgjpKoEGPpSy5SXVNr94fL7IkdjfzxcAPj6m7gUNGut0hHkc9GgUpr5PvXnSn2Z75Pk1B9qOjQT9Z7a/ashGrMIHpPjh/tcEAAA=" | base64 -d | gzip -d | sudo tee /etc/apt/sources.list
sudo apt-get remove --purge man-db
sudo apt-get update -y
sudo apt-get install -y g++-riscv64-linux-gnu qemu-user-binfmt ninja-build
sudo apt-get install -y g++-riscv64-linux-gnu qemu-user-binfmt
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/riscv64-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/riscv64-linux-gnu.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_TESTS=ON -DTILE_BUILD_BENCHMARKS=ON ..
- name: build
run: cmake --build build --target all -j $(nproc)
run: cmake --build build --target all -j `nproc`
- name: test
run: |-
cd build

View File

@ -29,24 +29,24 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: install-tools
run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build
# - name: install-tools
# run: |
# sudo apt-get update -y
# sudo apt-get install -y cmake make
- name: configure
env:
CC: clang
CXX: clang++
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
- name: build
run: |
cmake --build build -j $(nproc)
cmake --build build -j `nproc`
- name: test
run: |
cd build
ctest --output-on-failure
ctest --output-on-failure -j$(nproc)
# - name: benchmark
# run: |
# ./build/sled_benchmark

View File

@ -33,21 +33,21 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: install-tools
run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build
# - name: install-tools
# run: |
# sudo apt-get update -y
# sudo apt-get install -y cmake make
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
- name: build
run: |
cmake --build build -j $(nproc)
cmake --build build -j `nproc`
- name: test
run: |
cd build
ctest --output-on-failure -j$(nproc)
- name: benchmark
run: |
./build/bin/tile_bm_all
# - name: benchmark
# run: |
# ./build/sled_benchmark

View File

@ -38,18 +38,18 @@ jobs:
- name: install-tools
run: |
sudo apt-get update -y
sudo apt-get install -y gcc-multilib g++-multilib ninja-build
sudo apt-get install -y gcc-multilib g++-multilib
- name: configure
run: |
mkdir build && cd build
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=../toolchains/host.gcc-m32.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/host.gcc-m32.toolchain.cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DTILE_BUILD_BENCHMARKS=ON -DTILE_BUILD_TESTS=ON ..
- name: build
run: |
cmake --build build -j $(nproc)
cmake --build build -j `nproc`
- name: test
run: |
cd build
ctest --output-on-failure -j$(nproc)
- name: benchmark
run: |
./build/bin/tile_bm_all
# - name: benchmark
# run: |
# ./build/sled_benchmark

2
.gitignore vendored
View File

@ -2,5 +2,3 @@ out/
build/
.cache/
compile_commands.json
.gdb_history
.cmake.conf

0
.gitmodules vendored Normal file
View File

View File

@ -1,69 +1,56 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.12)
set(tile_VERSION_MAJOR 0)
set(tile_VERSION_MINOR 1)
set(tile_VERSION_PATCH 1)
set(tile_VERSION_BUILD $ENV{CI_STEP_NUMBER})
if(NOT tile_VERSION_BUILD)
set(tile_VERSION_BUILD "0")
endif()
set(TILE_VERSION
"${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}.${tile_VERSION_BUILD}"
)
set(tile_VERSION_PATCH 0)
project(
tile
VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}"
VERSION ${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}
LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
# add static libgcc and libstdc++ for static linking set(CMAKE_C_FLAGS
# "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++") set(CMAKE_CXX_FLAGS
# "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
option(TILE_BUILD_TESTS "Build tests" OFF)
option(TILE_BUILD_BENCHMARKS "Build tests" OFF)
option(TILE_WITH_OPENSSL "Build wih openssl" OFF)
option(TILE_WITH_OPENSSL "Build with openssl" OFF)
option(TILE_BUILD_SHARED "Build shared library" ON)
option(TILE_WITH_MIMALLOC "Build with mimalloc" OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
set(TILE_BUILD_TESTS ON)
set(TILE_BUILD_BENCHMARKS ON)
endif()
endif()
option(TILE_BUILD_STATIC "Build static library" ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_BUILD_TYPE "Debug")
endif()
# if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # set(CMAKE_CXX_FLAGS
# "${CMAKE_CXX_FLAGS} -gz") # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gz") #
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") set(CMAKE_C_FLAGS #
# "${CMAKE_CXX_FLAGS} -static") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} #
# -fsanitize=address ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address #
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") set(CMAKE_C_FLAGS
# "${CMAKE_CXX_FLAGS} -static") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}
# -fsanitize=address ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address
# ")
#
# set(WHOLE_ARCHIVE_PREFIX "-Wl,-force_load") # set(NO_WHOLE_ARCHIVE_PREFIX "")
# elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") # set(CMAKE_CXX_FLAGS
# "${CMAKE_CXX_FLAGS} -gz") # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gz") #
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") set(CMAKE_C_FLAGS #
set(WHOLE_ARCHIVE_PREFIX "-Wl,-force_load")
# set(NO_WHOLE_ARCHIVE_PREFIX "")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") set(CMAKE_C_FLAGS
# "${CMAKE_CXX_FLAGS} -static")
#
# set(WHOLE_ARCHIVE_PREFIX "-Wl,-force_load,") # set(NO_WHOLE_ARCHIVE_PREFIX "")
# elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS
# "${CMAKE_CXX_FLAGS} -gz") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gz") #
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") #
# set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
#
# set(STATIC_BINARY_FLAGS "-static-libgcc -static-libstdc++")
# set(WHOLE_ARCHIVE_PREFIX "-Wl,--whole-archive") set(WHOLE_ARCHIVE_SUFFIX
# "-Wl,--no-whole-archive") endif()
set(WHOLE_ARCHIVE_PREFIX "-Wl,-force_load,")
# set(NO_WHOLE_ARCHIVE_PREFIX "")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
set(WHOLE_ARCHIVE_PREFIX "-Wl,--whole-archive")
set(WHOLE_ARCHIVE_SUFFIX "-Wl,--no-whole-archive")
endif()
find_package(Threads REQUIRED)
# extern int getifaddrs(struct ifaddrs **ifap); extern void freeifaddrs(struct
# ifaddrs *ifa);
@ -73,31 +60,24 @@ include(cmake/BuildInfo.cmake)
check_symbol_exists("getifaddrs" "ifaddrs.h" TILE_HAVE_GETIFADDRS)
check_symbol_exists("freeifaddrs" "ifaddrs.h" TILE_HAVE_FREEIFADDRS)
# find_package(Git REQUIRED)
#
# get_git_commit_hash(GIT_COMMIT_HASH) get_git_commit_date(GIT_COMMIT_DATE)
# get_git_commit_subject(GIT_COMMIT_SUBJECT)
get_git_commit_hash(GIT_COMMIT_HASH)
get_git_commit_date(GIT_COMMIT_DATE)
get_git_commit_subject(GIT_COMMIT_SUBJECT)
set(THIRD_PARTY_INCLUDE_DIRS # "third_party/json" "third_party/inja"
"third_party/sigslot"
"${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include")
include_directories(${THIRD_PARTY_INCLUDE_DIRS})
include_directories("third_party/json" "third_party/inja" "third_party/sigslot")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include")
add_subdirectory("third_party/context")
add_subdirectory("third_party/zlib")
if(TILE_WITH_MIMALLOC)
add_subdirectory("third_party/mimalloc")
endif()
add_subdirectory("third_party/jsoncpp")
add_subdirectory("third_party/fmt")
add_subdirectory("third_party/googletest")
set(INTTYPES_FORMAT "C99")
add_subdirectory("third_party/gflags")
set(GFLAGS_USE_TARGET_NAMESPACE ON)
set(gflags_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags")
# add_subdirectory("third_party/context")
add_subdirectory("third_party/glog")
set(CURL_DISABLE_TESTS ON)
set(CURL_CA_PATH
"none"
CACHE STRING "" FORCE)
set(CURL_ENABLE_SSL
OFF
CACHE BOOL "" FORCE)
@ -156,7 +136,6 @@ set(TILE_SRCS
"tile/base/encoding/detail/hex_chars.cc"
"tile/base/encoding/hex.cc"
"tile/base/encoding/percent.cc"
"tile/base/exposed_var.cc"
"tile/base/internal/background_task_host.cc"
"tile/base/internal/background_task_host.h"
"tile/base/internal/case_insensitive_hash_map.h"
@ -169,9 +148,6 @@ set(TILE_SRCS
"tile/base/internal/thread_pool.cc"
"tile/base/internal/time_keeper.cc"
"tile/base/internal/time_keeper.h"
"tile/base/logging/basic_file_sink.cc"
"tile/base/logging/splitter_sink.cc"
"tile/base/logging/console_sink.cc"
"tile/base/net/endpoint.cc"
"tile/base/object_pool/disabled.cc"
"tile/base/object_pool/global.cc"
@ -191,12 +167,10 @@ set(TILE_SRCS
"tile/base/thread/rw_mutex.cc"
"tile/base/thread/scoped_lock.cc"
"tile/base/thread/spinlock.cc"
"tile/base/memory_barrier.cc"
# "tile/fiber/detail/fiber.cc"
"tile/fiber/detail/fiber.cc"
"tile/io/detail/eintr_safe.cc"
"tile/io/native/acceptor.cc"
"tile/io/descriptor.cc"
"tile/io/util/rate_limiter.cc"
"tile/io/event_loop.cc"
"tile/init.cc"
"tile/init/on_init.cc"
@ -213,59 +187,37 @@ set(TILE_SRCS
"tile/rpc/protocol/http/buffer_io.cc"
"tile/rpc/protocol/message.cc"
# "tile/rpc/server.cc"
"tile/base/config/configuration.cc"
"tile/base/config/ini_file_configuration.cc"
"tile/base/config/json_configuration.cc"
"tile/base/config/layered_configuration.cc"
"tile/base/config/toml_configuration.cc"
"tile/system/os.cc")
)
if((NOT TILE_HAVE_GETIFADDRS) OR (NOT TILE_HAVE_FREEIFADDRS))
list(APPEND TILE_SRCS "tile/base/net/detail/android/ifaddrs.c")
endif()
if(TILE_BUILD_SHARED)
add_library(tile SHARED ${TILE_SRCS})
else()
add_library(tile STATIC ${TILE_SRCS})
endif()
add_library(tile OBJECT ${TILE_SRCS})
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
target_precompile_headers(
tile
PUBLIC
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/third_party/header_only/toml.hpp>"
# ${CMAKE_CURRENT_SOURCE_DIR}/third_party/json/nlohann/json.hpp
# ${CMAKE_CURRENT_SOURCE_DIR}/third_party/inja/inja/string_view.h
# ${CMAKE_CURRENT_SOURCE_DIR}/third_party/inja/inja/inja.h
)
SOVERSION "${tile_VERSION_MAJRO}")
# target_sources(tile PRIVATE ${TILE_SRCS})
target_include_directories(
tile
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/third_party/mustache.hpp"
"${CMAKE_CURRENT_BINARY_DIR}"
PUBLIC "${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
# "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
# "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
"${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
"${CMAKE_CURRENT_SOURCE_DIR}"
${THIRD_PARTY_INCLUDE_DIRS}
RPIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/header_only/"
"${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include")
if(TILE_WITH_MIMALLOC)
target_link_libraries(tile PUBLIC mimalloc-obj)
endif()
target_link_libraries(
tile
PUBLIC # -Wl,--start-group nova_context
PUBLIC # -Wl,--start-group
nova_context
zlib
gflags::gflags # glog::glog
jsoncpp_static
gflags::gflags
glog::glog
# -Wl,--end-group
libcurl
fmt)
fmt
Threads::Threads)
if((CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES
"mips*"))
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@ -300,46 +252,88 @@ if(TILE_BUILD_TESTS)
add_executable(tile_test_all "tile/testing/main.cc")
target_link_libraries(tile_test_all PRIVATE gtest gmock tile::tile)
macro(tile_add_custom_test test_name test_file)
macro(tile_add_test test_name test_file)
add_executable(${test_name} ${test_file} "tile/testing/main.cc")
target_link_libraries(
${test_name} PUBLIC gtest gmock ${WHOLE_ARCHIVE_PREFIX} tile::tile
${WHOLE_ARCHIVE_SUFFIX})
add_test(NAME ${test_name} COMMAND ${test_name})
target_sources(${PROJECT_NAME}_test_all PRIVATE ${test_file})
endmacro()
macro(tile_add_test test_name test_file)
tile_add_custom_test(${test_name} ${test_file})
add_test(NAME ${test_name} COMMAND ${test_name})
endmacro()
tile_add_test(fiber_detail_fiber_test "tile/fiber/detail/fiber_test.cc")
function(add_test_group prefix group_name)
file(GLOB_RECURSE TEST_FILES "${prefix}/**/*_test.cc" "${prefix}/*_test.cc")
foreach(SRC_FILE ${TEST_FILES})
if(IS_DIRECTORY ${SRC_FILE})
continue()
endif()
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
string(REPLACE "_test.cc" "_test" TEST_NAME "${TEST_NAME}")
# if group_name is not empty, add suffix _
if(NOT group_name STREQUAL "")
set(TEST_NAME "${group_name}_${TEST_NAME}")
endif()
tile_add_test(base_internal_meta_test "tile/base/internal/meta_test.cc")
# tile_add_test(net_internal_http_engine_test
# "tile/net/internal/http_engine_test.cc")
tile_add_test(net_internal_http_task_test
"tile/net/internal/http_task_test.cc")
tile_add_test(net_http_http_client_test "tile/net/http/http_client_test.cc")
tile_add_test(net_http_http_request_test "tile/net/http/http_reqeust_test.cc")
tile_add_test(net_http_http_response_test
"tile/net/http/http_response_test.cc")
tile_add_test(base_compression_util_test "tile/base/compression/util_test.cc")
tile_add_test(rpc_protocol_http_buffer_io_test
"tile/rpc/protocol/http/buffer_io_test.cc")
tile_add_test(${TEST_NAME} ${SRC_FILE})
endforeach()
endfunction(add_test_group)
tile_add_test(base_compression_test "tile/base/compression_test.cc")
tile_add_test(base_casting_test "tile/base/casting_test.cc")
tile_add_test(base_future_future_test "tile/base/future/future_test.cc")
tile_add_test(base_future_boxed_test "tile/base/future/boxed_test.cc")
tile_add_test(base_option_option_service_test
"tile/base/option/option_service_test.cc")
tile_add_test(base_ref_ptr_test "tile/base/ref_ptr_test.cc")
tile_add_test(base_object_pool_disabled_test
"tile/base/object_pool/disabled_test.cc")
tile_add_test(base_object_pool_types_test
"tile/base/object_pool/types_test.cc")
tile_add_test(base_string_test "tile/base/string_test.cc")
tile_add_test(base_deferred_test "tile/base/deferred_test.cc")
tile_add_test(base_internal_singly_linked_list_test
"tile/base/internal/singly_linked_list_test.cc")
tile_add_test(base_internal_move_on_copy_test
"tile/base/internal/move_on_copy_test.cc")
tile_add_test(base_internal_thread_pool_test
"tile/base/internal/thread_pool_test.cc")
tile_add_test(base_internal_format_test "tile/base/internal/format_test.cc")
tile_add_test(base_internal_background_task_host_test
"tile/base/internal/background_task_host_test.cc")
tile_add_test(base_down_cast_test "tile/base/down_cast_test.cc")
tile_add_test(base_encoding_hex_test "tile/base/encoding/hex_test.cc")
tile_add_test(base_encoding_percent_test "tile/base/encoding/percent_test.cc")
tile_add_test(base_encoding_base64_test "tile/base/encoding/base64_test.cc")
tile_add_test(base_internal_case_insensitive_hash_map_test
"tile/base/internal/case_insensitive_hash_map_test.cc")
tile_add_test(net_http_http_headers_test "tile/net/http/http_headers_test.cc")
tile_add_test(base_demangle_test "tile/base/demangle_test.cc")
tile_add_test(base_option_json_parser_test
"tile/base/option/json_parser_test.cc")
tile_add_test(base_option_key_test "tile/base/option/key_test.cc")
tile_add_test(base_dependency_registry_test
"tile/base/dependency_registry_test.cc")
tile_add_test(base_maybe_owning_test "tile/base/maybe_owning_test.cc")
tile_add_test(base_status_test "tile/base/status_test.cc")
tile_add_test(base_net_endpoint_test "tile/base/net/endpoint_test.cc")
tile_add_test(base_handle_test "tile/base/handle_test.cc")
tile_add_test(base_thread_scoped_lock_test
"tile/base/thread/scoped_lock_test.cc")
tile_add_test(base_thread_spinlock_test "tile/base/thread/spinlock_test.cc")
tile_add_test(base_thread_unique_lock_test
"tile/base/thread/unique_lock_test.cc")
tile_add_test(base_thread_cond_var_test "tile/base/thread/cond_var_test.cc")
tile_add_test(base_thread_latch_test "tile/base/thread/latch_test.cc")
# tile_add_test(fiber_ucontext_test "tile/fiber/ucontext_test.cc")
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/system system)
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/base base)
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/init init)
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/io io)
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/net net)
add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/rpc rpc)
tile_add_custom_test("custom_http_client_test" "tests/http_client_test.cc")
tile_add_test(init_on_init_test "tile/init/on_init_test.cc")
tile_add_test(base_buffer_test "tile/base/buffer_test.cc")
tile_add_test(base_object_pool_thread_local_test
"tile/base/object_pool/thread_local_test.cc")
tile_add_test(base_internal_logging_test "tile/base/internal/logging_test.cc")
tile_add_test(base_chrono_test "tile/base/chrono_test.cc")
tile_add_test(init_override_flag_test "tile/init/override_flag_test.cc")
# tile_add_test(base_internal_time_keeper_test
# "tile/base/internal/time_keeper_test.cc")
endif(TILE_BUILD_TESTS)
if(TILE_BUILD_BENCHMARKS)
@ -357,9 +351,8 @@ if(TILE_BUILD_BENCHMARKS)
target_sources(tile_bm_all PRIVATE ${benchmark_file})
endmacro()
# tile_add_bm(fiber_detail_fiber_benchmark
# "tile/fiber/detail/fiber_benchmark.cc")
tile_add_bm(base_buffer_benchmark "tile/base/buffer_benchmark.cc")
tile_add_bm(fiber_detail_fiber_benchmark
"tile/fiber/detail/fiber_benchmark.cc")
tile_add_bm(base_casting_benchmark "tile/base/casting_benchmark.cc")
tile_add_bm(base_thread_mutex_benchmark "tile/base/thread/mutex_benchmark.cc")
tile_add_bm(base_encoding_benchmark "tile/base/encoding_benchmark.cc")

View File

@ -1,3 +0,0 @@
## TILE
一个`C++11`工具库,集成常见的编码工具

View File

@ -1,3 +1,5 @@
find_package(Git REQUIRED)
macro(get_git_commit_hash output)
# full commit hash
execute_process(

View File

@ -3,11 +3,12 @@ custom_data_source: {
base_data_source: "compileunits"
rewrite: {
pattern: "^(.*/)(third_party/\\w+)"
pattern: "^(.*/tile/)(third_party/\\w+)"
replacement: "\\2"
}
rewrite: {
pattern: "^(.*/)(3party/\\w+)"
pattern: "^(.*/tile/)((\\w+/)+)"
replacement: "\\2"
}
}

View File

@ -1,85 +0,0 @@
#include "tile/net/http/http_client.h"
#include "gtest/gtest.h"
#include "tile/base/thread/latch.h"
const std::string url = "http://127.0.0.1:8000/";
TEST(HttpClient, Request) {
tile::HttpClient client;
std::vector<tile::Future<
std::expected<tile::HttpResponse, tile::HttpClient::ErrorCode>>>
v;
tile::HttpClient::RequestOptions options;
options.timeout = std::chrono::seconds(20);
std::atomic<int> count{0};
for (int i = 0; i != 1000; ++i) {
for (auto code : tile::AllHttpStatus) {
if (static_cast<int>(code) < 200) {
continue;
}
v.emplace_back(
client.AsyncGet(url + std::to_string(static_cast<int>(code)), options)
.Then([&](std::expected<tile::HttpResponse,
tile::HttpClient::ErrorCode> &&res) {
int cnt = count.fetch_add(1) + 1;
TILE_LOG_INFO_EVERY_SECOND("complete {}", cnt);
return res;
}));
}
}
int j = 0;
for (int i = 0; i != 1000; ++i) {
for (auto &code : tile::AllHttpStatus) {
if (static_cast<int>(code) < 200) {
continue;
}
auto resp = tile::future::BlockingGet(std::move(v[j++]));
EXPECT_TRUE(resp) << tile::HttpClient::ErrorCodeToString(resp.error());
EXPECT_EQ(resp->status(), code);
}
}
}
TEST(HttpClient, RequestNoWait) {
tile::HttpClient client;
tile::HttpClient::RequestOptions options;
options.timeout = std::chrono::seconds(20);
int cnt = 0;
for (int i = 0; i != 1000; ++i) {
for (auto code : tile::AllHttpStatus) {
if (static_cast<int>(code) < 200) {
continue;
}
++cnt;
}
}
tile::Latch latch(cnt);
std::atomic<int> count{0};
for (int i = 0; i != 1000; ++i) {
for (auto code : tile::AllHttpStatus) {
if (static_cast<int>(code) < 200) {
continue;
}
client.AsyncGet(url + std::to_string(static_cast<int>(code)), options)
.Then([&](std::expected<tile::HttpResponse,
tile::HttpClient::ErrorCode> &&) {
int cnt = count.fetch_add(1) + 1;
TILE_LOG_INFO_EVERY_SECOND("complete {}", cnt);
latch.CountDown();
});
}
}
latch.Wait();
}

View File

@ -1,24 +0,0 @@
#!/usr/bin/python3
import http.server
import socket
import socketserver
from http.server import HTTPServer, BaseHTTPRequestHandler
PORT = 8000
class Request(BaseHTTPRequestHandler):
def do_GET(self):
code = int(self.path.split("/")[1])
self.send_response(code)
self.send_header('Content-type', 'text/plain')
self.end_headers()
class HTTPServer(socketserver.TCPServer):
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
Handler = http.server.SimpleHTTPRequestHandler
with HTTPServer(("", PORT), Request) as httpd:
httpd.serve_forever()

View File

@ -1,3 +0,0 @@
# Library
- [toml11](https://github.com/ToruNiina/toml11/archive/refs/tags/v4.2.0.tar.gz)

View File

@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**System**
Which OS, compiler, and compiler version are you using:
- OS:
- Compiler and version:
**To reproduce**
Steps to reproduce the behavior:
1. sync to commit ...
2. cmake/bazel...
3. make ...
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FR]"
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,12 @@
if ! bazel version; then
arch=$(uname -m)
if [ "$arch" == "aarch64" ]; then
arch="arm64"
fi
echo "Downloading $arch Bazel binary from GitHub releases."
curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/7.1.1/bazel-7.1.1-linux-$arch"
chmod +x $HOME/bin/bazel
else
# Bazel is installed for the correct architecture
exit 0
fi

26
third_party/benchmark/.github/libcxx-setup.sh vendored Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
# Checkout LLVM sources
git clone --depth=1 --branch llvmorg-16.0.6 https://github.com/llvm/llvm-project.git llvm-project
## Setup libc++ options
if [ -z "$BUILD_32_BITS" ]; then
export BUILD_32_BITS=OFF && echo disabling 32 bit build
fi
## Build and install libc++ (Use unstable ABI for better sanitizer coverage)
mkdir llvm-build && cd llvm-build
cmake -DCMAKE_C_COMPILER=${CC} \
-DCMAKE_CXX_COMPILER=${CXX} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX=/usr \
-DLIBCXX_ABI_UNSTABLE=OFF \
-DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \
-DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \
-DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi;libunwind' \
-G "Unix Makefiles" \
../llvm-project/runtimes/
make -j cxx cxxabi unwind
cd ..

View File

@ -0,0 +1,35 @@
name: bazel
on:
push: {}
pull_request: {}
jobs:
build_and_test_default:
name: bazel.${{ matrix.os }}.${{ matrix.bzlmod && 'bzlmod' || 'no_bzlmod' }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
bzlmod: [false, true]
steps:
- uses: actions/checkout@v4
- name: mount bazel cache
uses: actions/cache@v3
env:
cache-name: bazel-cache
with:
path: "~/.cache/bazel"
key: ${{ env.cache-name }}-${{ matrix.os }}-${{ github.ref }}
restore-keys: |
${{ env.cache-name }}-${{ matrix.os }}-main
- name: build
run: |
bazel build ${{ matrix.bzlmod && '--enable_bzlmod' || '--noenable_bzlmod' }} //:benchmark //:benchmark_main //test/...
- name: test
run: |
bazel test ${{ matrix.bzlmod && '--enable_bzlmod' || '--noenable_bzlmod' }} --test_output=all //test/...

View File

@ -0,0 +1,46 @@
name: build-and-test-min-cmake
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
job:
name: ${{ matrix.os }}.min-cmake
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.10.0
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: setup cmake initial cache
run: touch compiler-cache.cmake
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake -C ${{ github.workspace }}/compiler-cache.cmake
$GITHUB_WORKSPACE
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_CXX_VISIBILITY_PRESET=hidden
-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build .

View File

@ -0,0 +1,51 @@
name: build-and-test-perfcounters
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
job:
# TODO(dominic): Extend this to include compiler and set through env: CC/CXX.
name: ${{ matrix.os }}.${{ matrix.build_type }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
build_type: ['Release', 'Debug']
steps:
- uses: actions/checkout@v3
- name: install libpfm
run: |
sudo apt update
sudo apt -y install libpfm4-dev
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_LIBPFM=1
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build . --config ${{ matrix.build_type }}
# Skip testing, for now. It seems perf_event_open does not succeed on the
# hosting machine, very likely a permissions issue.
# TODO(mtrofin): Enable test.
# - name: test
# shell: bash
# working-directory: ${{ runner.workspace }}/_build
# run: ctest -C ${{ matrix.build_type }} --rerun-failed --output-on-failure

View File

@ -0,0 +1,161 @@
name: build-and-test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
# TODO: add 32-bit builds (g++ and clang++) for ubuntu
# (requires g++-multilib and libc6:i386)
# TODO: add coverage build (requires lcov)
# TODO: add clang + libc++ builds for ubuntu
job:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.compiler }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-20.04, macos-latest]
build_type: ['Release', 'Debug']
compiler: ['g++', 'clang++']
lib: ['shared', 'static']
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: setup cmake initial cache
run: touch compiler-cache.cmake
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake -C ${{ github.workspace }}/compiler-cache.cmake
$GITHUB_WORKSPACE
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DCMAKE_CXX_COMPILER=${{ env.CXX }}
-DCMAKE_CXX_VISIBILITY_PRESET=hidden
-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build . --config ${{ matrix.build_type }}
- name: test
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: ctest -C ${{ matrix.build_type }} -VV
msvc:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msvc }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: powershell
strategy:
fail-fast: false
matrix:
msvc:
- VS-16-2019
- VS-17-2022
arch:
- x64
build_type:
- Debug
- Release
lib:
- shared
- static
include:
- msvc: VS-16-2019
os: windows-2019
generator: 'Visual Studio 16 2019'
- msvc: VS-17-2022
os: windows-2022
generator: 'Visual Studio 17 2022'
steps:
- uses: actions/checkout@v2
- uses: lukka/get-cmake@latest
- name: configure cmake
run: >
cmake -S . -B _build/
-A ${{ matrix.arch }}
-G "${{ matrix.generator }}"
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
- name: build
run: cmake --build _build/ --config ${{ matrix.build_type }}
- name: test
run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV
msys2:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msys2.msystem }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
os: [ windows-latest ]
msys2:
- { msystem: MINGW64, arch: x86_64, family: GNU, compiler: g++ }
- { msystem: MINGW32, arch: i686, family: GNU, compiler: g++ }
- { msystem: CLANG64, arch: x86_64, family: LLVM, compiler: clang++ }
- { msystem: CLANG32, arch: i686, family: LLVM, compiler: clang++ }
- { msystem: UCRT64, arch: x86_64, family: GNU, compiler: g++ }
build_type:
- Debug
- Release
lib:
- shared
- static
steps:
- uses: actions/checkout@v2
- name: Install Base Dependencies
uses: msys2/setup-msys2@v2
with:
cache: false
msystem: ${{ matrix.msys2.msystem }}
update: true
install: >-
git
base-devel
pacboy: >-
cc:p
cmake:p
ninja:p
- name: configure cmake
env:
CXX: ${{ matrix.msys2.compiler }}
run: >
cmake -S . -B _build/
-GNinja
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
- name: build
run: cmake --build _build/ --config ${{ matrix.build_type }}
- name: test
run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV

View File

@ -0,0 +1,18 @@
name: clang-format-lint
on:
push: {}
pull_request: {}
jobs:
job:
name: check-clang-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.13
with:
source: './include/benchmark ./src ./test'
extensions: 'h,cc'
clangFormatVersion: 12
style: Google

View File

@ -0,0 +1,38 @@
name: clang-tidy
on:
push: {}
pull_request: {}
jobs:
job:
name: run-clang-tidy
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: install clang-tidy
run: sudo apt update && sudo apt -y install clang-tidy
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
-DBENCHMARK_ENABLE_LIBPFM=OFF
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DGTEST_COMPILE_COMMANDS=OFF
- name: run
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: run-clang-tidy

View File

@ -0,0 +1,28 @@
name: doxygen
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-deploy:
name: Build HTML documentation
runs-on: ubuntu-latest
steps:
- name: Fetching sources
uses: actions/checkout@v3
- name: Installing build dependencies
run: |
sudo apt update
sudo apt install doxygen gcc git
- name: Creating build directory
run: mkdir build
- name: Building HTML documentation with Doxygen
run: |
cmake -S . -B build -DBENCHMARK_ENABLE_TESTING:BOOL=OFF -DBENCHMARK_ENABLE_DOXYGEN:BOOL=ON -DBENCHMARK_INSTALL_DOCS:BOOL=ON
cmake --build build --target benchmark_doxygen

View File

@ -0,0 +1,38 @@
name: python + Bazel pre-commit checks
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
pre-commit:
runs-on: ubuntu-latest
env:
MYPY_CACHE_DIR: "${{ github.workspace }}/.cache/mypy"
RUFF_CACHE_DIR: "${{ github.workspace }}/.cache/ruff"
PRE_COMMIT_HOME: "${{ github.workspace }}/.cache/pre-commit"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
cache: pip
cache-dependency-path: pyproject.toml
- name: Install dependencies
run: python -m pip install ".[dev]"
- name: Cache pre-commit tools
uses: actions/cache@v3
with:
path: |
${{ env.MYPY_CACHE_DIR }}
${{ env.RUFF_CACHE_DIR }}
${{ env.PRE_COMMIT_HOME }}
key: ${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}-linter-cache
- name: Run pre-commit checks
run: pre-commit run --all-files --verbose --show-diff-on-failure

View File

@ -0,0 +1,96 @@
name: sanitizer
on:
push: {}
pull_request: {}
env:
UBSAN_OPTIONS: "print_stacktrace=1"
jobs:
job:
name: ${{ matrix.sanitizer }}.${{ matrix.build_type }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
build_type: ['Debug', 'RelWithDebInfo']
sanitizer: ['asan', 'ubsan', 'tsan', 'msan']
steps:
- uses: actions/checkout@v3
- name: configure msan env
if: matrix.sanitizer == 'msan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=MemoryWithOrigins" >> $GITHUB_ENV
- name: configure ubsan env
if: matrix.sanitizer == 'ubsan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Undefined" >> $GITHUB_ENV
- name: configure asan env
if: matrix.sanitizer == 'asan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Address" >> $GITHUB_ENV
- name: configure tsan env
if: matrix.sanitizer == 'tsan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Thread" >> $GITHUB_ENV
- name: fine-tune asan options
# in asan we get an error from std::regex. ignore it.
if: matrix.sanitizer == 'asan'
run: |
echo "ASAN_OPTIONS=alloc_dealloc_mismatch=0" >> $GITHUB_ENV
- name: setup clang
uses: egor-tensin/setup-clang@v1
with:
version: latest
platform: x64
- name: configure clang
run: |
echo "CC=cc" >> $GITHUB_ENV
echo "CXX=c++" >> $GITHUB_ENV
- name: build libc++ (non-asan)
if: matrix.sanitizer != 'asan'
run: |
"${GITHUB_WORKSPACE}/.github/libcxx-setup.sh"
echo "EXTRA_CXX_FLAGS=-stdlib=libc++ -L ${GITHUB_WORKSPACE}/llvm-build/lib -lc++abi -Isystem${GITHUB_WORKSPACE}/llvm-build/include -Isystem${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Wl,-rpath,${GITHUB_WORKSPACE}/llvm-build/lib" >> $GITHUB_ENV
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
VERBOSE=1
cmake $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
-DBENCHMARK_ENABLE_LIBPFM=OFF
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_C_COMPILER=${{ env.CC }}
-DCMAKE_CXX_COMPILER=${{ env.CXX }}
-DCMAKE_C_FLAGS="${{ env.EXTRA_FLAGS }}"
-DCMAKE_CXX_FLAGS="${{ env.EXTRA_FLAGS }} ${{ env.EXTRA_CXX_FLAGS }}"
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build . --config ${{ matrix.build_type }}
- name: test
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: ctest -C ${{ matrix.build_type }} -VV

View File

@ -0,0 +1,30 @@
name: test-bindings
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
python_bindings:
name: Test GBM Python bindings on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install GBM Python bindings on ${{ matrix.os }}
run: python -m pip install .
- name: Run bindings example on ${{ matrix.os }}
run:
python bindings/python/google_benchmark/example.py

View File

@ -0,0 +1,90 @@
name: Build and upload Python wheels
on:
workflow_dispatch:
release:
types:
- published
jobs:
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12
- run: python -m pip install build
- name: Build sdist
run: python -m build --sdist
- uses: actions/upload-artifact@v4
with:
name: dist-sdist
path: dist/*.tar.gz
build_wheels:
name: Build Google Benchmark wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-13, macos-14, windows-latest]
steps:
- name: Check out Google Benchmark
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build wheels on ${{ matrix.os }} using cibuildwheel
uses: pypa/cibuildwheel@v2.17
env:
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*"
CIBW_SKIP: "*-musllinux_*"
CIBW_TEST_SKIP: "cp38-macosx_*:arm64"
CIBW_ARCHS_LINUX: auto64 aarch64
CIBW_ARCHS_WINDOWS: auto64
CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh
# Grab the rootless Bazel installation inside the container.
CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin
CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
- name: Upload Google Benchmark ${{ matrix.os }} wheels
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.os }}
path: wheelhouse/*.whl
merge_wheels:
name: Merge all built wheels into one artifact
runs-on: ubuntu-latest
needs: build_wheels
steps:
- name: Merge wheels
uses: actions/upload-artifact/merge@v4
with:
name: dist
pattern: dist-*
delete-merged: true
pypi_upload:
name: Publish google-benchmark wheels to PyPI
needs: [merge_wheels]
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist
- uses: pypa/gh-action-pypi-publish@v1

View File

@ -0,0 +1,62 @@
"""
This file contains the Bazel build dependencies for Google Benchmark (both C++ source and Python bindings).
"""
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
def benchmark_deps():
"""Loads dependencies required to build Google Benchmark."""
if "bazel_skylib" not in native.existing_rules():
http_archive(
name = "bazel_skylib",
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
],
)
if "rules_foreign_cc" not in native.existing_rules():
http_archive(
name = "rules_foreign_cc",
sha256 = "476303bd0f1b04cc311fc258f1708a5f6ef82d3091e53fd1977fa20383425a6a",
strip_prefix = "rules_foreign_cc-0.10.1",
url = "https://github.com/bazelbuild/rules_foreign_cc/releases/download/0.10.1/rules_foreign_cc-0.10.1.tar.gz",
)
if "rules_python" not in native.existing_rules():
http_archive(
name = "rules_python",
sha256 = "e85ae30de33625a63eca7fc40a94fea845e641888e52f32b6beea91e8b1b2793",
strip_prefix = "rules_python-0.27.1",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.27.1/rules_python-0.27.1.tar.gz",
)
if "com_google_googletest" not in native.existing_rules():
new_git_repository(
name = "com_google_googletest",
remote = "https://github.com/google/googletest.git",
tag = "release-1.12.1",
)
if "nanobind" not in native.existing_rules():
new_git_repository(
name = "nanobind",
remote = "https://github.com/wjakob/nanobind.git",
tag = "v1.8.0",
build_file = "@//bindings/python:nanobind.BUILD",
recursive_init_submodules = True,
)
if "libpfm" not in native.existing_rules():
# Downloaded from v4.9.0 tag at https://sourceforge.net/p/perfmon2/libpfm4/ref/master/tags/
http_archive(
name = "libpfm",
build_file = str(Label("//tools:libpfm.BUILD.bazel")),
sha256 = "5da5f8872bde14b3634c9688d980f68bda28b510268723cc12973eedbab9fecc",
type = "tar.gz",
strip_prefix = "libpfm-4.11.0",
urls = ["https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.11.0.tar.gz/download"],
)

View File

@ -0,0 +1,27 @@
load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension")
py_library(
name = "google_benchmark",
srcs = ["__init__.py"],
visibility = ["//visibility:public"],
deps = [
":_benchmark",
],
)
nanobind_extension(
name = "_benchmark",
srcs = ["benchmark.cc"],
deps = ["//:benchmark"],
)
py_test(
name = "example",
srcs = ["example.py"],
python_version = "PY3",
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
":google_benchmark",
],
)

View File

@ -0,0 +1,141 @@
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Python benchmarking utilities.
Example usage:
import google_benchmark as benchmark
@benchmark.register
def my_benchmark(state):
... # Code executed outside `while` loop is not timed.
while state:
... # Code executed within `while` loop is timed.
if __name__ == '__main__':
benchmark.main()
"""
import atexit
from absl import app
from google_benchmark import _benchmark
from google_benchmark._benchmark import (
Counter as Counter,
State as State,
kMicrosecond as kMicrosecond,
kMillisecond as kMillisecond,
kNanosecond as kNanosecond,
kSecond as kSecond,
o1 as o1,
oAuto as oAuto,
oLambda as oLambda,
oLogN as oLogN,
oN as oN,
oNCubed as oNCubed,
oNLogN as oNLogN,
oNone as oNone,
oNSquared as oNSquared,
)
from google_benchmark.version import __version__ as __version__
class __OptionMaker:
"""A stateless class to collect benchmark options.
Collect all decorator calls like @option.range(start=0, limit=1<<5).
"""
class Options:
"""Pure data class to store options calls, along with the benchmarked function."""
def __init__(self, func):
self.func = func
self.builder_calls = []
@classmethod
def make(cls, func_or_options):
"""Make Options from Options or the benchmarked function."""
if isinstance(func_or_options, cls.Options):
return func_or_options
return cls.Options(func_or_options)
def __getattr__(self, builder_name):
"""Append option call in the Options."""
# The function that get returned on @option.range(start=0, limit=1<<5).
def __builder_method(*args, **kwargs):
# The decorator that get called, either with the benchmared function
# or the previous Options
def __decorator(func_or_options):
options = self.make(func_or_options)
options.builder_calls.append((builder_name, args, kwargs))
# The decorator returns Options so it is not technically a decorator
# and needs a final call to @register
return options
return __decorator
return __builder_method
# Alias for nicer API.
# We have to instantiate an object, even if stateless, to be able to use __getattr__
# on option.range
option = __OptionMaker()
def register(undefined=None, *, name=None):
"""Register function for benchmarking."""
if undefined is None:
# Decorator is called without parenthesis so we return a decorator
return lambda f: register(f, name=name)
# We have either the function to benchmark (simple case) or an instance of Options
# (@option._ case).
options = __OptionMaker.make(undefined)
if name is None:
name = options.func.__name__
# We register the benchmark and reproduce all the @option._ calls onto the
# benchmark builder pattern
benchmark = _benchmark.RegisterBenchmark(name, options.func)
for name, args, kwargs in options.builder_calls[::-1]:
getattr(benchmark, name)(*args, **kwargs)
# return the benchmarked function because the decorator does not modify it
return options.func
def _flags_parser(argv):
argv = _benchmark.Initialize(argv)
return app.parse_flags_with_usage(argv)
def _run_benchmarks(argv):
if len(argv) > 1:
raise app.UsageError("Too many command-line arguments.")
return _benchmark.RunSpecifiedBenchmarks()
def main(argv=None):
return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser)
# Methods for use with custom main function.
initialize = _benchmark.Initialize
run_benchmarks = _benchmark.RunSpecifiedBenchmarks
atexit.register(_benchmark.ClearRegisteredBenchmarks)

View File

@ -0,0 +1,184 @@
// Benchmark for Python.
#include "benchmark/benchmark.h"
#include "nanobind/nanobind.h"
#include "nanobind/operators.h"
#include "nanobind/stl/bind_map.h"
#include "nanobind/stl/string.h"
#include "nanobind/stl/vector.h"
NB_MAKE_OPAQUE(benchmark::UserCounters);
namespace {
namespace nb = nanobind;
std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
// The `argv` pointers here become invalid when this function returns, but
// benchmark holds the pointer to `argv[0]`. We create a static copy of it
// so it persists, and replace the pointer below.
static std::string executable_name(argv[0]);
std::vector<char*> ptrs;
ptrs.reserve(argv.size());
for (auto& arg : argv) {
ptrs.push_back(const_cast<char*>(arg.c_str()));
}
ptrs[0] = const_cast<char*>(executable_name.c_str());
int argc = static_cast<int>(argv.size());
benchmark::Initialize(&argc, ptrs.data());
std::vector<std::string> remaining_argv;
remaining_argv.reserve(argc);
for (int i = 0; i < argc; ++i) {
remaining_argv.emplace_back(ptrs[i]);
}
return remaining_argv;
}
benchmark::internal::Benchmark* RegisterBenchmark(const std::string& name,
nb::callable f) {
return benchmark::RegisterBenchmark(
name, [f](benchmark::State& state) { f(&state); });
}
NB_MODULE(_benchmark, m) {
using benchmark::TimeUnit;
nb::enum_<TimeUnit>(m, "TimeUnit")
.value("kNanosecond", TimeUnit::kNanosecond)
.value("kMicrosecond", TimeUnit::kMicrosecond)
.value("kMillisecond", TimeUnit::kMillisecond)
.value("kSecond", TimeUnit::kSecond)
.export_values();
using benchmark::BigO;
nb::enum_<BigO>(m, "BigO")
.value("oNone", BigO::oNone)
.value("o1", BigO::o1)
.value("oN", BigO::oN)
.value("oNSquared", BigO::oNSquared)
.value("oNCubed", BigO::oNCubed)
.value("oLogN", BigO::oLogN)
.value("oNLogN", BigO::oNLogN)
.value("oAuto", BigO::oAuto)
.value("oLambda", BigO::oLambda)
.export_values();
using benchmark::internal::Benchmark;
nb::class_<Benchmark>(m, "Benchmark")
// For methods returning a pointer to the current object, reference
// return policy is used to ask nanobind not to take ownership of the
// returned object and avoid calling delete on it.
// https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
//
// For methods taking a const std::vector<...>&, a copy is created
// because a it is bound to a Python list.
// https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
.def("unit", &Benchmark::Unit, nb::rv_policy::reference)
.def("arg", &Benchmark::Arg, nb::rv_policy::reference)
.def("args", &Benchmark::Args, nb::rv_policy::reference)
.def("range", &Benchmark::Range, nb::rv_policy::reference,
nb::arg("start"), nb::arg("limit"))
.def("dense_range", &Benchmark::DenseRange,
nb::rv_policy::reference, nb::arg("start"),
nb::arg("limit"), nb::arg("step") = 1)
.def("ranges", &Benchmark::Ranges, nb::rv_policy::reference)
.def("args_product", &Benchmark::ArgsProduct,
nb::rv_policy::reference)
.def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference)
.def("arg_names", &Benchmark::ArgNames,
nb::rv_policy::reference)
.def("range_pair", &Benchmark::RangePair,
nb::rv_policy::reference, nb::arg("lo1"), nb::arg("hi1"),
nb::arg("lo2"), nb::arg("hi2"))
.def("range_multiplier", &Benchmark::RangeMultiplier,
nb::rv_policy::reference)
.def("min_time", &Benchmark::MinTime, nb::rv_policy::reference)
.def("min_warmup_time", &Benchmark::MinWarmUpTime,
nb::rv_policy::reference)
.def("iterations", &Benchmark::Iterations,
nb::rv_policy::reference)
.def("repetitions", &Benchmark::Repetitions,
nb::rv_policy::reference)
.def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
nb::rv_policy::reference)
.def("use_real_time", &Benchmark::UseRealTime,
nb::rv_policy::reference)
.def("use_manual_time", &Benchmark::UseManualTime,
nb::rv_policy::reference)
.def(
"complexity",
(Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
nb::rv_policy::reference,
nb::arg("complexity") = benchmark::oAuto);
using benchmark::Counter;
nb::class_<Counter> py_counter(m, "Counter");
nb::enum_<Counter::Flags>(py_counter, "Flags")
.value("kDefaults", Counter::Flags::kDefaults)
.value("kIsRate", Counter::Flags::kIsRate)
.value("kAvgThreads", Counter::Flags::kAvgThreads)
.value("kAvgThreadsRate", Counter::Flags::kAvgThreadsRate)
.value("kIsIterationInvariant", Counter::Flags::kIsIterationInvariant)
.value("kIsIterationInvariantRate",
Counter::Flags::kIsIterationInvariantRate)
.value("kAvgIterations", Counter::Flags::kAvgIterations)
.value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
.value("kInvert", Counter::Flags::kInvert)
.export_values()
.def(nb::self | nb::self);
nb::enum_<Counter::OneK>(py_counter, "OneK")
.value("kIs1000", Counter::OneK::kIs1000)
.value("kIs1024", Counter::OneK::kIs1024)
.export_values();
py_counter
.def(nb::init<double, Counter::Flags, Counter::OneK>(),
nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults,
nb::arg("k") = Counter::kIs1000)
.def("__init__", ([](Counter *c, double value) { new (c) Counter(value); }))
.def_rw("value", &Counter::value)
.def_rw("flags", &Counter::flags)
.def_rw("oneK", &Counter::oneK)
.def(nb::init_implicit<double>());
nb::implicitly_convertible<nb::int_, Counter>();
nb::bind_map<benchmark::UserCounters>(m, "UserCounters");
using benchmark::State;
nb::class_<State>(m, "State")
.def("__bool__", &State::KeepRunning)
.def_prop_ro("keep_running", &State::KeepRunning)
.def("pause_timing", &State::PauseTiming)
.def("resume_timing", &State::ResumeTiming)
.def("skip_with_error", &State::SkipWithError)
.def_prop_ro("error_occurred", &State::error_occurred)
.def("set_iteration_time", &State::SetIterationTime)
.def_prop_rw("bytes_processed", &State::bytes_processed,
&State::SetBytesProcessed)
.def_prop_rw("complexity_n", &State::complexity_length_n,
&State::SetComplexityN)
.def_prop_rw("items_processed", &State::items_processed,
&State::SetItemsProcessed)
.def("set_label", &State::SetLabel)
.def("range", &State::range, nb::arg("pos") = 0)
.def_prop_ro("iterations", &State::iterations)
.def_prop_ro("name", &State::name)
.def_rw("counters", &State::counters)
.def_prop_ro("thread_index", &State::thread_index)
.def_prop_ro("threads", &State::threads);
m.def("Initialize", Initialize);
m.def("RegisterBenchmark", RegisterBenchmark,
nb::rv_policy::reference);
m.def("RunSpecifiedBenchmarks",
[]() { benchmark::RunSpecifiedBenchmarks(); });
m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
};
} // namespace

View File

@ -0,0 +1,139 @@
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Example of Python using C++ benchmark framework.
To run this example, you must first install the `google_benchmark` Python package.
To install using `setup.py`, download and extract the `google_benchmark` source.
In the extracted directory, execute:
python setup.py install
"""
import random
import time
import google_benchmark as benchmark
from google_benchmark import Counter
@benchmark.register
def empty(state):
while state:
pass
@benchmark.register
def sum_million(state):
while state:
sum(range(1_000_000))
@benchmark.register
def pause_timing(state):
"""Pause timing every iteration."""
while state:
# Construct a list of random ints every iteration without timing it
state.pause_timing()
random_list = [random.randint(0, 100) for _ in range(100)]
state.resume_timing()
# Time the in place sorting algorithm
random_list.sort()
@benchmark.register
def skipped(state):
if True: # Test some predicate here.
state.skip_with_error("some error")
return # NOTE: You must explicitly return, or benchmark will continue.
... # Benchmark code would be here.
@benchmark.register
def manual_timing(state):
while state:
# Manually count Python CPU time
start = time.perf_counter() # perf_counter_ns() in Python 3.7+
# Something to benchmark
time.sleep(0.01)
end = time.perf_counter()
state.set_iteration_time(end - start)
@benchmark.register
def custom_counters(state):
"""Collect custom metric using benchmark.Counter."""
num_foo = 0.0
while state:
# Benchmark some code here
pass
# Collect some custom metric named foo
num_foo += 0.13
# Automatic Counter from numbers.
state.counters["foo"] = num_foo
# Set a counter as a rate.
state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
# Set a counter as an inverse of rate.
state.counters["foo_inv_rate"] = Counter(
num_foo, Counter.kIsRate | Counter.kInvert
)
# Set a counter as a thread-average quantity.
state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
# There's also a combined flag:
state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
@benchmark.register
@benchmark.option.measure_process_cpu_time()
@benchmark.option.use_real_time()
def with_options(state):
while state:
sum(range(1_000_000))
@benchmark.register(name="sum_million_microseconds")
@benchmark.option.unit(benchmark.kMicrosecond)
def with_options2(state):
while state:
sum(range(1_000_000))
@benchmark.register
@benchmark.option.arg(100)
@benchmark.option.arg(1000)
def passing_argument(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range(8, limit=8 << 10)
def using_range(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range_multiplier(2)
@benchmark.option.range(1 << 10, 1 << 18)
@benchmark.option.complexity(benchmark.oN)
def computing_complexity(state):
while state:
sum(range(state.range(0)))
state.complexity_n = state.range(0)
if __name__ == "__main__":
benchmark.main()

View File

@ -0,0 +1,7 @@
from importlib.metadata import PackageNotFoundError, version
try:
__version__ = version("google-benchmark")
except PackageNotFoundError:
# package is not installed
pass

20
third_party/benchmark/tools/BUILD.bazel vendored Normal file
View File

@ -0,0 +1,20 @@
load("@tools_pip_deps//:requirements.bzl", "requirement")
py_library(
name = "gbench",
srcs = glob(["gbench/*.py"]),
deps = [
requirement("numpy"),
requirement("scipy"),
],
)
py_binary(
name = "compare",
srcs = ["compare.py"],
imports = ["."],
python_version = "PY3",
deps = [
":gbench",
],
)

523
third_party/benchmark/tools/compare.py vendored Executable file
View File

@ -0,0 +1,523 @@
#!/usr/bin/env python3
# type: ignore
"""
compare.py - versatile benchmark output compare tool
"""
import argparse
import json
import os
import sys
import unittest
from argparse import ArgumentParser
import gbench
from gbench import report, util
def check_inputs(in1, in2, flags):
"""
Perform checking on the user provided inputs and diagnose any abnormalities
"""
in1_kind, in1_err = util.classify_input_file(in1)
in2_kind, in2_err = util.classify_input_file(in2)
output_file = util.find_benchmark_flag("--benchmark_out=", flags)
output_type = util.find_benchmark_flag("--benchmark_out_format=", flags)
if (
in1_kind == util.IT_Executable
and in2_kind == util.IT_Executable
and output_file
):
print(
(
"WARNING: '--benchmark_out=%s' will be passed to both "
"benchmarks causing it to be overwritten"
)
% output_file
)
if in1_kind == util.IT_JSON and in2_kind == util.IT_JSON:
# When both sides are JSON the only supported flag is
# --benchmark_filter=
for flag in util.remove_benchmark_flags("--benchmark_filter=", flags):
print(
"WARNING: passing %s has no effect since both "
"inputs are JSON" % flag
)
if output_type is not None and output_type != "json":
print(
(
"ERROR: passing '--benchmark_out_format=%s' to 'compare.py`"
" is not supported."
)
% output_type
)
sys.exit(1)
def create_parser():
parser = ArgumentParser(
description="versatile benchmark output compare tool"
)
parser.add_argument(
"-a",
"--display_aggregates_only",
dest="display_aggregates_only",
action="store_true",
help="If there are repetitions, by default, we display everything - the"
" actual runs, and the aggregates computed. Sometimes, it is "
"desirable to only view the aggregates. E.g. when there are a lot "
"of repetitions. Do note that only the display is affected. "
"Internally, all the actual runs are still used, e.g. for U test.",
)
parser.add_argument(
"--no-color",
dest="color",
default=True,
action="store_false",
help="Do not use colors in the terminal output",
)
parser.add_argument(
"-d",
"--dump_to_json",
dest="dump_to_json",
help="Additionally, dump benchmark comparison output to this file in JSON format.",
)
utest = parser.add_argument_group()
utest.add_argument(
"--no-utest",
dest="utest",
default=True,
action="store_false",
help="The tool can do a two-tailed Mann-Whitney U test with the null hypothesis that it is equally likely that a randomly selected value from one sample will be less than or greater than a randomly selected value from a second sample.\nWARNING: requires **LARGE** (no less than {}) number of repetitions to be meaningful!\nThe test is being done by default, if at least {} repetitions were done.\nThis option can disable the U Test.".format(
report.UTEST_OPTIMAL_REPETITIONS, report.UTEST_MIN_REPETITIONS
),
)
alpha_default = 0.05
utest.add_argument(
"--alpha",
dest="utest_alpha",
default=alpha_default,
type=float,
help=(
"significance level alpha. if the calculated p-value is below this value, then the result is said to be statistically significant and the null hypothesis is rejected.\n(default: %0.4f)"
)
% alpha_default,
)
subparsers = parser.add_subparsers(
help="This tool has multiple modes of operation:", dest="mode"
)
parser_a = subparsers.add_parser(
"benchmarks",
help="The most simple use-case, compare all the output of these two benchmarks",
)
baseline = parser_a.add_argument_group("baseline", "The benchmark baseline")
baseline.add_argument(
"test_baseline",
metavar="test_baseline",
type=argparse.FileType("r"),
nargs=1,
help="A benchmark executable or JSON output file",
)
contender = parser_a.add_argument_group(
"contender", "The benchmark that will be compared against the baseline"
)
contender.add_argument(
"test_contender",
metavar="test_contender",
type=argparse.FileType("r"),
nargs=1,
help="A benchmark executable or JSON output file",
)
parser_a.add_argument(
"benchmark_options",
metavar="benchmark_options",
nargs=argparse.REMAINDER,
help="Arguments to pass when running benchmark executables",
)
parser_b = subparsers.add_parser(
"filters", help="Compare filter one with the filter two of benchmark"
)
baseline = parser_b.add_argument_group("baseline", "The benchmark baseline")
baseline.add_argument(
"test",
metavar="test",
type=argparse.FileType("r"),
nargs=1,
help="A benchmark executable or JSON output file",
)
baseline.add_argument(
"filter_baseline",
metavar="filter_baseline",
type=str,
nargs=1,
help="The first filter, that will be used as baseline",
)
contender = parser_b.add_argument_group(
"contender", "The benchmark that will be compared against the baseline"
)
contender.add_argument(
"filter_contender",
metavar="filter_contender",
type=str,
nargs=1,
help="The second filter, that will be compared against the baseline",
)
parser_b.add_argument(
"benchmark_options",
metavar="benchmark_options",
nargs=argparse.REMAINDER,
help="Arguments to pass when running benchmark executables",
)
parser_c = subparsers.add_parser(
"benchmarksfiltered",
help="Compare filter one of first benchmark with filter two of the second benchmark",
)
baseline = parser_c.add_argument_group("baseline", "The benchmark baseline")
baseline.add_argument(
"test_baseline",
metavar="test_baseline",
type=argparse.FileType("r"),
nargs=1,
help="A benchmark executable or JSON output file",
)
baseline.add_argument(
"filter_baseline",
metavar="filter_baseline",
type=str,
nargs=1,
help="The first filter, that will be used as baseline",
)
contender = parser_c.add_argument_group(
"contender", "The benchmark that will be compared against the baseline"
)
contender.add_argument(
"test_contender",
metavar="test_contender",
type=argparse.FileType("r"),
nargs=1,
help="The second benchmark executable or JSON output file, that will be compared against the baseline",
)
contender.add_argument(
"filter_contender",
metavar="filter_contender",
type=str,
nargs=1,
help="The second filter, that will be compared against the baseline",
)
parser_c.add_argument(
"benchmark_options",
metavar="benchmark_options",
nargs=argparse.REMAINDER,
help="Arguments to pass when running benchmark executables",
)
return parser
def main():
# Parse the command line flags
parser = create_parser()
args, unknown_args = parser.parse_known_args()
if args.mode is None:
parser.print_help()
exit(1)
assert not unknown_args
benchmark_options = args.benchmark_options
if args.mode == "benchmarks":
test_baseline = args.test_baseline[0].name
test_contender = args.test_contender[0].name
filter_baseline = ""
filter_contender = ""
# NOTE: if test_baseline == test_contender, you are analyzing the stdev
description = "Comparing %s to %s" % (test_baseline, test_contender)
elif args.mode == "filters":
test_baseline = args.test[0].name
test_contender = args.test[0].name
filter_baseline = args.filter_baseline[0]
filter_contender = args.filter_contender[0]
# NOTE: if filter_baseline == filter_contender, you are analyzing the
# stdev
description = "Comparing %s to %s (from %s)" % (
filter_baseline,
filter_contender,
args.test[0].name,
)
elif args.mode == "benchmarksfiltered":
test_baseline = args.test_baseline[0].name
test_contender = args.test_contender[0].name
filter_baseline = args.filter_baseline[0]
filter_contender = args.filter_contender[0]
# NOTE: if test_baseline == test_contender and
# filter_baseline == filter_contender, you are analyzing the stdev
description = "Comparing %s (from %s) to %s (from %s)" % (
filter_baseline,
test_baseline,
filter_contender,
test_contender,
)
else:
# should never happen
print("Unrecognized mode of operation: '%s'" % args.mode)
parser.print_help()
exit(1)
check_inputs(test_baseline, test_contender, benchmark_options)
if args.display_aggregates_only:
benchmark_options += ["--benchmark_display_aggregates_only=true"]
options_baseline = []
options_contender = []
if filter_baseline and filter_contender:
options_baseline = ["--benchmark_filter=%s" % filter_baseline]
options_contender = ["--benchmark_filter=%s" % filter_contender]
# Run the benchmarks and report the results
json1 = json1_orig = gbench.util.sort_benchmark_results(
gbench.util.run_or_load_benchmark(
test_baseline, benchmark_options + options_baseline
)
)
json2 = json2_orig = gbench.util.sort_benchmark_results(
gbench.util.run_or_load_benchmark(
test_contender, benchmark_options + options_contender
)
)
# Now, filter the benchmarks so that the difference report can work
if filter_baseline and filter_contender:
replacement = "[%s vs. %s]" % (filter_baseline, filter_contender)
json1 = gbench.report.filter_benchmark(
json1_orig, filter_baseline, replacement
)
json2 = gbench.report.filter_benchmark(
json2_orig, filter_contender, replacement
)
diff_report = gbench.report.get_difference_report(json1, json2, args.utest)
output_lines = gbench.report.print_difference_report(
diff_report,
args.display_aggregates_only,
args.utest,
args.utest_alpha,
args.color,
)
print(description)
for ln in output_lines:
print(ln)
# Optionally, diff and output to JSON
if args.dump_to_json is not None:
with open(args.dump_to_json, "w") as f_json:
json.dump(diff_report, f_json, indent=1)
class TestParser(unittest.TestCase):
def setUp(self):
self.parser = create_parser()
testInputs = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "gbench", "Inputs"
)
self.testInput0 = os.path.join(testInputs, "test1_run1.json")
self.testInput1 = os.path.join(testInputs, "test1_run2.json")
def test_benchmarks_basic(self):
parsed = self.parser.parse_args(
["benchmarks", self.testInput0, self.testInput1]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_basic_without_utest(self):
parsed = self.parser.parse_args(
["--no-utest", "benchmarks", self.testInput0, self.testInput1]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertFalse(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.05)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_basic_display_aggregates_only(self):
parsed = self.parser.parse_args(
["-a", "benchmarks", self.testInput0, self.testInput1]
)
self.assertTrue(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_basic_with_utest_alpha(self):
parsed = self.parser.parse_args(
["--alpha=0.314", "benchmarks", self.testInput0, self.testInput1]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.314)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_basic_without_utest_with_utest_alpha(self):
parsed = self.parser.parse_args(
[
"--no-utest",
"--alpha=0.314",
"benchmarks",
self.testInput0,
self.testInput1,
]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertFalse(parsed.utest)
self.assertEqual(parsed.utest_alpha, 0.314)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertFalse(parsed.benchmark_options)
def test_benchmarks_with_remainder(self):
parsed = self.parser.parse_args(
["benchmarks", self.testInput0, self.testInput1, "d"]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.benchmark_options, ["d"])
def test_benchmarks_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
["benchmarks", self.testInput0, self.testInput1, "--", "e"]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarks")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.benchmark_options, ["e"])
def test_filters_basic(self):
parsed = self.parser.parse_args(["filters", self.testInput0, "c", "d"])
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "filters")
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.filter_contender[0], "d")
self.assertFalse(parsed.benchmark_options)
def test_filters_with_remainder(self):
parsed = self.parser.parse_args(
["filters", self.testInput0, "c", "d", "e"]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "filters")
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.filter_contender[0], "d")
self.assertEqual(parsed.benchmark_options, ["e"])
def test_filters_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
["filters", self.testInput0, "c", "d", "--", "f"]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "filters")
self.assertEqual(parsed.test[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.filter_contender[0], "d")
self.assertEqual(parsed.benchmark_options, ["f"])
def test_benchmarksfiltered_basic(self):
parsed = self.parser.parse_args(
["benchmarksfiltered", self.testInput0, "c", self.testInput1, "e"]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarksfiltered")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], "e")
self.assertFalse(parsed.benchmark_options)
def test_benchmarksfiltered_with_remainder(self):
parsed = self.parser.parse_args(
[
"benchmarksfiltered",
self.testInput0,
"c",
self.testInput1,
"e",
"f",
]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarksfiltered")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], "e")
self.assertEqual(parsed.benchmark_options[0], "f")
def test_benchmarksfiltered_with_remainder_after_doubleminus(self):
parsed = self.parser.parse_args(
[
"benchmarksfiltered",
self.testInput0,
"c",
self.testInput1,
"e",
"--",
"g",
]
)
self.assertFalse(parsed.display_aggregates_only)
self.assertTrue(parsed.utest)
self.assertEqual(parsed.mode, "benchmarksfiltered")
self.assertEqual(parsed.test_baseline[0].name, self.testInput0)
self.assertEqual(parsed.filter_baseline[0], "c")
self.assertEqual(parsed.test_contender[0].name, self.testInput1)
self.assertEqual(parsed.filter_contender[0], "e")
self.assertEqual(parsed.benchmark_options[0], "g")
if __name__ == "__main__":
# unittest.main()
main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
# kate: indent-mode python; remove-trailing-spaces modified;

View File

@ -0,0 +1,127 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_SameTimes",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_2xFaster",
"iterations": 1000,
"real_time": 50,
"cpu_time": 50,
"time_unit": "ns"
},
{
"name": "BM_2xSlower",
"iterations": 1000,
"real_time": 50,
"cpu_time": 50,
"time_unit": "ns"
},
{
"name": "BM_1PercentFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_1PercentSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_100xSlower",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_100xFaster",
"iterations": 1000,
"real_time": 10000,
"cpu_time": 10000,
"time_unit": "ns"
},
{
"name": "BM_10PercentCPUToTime",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_ThirdFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "MyComplexityTest_BigO",
"run_name": "MyComplexityTest",
"run_type": "aggregate",
"aggregate_name": "BigO",
"cpu_coefficient": 4.2749856294592886e+00,
"real_coefficient": 6.4789275289789780e+00,
"big_o": "N",
"time_unit": "ns"
},
{
"name": "MyComplexityTest_RMS",
"run_name": "MyComplexityTest",
"run_type": "aggregate",
"aggregate_name": "RMS",
"rms": 4.5097802512472874e-03
},
{
"name": "BM_NotBadTimeUnit",
"iterations": 1000,
"real_time": 0.4,
"cpu_time": 0.5,
"time_unit": "s"
},
{
"name": "BM_DifferentTimeUnit",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "s"
},
{
"name": "BM_hasLabel",
"label": "a label",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "s"
}
]
}

View File

@ -0,0 +1,127 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_SameTimes",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_2xFaster",
"iterations": 1000,
"real_time": 25,
"cpu_time": 25,
"time_unit": "ns"
},
{
"name": "BM_2xSlower",
"iterations": 20833333,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_1PercentFaster",
"iterations": 1000,
"real_time": 98.9999999,
"cpu_time": 98.9999999,
"time_unit": "ns"
},
{
"name": "BM_1PercentSlower",
"iterations": 1000,
"real_time": 100.9999999,
"cpu_time": 100.9999999,
"time_unit": "ns"
},
{
"name": "BM_10PercentFaster",
"iterations": 1000,
"real_time": 90,
"cpu_time": 90,
"time_unit": "ns"
},
{
"name": "BM_10PercentSlower",
"iterations": 1000,
"real_time": 110,
"cpu_time": 110,
"time_unit": "ns"
},
{
"name": "BM_100xSlower",
"iterations": 1000,
"real_time": 1.0000e+04,
"cpu_time": 1.0000e+04,
"time_unit": "ns"
},
{
"name": "BM_100xFaster",
"iterations": 1000,
"real_time": 100,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_10PercentCPUToTime",
"iterations": 1000,
"real_time": 110,
"cpu_time": 90,
"time_unit": "ns"
},
{
"name": "BM_ThirdFaster",
"iterations": 1000,
"real_time": 66.665,
"cpu_time": 66.664,
"time_unit": "ns"
},
{
"name": "MyComplexityTest_BigO",
"run_name": "MyComplexityTest",
"run_type": "aggregate",
"aggregate_name": "BigO",
"cpu_coefficient": 5.6215779594361486e+00,
"real_coefficient": 5.6288314793554610e+00,
"big_o": "N",
"time_unit": "ns"
},
{
"name": "MyComplexityTest_RMS",
"run_name": "MyComplexityTest",
"run_type": "aggregate",
"aggregate_name": "RMS",
"rms": 3.3128901852342174e-03
},
{
"name": "BM_NotBadTimeUnit",
"iterations": 1000,
"real_time": 0.04,
"cpu_time": 0.6,
"time_unit": "s"
},
{
"name": "BM_DifferentTimeUnit",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "ns"
},
{
"name": "BM_hasLabel",
"label": "a label",
"iterations": 1,
"real_time": 1,
"cpu_time": 1,
"time_unit": "s"
}
]
}

View File

@ -0,0 +1,81 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_Hi",
"iterations": 1234,
"real_time": 42,
"cpu_time": 24,
"time_unit": "ms"
},
{
"name": "BM_Zero",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "BM_Zero/4",
"iterations": 4000,
"real_time": 40,
"cpu_time": 40,
"time_unit": "ns"
},
{
"name": "Prefix/BM_Zero",
"iterations": 2000,
"real_time": 20,
"cpu_time": 20,
"time_unit": "ns"
},
{
"name": "Prefix/BM_Zero/3",
"iterations": 3000,
"real_time": 30,
"cpu_time": 30,
"time_unit": "ns"
},
{
"name": "BM_One",
"iterations": 5000,
"real_time": 5,
"cpu_time": 5,
"time_unit": "ns"
},
{
"name": "BM_One/4",
"iterations": 2000,
"real_time": 20,
"cpu_time": 20,
"time_unit": "ns"
},
{
"name": "Prefix/BM_One",
"iterations": 1000,
"real_time": 10,
"cpu_time": 10,
"time_unit": "ns"
},
{
"name": "Prefix/BM_One/3",
"iterations": 1500,
"real_time": 15,
"cpu_time": 15,
"time_unit": "ns"
},
{
"name": "BM_Bye",
"iterations": 5321,
"real_time": 11,
"cpu_time": 63,
"time_unit": "ns"
}
]
}

View File

@ -0,0 +1,65 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_One",
"run_type": "aggregate",
"iterations": 1000,
"real_time": 10,
"cpu_time": 100,
"time_unit": "ns"
},
{
"name": "BM_Two",
"iterations": 1000,
"real_time": 9,
"cpu_time": 90,
"time_unit": "ns"
},
{
"name": "BM_Two",
"iterations": 1000,
"real_time": 8,
"cpu_time": 86,
"time_unit": "ns"
},
{
"name": "short",
"run_type": "aggregate",
"iterations": 1000,
"real_time": 8,
"cpu_time": 80,
"time_unit": "ns"
},
{
"name": "short",
"run_type": "aggregate",
"iterations": 1000,
"real_time": 8,
"cpu_time": 77,
"time_unit": "ns"
},
{
"name": "medium",
"run_type": "iteration",
"iterations": 1000,
"real_time": 8,
"cpu_time": 80,
"time_unit": "ns"
},
{
"name": "medium",
"run_type": "iteration",
"iterations": 1000,
"real_time": 9,
"cpu_time": 82,
"time_unit": "ns"
}
]
}

View File

@ -0,0 +1,65 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_One",
"iterations": 1000,
"real_time": 9,
"cpu_time": 110,
"time_unit": "ns"
},
{
"name": "BM_Two",
"run_type": "aggregate",
"iterations": 1000,
"real_time": 10,
"cpu_time": 89,
"time_unit": "ns"
},
{
"name": "BM_Two",
"iterations": 1000,
"real_time": 7,
"cpu_time": 72,
"time_unit": "ns"
},
{
"name": "short",
"run_type": "aggregate",
"iterations": 1000,
"real_time": 7,
"cpu_time": 75,
"time_unit": "ns"
},
{
"name": "short",
"run_type": "aggregate",
"iterations": 762,
"real_time": 4.54,
"cpu_time": 66.6,
"time_unit": "ns"
},
{
"name": "short",
"run_type": "iteration",
"iterations": 1000,
"real_time": 800,
"cpu_time": 1,
"time_unit": "ns"
},
{
"name": "medium",
"run_type": "iteration",
"iterations": 1200,
"real_time": 5,
"cpu_time": 53,
"time_unit": "ns"
}
]
}

View File

@ -0,0 +1,96 @@
{
"benchmarks": [
{
"name": "99 family 0 instance 0 repetition 0",
"run_type": "iteration",
"family_index": 0,
"per_family_instance_index": 0,
"repetition_index": 0
},
{
"name": "98 family 0 instance 0 repetition 1",
"run_type": "iteration",
"family_index": 0,
"per_family_instance_index": 0,
"repetition_index": 1
},
{
"name": "97 family 0 instance 0 aggregate",
"run_type": "aggregate",
"family_index": 0,
"per_family_instance_index": 0,
"aggregate_name": "9 aggregate"
},
{
"name": "96 family 0 instance 1 repetition 0",
"run_type": "iteration",
"family_index": 0,
"per_family_instance_index": 1,
"repetition_index": 0
},
{
"name": "95 family 0 instance 1 repetition 1",
"run_type": "iteration",
"family_index": 0,
"per_family_instance_index": 1,
"repetition_index": 1
},
{
"name": "94 family 0 instance 1 aggregate",
"run_type": "aggregate",
"family_index": 0,
"per_family_instance_index": 1,
"aggregate_name": "9 aggregate"
},
{
"name": "93 family 1 instance 0 repetition 0",
"run_type": "iteration",
"family_index": 1,
"per_family_instance_index": 0,
"repetition_index": 0
},
{
"name": "92 family 1 instance 0 repetition 1",
"run_type": "iteration",
"family_index": 1,
"per_family_instance_index": 0,
"repetition_index": 1
},
{
"name": "91 family 1 instance 0 aggregate",
"run_type": "aggregate",
"family_index": 1,
"per_family_instance_index": 0,
"aggregate_name": "9 aggregate"
},
{
"name": "90 family 1 instance 1 repetition 0",
"run_type": "iteration",
"family_index": 1,
"per_family_instance_index": 1,
"repetition_index": 0
},
{
"name": "89 family 1 instance 1 repetition 1",
"run_type": "iteration",
"family_index": 1,
"per_family_instance_index": 1,
"repetition_index": 1
},
{
"name": "88 family 1 instance 1 aggregate",
"run_type": "aggregate",
"family_index": 1,
"per_family_instance_index": 1,
"aggregate_name": "9 aggregate"
}
]
}

View File

@ -0,0 +1,21 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "whocares",
"run_type": "aggregate",
"aggregate_name": "zz",
"aggregate_unit": "percentage",
"iterations": 1000,
"real_time": 0.01,
"cpu_time": 0.10,
"time_unit": "ns"
}
]
}

View File

@ -0,0 +1,21 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "whocares",
"run_type": "aggregate",
"aggregate_name": "zz",
"aggregate_unit": "percentage",
"iterations": 1000,
"real_time": 0.005,
"cpu_time": 0.15,
"time_unit": "ns"
}
]
}

View File

@ -0,0 +1,18 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_ManyRepetitions",
"iterations": 1000,
"real_time": 1,
"cpu_time": 1000,
"time_unit": "s"
}
]
}

View File

@ -0,0 +1,18 @@
{
"context": {
"date": "2016-08-02 17:44:46",
"num_cpus": 4,
"mhz_per_cpu": 4228,
"cpu_scaling_enabled": false,
"library_build_type": "release"
},
"benchmarks": [
{
"name": "BM_ManyRepetitions",
"iterations": 1000,
"real_time": 1000,
"cpu_time": 1,
"time_unit": "s"
}
]
}

View File

@ -0,0 +1,8 @@
"""Google Benchmark tooling"""
__author__ = "Eric Fiselier"
__email__ = "eric@efcs.ca"
__versioninfo__ = (0, 5, 0)
__version__ = ".".join(str(v) for v in __versioninfo__) + "dev"
__all__ = [] # type: ignore

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,231 @@
"""util.py - General utilities for running, loading, and processing benchmarks"""
import json
import os
import re
import subprocess
import sys
import tempfile
# Input file type enumeration
IT_Invalid = 0
IT_JSON = 1
IT_Executable = 2
_num_magic_bytes = 2 if sys.platform.startswith("win") else 4
def is_executable_file(filename):
"""
Return 'True' if 'filename' names a valid file which is likely
an executable. A file is considered an executable if it starts with the
magic bytes for a EXE, Mach O, or ELF file.
"""
if not os.path.isfile(filename):
return False
with open(filename, mode="rb") as f:
magic_bytes = f.read(_num_magic_bytes)
if sys.platform == "darwin":
return magic_bytes in [
b"\xfe\xed\xfa\xce", # MH_MAGIC
b"\xce\xfa\xed\xfe", # MH_CIGAM
b"\xfe\xed\xfa\xcf", # MH_MAGIC_64
b"\xcf\xfa\xed\xfe", # MH_CIGAM_64
b"\xca\xfe\xba\xbe", # FAT_MAGIC
b"\xbe\xba\xfe\xca", # FAT_CIGAM
]
elif sys.platform.startswith("win"):
return magic_bytes == b"MZ"
else:
return magic_bytes == b"\x7fELF"
def is_json_file(filename):
"""
Returns 'True' if 'filename' names a valid JSON output file.
'False' otherwise.
"""
try:
with open(filename, "r") as f:
json.load(f)
return True
except BaseException:
pass
return False
def classify_input_file(filename):
"""
Return a tuple (type, msg) where 'type' specifies the classified type
of 'filename'. If 'type' is 'IT_Invalid' then 'msg' is a human readable
string representing the error.
"""
ftype = IT_Invalid
err_msg = None
if not os.path.exists(filename):
err_msg = "'%s' does not exist" % filename
elif not os.path.isfile(filename):
err_msg = "'%s' does not name a file" % filename
elif is_executable_file(filename):
ftype = IT_Executable
elif is_json_file(filename):
ftype = IT_JSON
else:
err_msg = (
"'%s' does not name a valid benchmark executable or JSON file"
% filename
)
return ftype, err_msg
def check_input_file(filename):
"""
Classify the file named by 'filename' and return the classification.
If the file is classified as 'IT_Invalid' print an error message and exit
the program.
"""
ftype, msg = classify_input_file(filename)
if ftype == IT_Invalid:
print("Invalid input file: %s" % msg)
sys.exit(1)
return ftype
def find_benchmark_flag(prefix, benchmark_flags):
"""
Search the specified list of flags for a flag matching `<prefix><arg>` and
if it is found return the arg it specifies. If specified more than once the
last value is returned. If the flag is not found None is returned.
"""
assert prefix.startswith("--") and prefix.endswith("=")
result = None
for f in benchmark_flags:
if f.startswith(prefix):
result = f[len(prefix) :]
return result
def remove_benchmark_flags(prefix, benchmark_flags):
"""
Return a new list containing the specified benchmark_flags except those
with the specified prefix.
"""
assert prefix.startswith("--") and prefix.endswith("=")
return [f for f in benchmark_flags if not f.startswith(prefix)]
def load_benchmark_results(fname, benchmark_filter):
"""
Read benchmark output from a file and return the JSON object.
Apply benchmark_filter, a regular expression, with nearly the same
semantics of the --benchmark_filter argument. May be None.
Note: the Python regular expression engine is used instead of the
one used by the C++ code, which may produce different results
in complex cases.
REQUIRES: 'fname' names a file containing JSON benchmark output.
"""
def benchmark_wanted(benchmark):
if benchmark_filter is None:
return True
name = benchmark.get("run_name", None) or benchmark["name"]
return re.search(benchmark_filter, name) is not None
with open(fname, "r") as f:
results = json.load(f)
if "context" in results:
if "json_schema_version" in results["context"]:
json_schema_version = results["context"]["json_schema_version"]
if json_schema_version != 1:
print(
"In %s, got unnsupported JSON schema version: %i, expected 1"
% (fname, json_schema_version)
)
sys.exit(1)
if "benchmarks" in results:
results["benchmarks"] = list(
filter(benchmark_wanted, results["benchmarks"])
)
return results
def sort_benchmark_results(result):
benchmarks = result["benchmarks"]
# From inner key to the outer key!
benchmarks = sorted(
benchmarks,
key=lambda benchmark: benchmark["repetition_index"]
if "repetition_index" in benchmark
else -1,
)
benchmarks = sorted(
benchmarks,
key=lambda benchmark: 1
if "run_type" in benchmark and benchmark["run_type"] == "aggregate"
else 0,
)
benchmarks = sorted(
benchmarks,
key=lambda benchmark: benchmark["per_family_instance_index"]
if "per_family_instance_index" in benchmark
else -1,
)
benchmarks = sorted(
benchmarks,
key=lambda benchmark: benchmark["family_index"]
if "family_index" in benchmark
else -1,
)
result["benchmarks"] = benchmarks
return result
def run_benchmark(exe_name, benchmark_flags):
"""
Run a benchmark specified by 'exe_name' with the specified
'benchmark_flags'. The benchmark is run directly as a subprocess to preserve
real time console output.
RETURNS: A JSON object representing the benchmark output
"""
output_name = find_benchmark_flag("--benchmark_out=", benchmark_flags)
is_temp_output = False
if output_name is None:
is_temp_output = True
thandle, output_name = tempfile.mkstemp()
os.close(thandle)
benchmark_flags = list(benchmark_flags) + [
"--benchmark_out=%s" % output_name
]
cmd = [exe_name] + benchmark_flags
print("RUNNING: %s" % " ".join(cmd))
exitCode = subprocess.call(cmd)
if exitCode != 0:
print("TEST FAILED...")
sys.exit(exitCode)
json_res = load_benchmark_results(output_name, None)
if is_temp_output:
os.unlink(output_name)
return json_res
def run_or_load_benchmark(filename, benchmark_flags):
"""
Get the results for a specified benchmark. If 'filename' specifies
an executable benchmark then the results are generated by running the
benchmark. Otherwise 'filename' must name a valid JSON output file,
which is loaded and the result returned.
"""
ftype = check_input_file(filename)
if ftype == IT_JSON:
benchmark_filter = find_benchmark_flag(
"--benchmark_filter=", benchmark_flags
)
return load_benchmark_results(filename, benchmark_filter)
if ftype == IT_Executable:
return run_benchmark(filename, benchmark_flags)
raise ValueError("Unknown file type %s" % ftype)

View File

@ -0,0 +1,22 @@
# Build rule for libpfm, which is required to collect performance counters for
# BENCHMARK_ENABLE_LIBPFM builds.
load("@rules_foreign_cc//foreign_cc:defs.bzl", "make")
filegroup(
name = "pfm_srcs",
srcs = glob(["**"]),
)
make(
name = "libpfm",
lib_source = ":pfm_srcs",
lib_name = "libpfm",
copts = [
"-Wno-format-truncation",
"-Wno-use-after-free",
],
visibility = [
"//visibility:public",
],
)

View File

@ -0,0 +1,2 @@
numpy == 1.25
scipy == 1.10.0

163
third_party/benchmark/tools/strip_asm.py vendored Executable file
View File

@ -0,0 +1,163 @@
#!/usr/bin/env python3
"""
strip_asm.py - Cleanup ASM output for the specified file
"""
import os
import re
import sys
from argparse import ArgumentParser
def find_used_labels(asm):
found = set()
label_re = re.compile(r"\s*j[a-z]+\s+\.L([a-zA-Z0-9][a-zA-Z0-9_]*)")
for line in asm.splitlines():
m = label_re.match(line)
if m:
found.add(".L%s" % m.group(1))
return found
def normalize_labels(asm):
decls = set()
label_decl = re.compile("^[.]{0,1}L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
for line in asm.splitlines():
m = label_decl.match(line)
if m:
decls.add(m.group(0))
if len(decls) == 0:
return asm
needs_dot = next(iter(decls))[0] != "."
if not needs_dot:
return asm
for ld in decls:
asm = re.sub(r"(^|\s+)" + ld + r"(?=:|\s)", "\\1." + ld, asm)
return asm
def transform_labels(asm):
asm = normalize_labels(asm)
used_decls = find_used_labels(asm)
new_asm = ""
label_decl = re.compile(r"^\.L([a-zA-Z0-9][a-zA-Z0-9_]*)(?=:)")
for line in asm.splitlines():
m = label_decl.match(line)
if not m or m.group(0) in used_decls:
new_asm += line
new_asm += "\n"
return new_asm
def is_identifier(tk):
if len(tk) == 0:
return False
first = tk[0]
if not first.isalpha() and first != "_":
return False
for i in range(1, len(tk)):
c = tk[i]
if not c.isalnum() and c != "_":
return False
return True
def process_identifiers(line):
"""
process_identifiers - process all identifiers and modify them to have
consistent names across all platforms; specifically across ELF and MachO.
For example, MachO inserts an additional understore at the beginning of
names. This function removes that.
"""
parts = re.split(r"([a-zA-Z0-9_]+)", line)
new_line = ""
for tk in parts:
if is_identifier(tk):
if tk.startswith("__Z"):
tk = tk[1:]
elif (
tk.startswith("_")
and len(tk) > 1
and tk[1].isalpha()
and tk[1] != "Z"
):
tk = tk[1:]
new_line += tk
return new_line
def process_asm(asm):
"""
Strip the ASM of unwanted directives and lines
"""
new_contents = ""
asm = transform_labels(asm)
# TODO: Add more things we want to remove
discard_regexes = [
re.compile(r"\s+\..*$"), # directive
re.compile(r"\s*#(NO_APP|APP)$"), # inline ASM
re.compile(r"\s*#.*$"), # comment line
re.compile(
r"\s*\.globa?l\s*([.a-zA-Z_][a-zA-Z0-9$_.]*)"
), # global directive
re.compile(
r"\s*\.(string|asciz|ascii|[1248]?byte|short|word|long|quad|value|zero)"
),
]
keep_regexes: list[re.Pattern] = []
fn_label_def = re.compile("^[a-zA-Z_][a-zA-Z0-9_.]*:")
for line in asm.splitlines():
# Remove Mach-O attribute
line = line.replace("@GOTPCREL", "")
add_line = True
for reg in discard_regexes:
if reg.match(line) is not None:
add_line = False
break
for reg in keep_regexes:
if reg.match(line) is not None:
add_line = True
break
if add_line:
if fn_label_def.match(line) and len(new_contents) != 0:
new_contents += "\n"
line = process_identifiers(line)
new_contents += line
new_contents += "\n"
return new_contents
def main():
parser = ArgumentParser(description="generate a stripped assembly file")
parser.add_argument(
"input",
metavar="input",
type=str,
nargs=1,
help="An input assembly file",
)
parser.add_argument(
"out", metavar="output", type=str, nargs=1, help="The output file"
)
args, unknown_args = parser.parse_known_args()
input = args.input[0]
output = args.out[0]
if not os.path.isfile(input):
print("ERROR: input file '%s' does not exist" % input)
sys.exit(1)
with open(input, "r") as f:
contents = f.read()
new_contents = process_asm(contents)
with open(output, "w") as f:
f.write(new_contents)
if __name__ == "__main__":
main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# kate: tab-width: 4; replace-tabs on; indent-width 4; tab-indents: off;
# kate: indent-mode python; remove-trailing-spaces modified;

59
third_party/context/.gitignore vendored Normal file
View File

@ -0,0 +1,59 @@
# .gitignore - The Nova Project
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# CMake
build/
cmake-build/
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps

278
third_party/context/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,278 @@
# Nova-Context This file is part of the Nova-Context library source code.
# Copyright (c) 2023 - The Nova Project
#
# Parts of this build configuration have been brazenly stolen from the
# boost.context foundational library: https://github.com/boostorg/context
# Copyright (c) 2009 - Oliver Kowalke, licensed under the Boost Software License
# 1.0: http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
project(
nova_context
VERSION 0.1.0
LANGUAGES C ASM)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
option(NOVA_CONTEXT_BUILD_STATIC "Build Nova-Context as static library" ON)
# option(NOVA_CONTEXT_BUILD_TEST "Nova-Context build test app" OFF)
option(NOVA_CONTEXT_PIC
"Compile Nova-Context with position independent code (PIC)" ON)
option(NOVA_CONTEXT_INSTALL "Generate installation target for Nova-Context" OFF)
# Binary format
if(WIN32)
set(_default_binfmt pe)
elseif(APPLE)
set(_default_binfmt mach-o)
else()
set(_default_binfmt elf)
endif()
set(NOVA_CONTEXT_BINARY_FORMAT
"${_default_binfmt}"
CACHE STRING "Nova-Context binary format (elf, mach-o, pe, xcoff)")
set_property(CACHE NOVA_CONTEXT_BINARY_FORMAT PROPERTY STRINGS elf mach-o pe
xcoff)
unset(_default_binfmt)
# ABI
math(EXPR _bits "${CMAKE_SIZEOF_VOID_P} * 8")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]" OR CMAKE_SYSTEM_PROCESSOR
STREQUAL "aarch64")
set(_default_abi aapcs)
elseif(WIN32)
set(_default_abi ms)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
if(_bits EQUAL 32)
set(_default_abi o32)
else()
set(_default_abi n64)
endif()
else()
set(_default_abi sysv)
endif()
set(NOVA_CONTEXT_ABI
"${_default_abi}"
CACHE STRING
"Nova-Context ABI (aapcs, eabi, ms, n32, n64, o32, o64, sysv, x32)")
set_property(
CACHE NOVA_CONTEXT_ABI
PROPERTY STRINGS
aapcs
eabi
ms
n32
n64
o32
o64
sysv
x32)
unset(_default_abi)
# Arch-and-model
set(_all_archs
arm
arm64
loongarch64
mips32
mips64
ppc32
ppc64
riscv64
s390x
i386
x86_64
combined)
# Try at start to auto determine arch from CMake.
if(CMAKE_SYSTEM_PROCESSOR IN_LIST _all_archs)
set(_default_arch ${CMAKE_SYSTEM_PROCESSOR})
elseif(_bits EQUAL 32)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]")
set(_default_arch arm)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(_default_arch mips32)
else()
set(_default_arch i386)
endif()
else()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^[Aa][Rr][Mm]" OR CMAKE_SYSTEM_PROCESSOR
STREQUAL "aarch64"
)# armv8
set(_default_arch arm64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(_default_arch mips64)
else()
set(_default_arch x86_64)
endif()
endif()
set(NOVA_CONTEXT_ARCHITECTURE
"${_default_arch}"
CACHE
STRING
"Nova-Context architecture (arm, arm64, loongarch64, mips32, mips64, ppc32, ppc64, riscv64, s390x, i386, x86_64, combined)"
)
set_property(CACHE NOVA_CONTEXT_ARCHITECTURE PROPERTY STRINGS ${_all_archs})
unset(_all_archs)
unset(_bits)
unset(_default_arch)
# Assembler type
if(MSVC)
if(NOVA_CONTEXT_ARCHITECTURE STREQUAL arm64 OR NOVA_CONTEXT_ARCHITECTURE
STREQUAL arm)
set(_default_asm armasm)
else()
set(_default_asm masm)
endif()
else()
set(_default_asm gas)
endif()
set(NOVA_CONTEXT_ASSEMBLER
"${_default_asm}"
CACHE STRING "Nova-Context assembler (masm, gas, armasm)")
set_property(CACHE NOVA_CONTEXT_ASSEMBLER PROPERTY STRINGS masm gas armasm)
unset(_default_asm)
# Assembler source suffix
if(NOVA_CONTEXT_BINARY_FORMAT STREQUAL pe)
set(_default_ext .asm)
elseif(NOVA_CONTEXT_ASSEMBLER STREQUAL gas)
set(_default_ext .S)
else()
set(_default_ext .asm)
endif()
set(NOVA_CONTEXT_ASM_SUFFIX
"${_default_ext}"
CACHE STRING "Nova-Context assembler source suffix (.asm, .S)")
set_property(CACHE NOVA_CONTEXT_ASM_SUFFIX PROPERTY STRINGS .asm .S)
unset(_default_ext)
message(
STATUS "Nova-Context: "
"architecture ${NOVA_CONTEXT_ARCHITECTURE}, "
"binary format ${NOVA_CONTEXT_BINARY_FORMAT}, "
"ABI ${NOVA_CONTEXT_ABI}, "
"assembler ${NOVA_CONTEXT_ASSEMBLER}, "
"suffix ${NOVA_CONTEXT_ASM_SUFFIX}")
# Enable the right assembler
if(NOVA_CONTEXT_ASSEMBLER STREQUAL gas)
if(CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
enable_language(CXX ASM-ATT)
else()
enable_language(CXX ASM)
endif()
elseif(NOVA_CONTEXT_ASSEMBLER STREQUAL armasm)
enable_language(CXX ASM_ARMASM)
else()
enable_language(CXX ASM_MASM)
# NOTE(julian): workaround for CMake MSVC ASM_MASM building bug #18889:
# https://gitlab.kitware.com/cmake/cmake/-/issues/18889
set(CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY
"<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
endif()
# Choose .asm sources
if(NOVA_CONTEXT_BINARY_FORMAT STREQUAL mach-o)
set(NOVA_CONTEXT_BINARY_FORMAT macho)
endif()
set(_asm_suffix
"${NOVA_CONTEXT_ARCHITECTURE}_${NOVA_CONTEXT_ABI}_${NOVA_CONTEXT_BINARY_FORMAT}_${NOVA_CONTEXT_ASSEMBLER}${NOVA_CONTEXT_ASM_SUFFIX}"
)
set(ASM_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/asm/make_${_asm_suffix}
${CMAKE_CURRENT_SOURCE_DIR}/src/asm/jump_${_asm_suffix}
${CMAKE_CURRENT_SOURCE_DIR}/src/asm/ontop_${_asm_suffix})
unset(_asm_suffix)
set_source_files_properties(${ASM_SRC} PROPERTIES LINKER_LANGUAGE C)
# POWERPC_32/SYSV Special case: https://github.com/boostorg/context/issues/120
if((NOVA_CONTEXT_ARCHITECTURE STREQUAL ppc32) AND (NOVA_CONTEXT_ABI STREQUAL
sysv))
string(APPEND ASM_SRC " ${CMAKE_CURRENT_SOURCE_DIR}/asm/tail_ppc32_sysv.cpp")
endif()
# Assembly source file properties
if(NOVA_CONTEXT_ASSEMBLER STREQUAL masm AND NOVA_CONTEXT_ARCHITECTURE STREQUAL
i386)
set_source_files_properties(${ASM_SRC} PROPERTIES COMPILE_FLAGS "/safeseh")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
# set_source_files_properties(${ASM_SRC} PROPERTIES COMPILE_OPTIONS
# "-x assembler-with-cpp")
endif()
# Boost specific definitions
if(MSVC)
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
add_definitions(-D_HAS_EXCEPTIONS=0)
endif()
# Find project sources
file(GLOB_RECURSE INC ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c)
# Create target
if(NOVA_CONTEXT_BUILD_STATIC)
add_library(nova_context STATIC ${INC} ${SRC} ${ASM_SRC})
target_compile_definitions(nova_context PUBLIC NOVA_CONTEXT_STATIC
BOOST_CONTEXT_EXPORT=)
else()
add_library(nova_context SHARED ${INC} ${SRC} ${ASM_SRC})
target_compile_definitions(nova_context PUBLIC BOOST_CONTEXT_EXPORT=EXPORT)
endif()
# Link threading system dependencies if(WIN32)
# target_link_libraries(nova_context wsock32 ws2_32) endif() if
# (CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(nova_context
# pthread) endif()
# Position-independent code
if(NOVA_CONTEXT_PIC)
set_target_properties(nova_context PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
# Include directories
target_include_directories(
nova_context PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
if(NOVA_CONTEXT_BUILD_TEST)
# TODO(julian): Build test project
endif()
# Install library
if(NOVA_CONTEXT_INSTALL)
include(GNUInstallDirs)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN *.h)
install(
TARGETS nova_context
EXPORT nova-context-export
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(
EXPORT nova-context-export
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nova-context
FILE nova-context-config.cmake)
endif()

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen
Copyright (c) 2023 Julian Schönbächler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -0,0 +1,13 @@
# For the armasm assembler, armasm or armasm64
set(ASM_DIALECT "_ARMASM")
set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
# The ASM_ARMASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
include(CMakeASMInformation)
set(ASM_DIALECT)

View File

@ -0,0 +1,12 @@
# Find the armasm assembler, armasm or armasm64
set(ASM_DIALECT "_ARMASM")
# If we are using the 64bit cl compiler, assume we also want the 64bit assembler
if (";${CMAKE_VS_PLATFORM_NAME};${MSVC_C_ARCHITECTURE_ID};${MSVC_CXX_ARCHITECTURE_ID};" MATCHES ";ARM64;")
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm64)
else ()
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm)
endif ()
include(CMakeDetermineASMCompiler)
set(ASM_DIALECT)

View File

@ -0,0 +1,13 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# This file is used by EnableLanguage in cmGlobalGenerator to
# determine that the selected ASM_MASM "compiler" (should be masm or masm64)
# works. For assembler this can only check whether the compiler has been found,
# because otherwise there would have to be a separate assembler source file
# for each assembler on every architecture.
set(ASM_DIALECT "_ARMASM")
include(CMakeTestASMCompiler)
set(ASM_DIALECT)

View File

@ -0,0 +1,26 @@
/*
* Nova-Context
* This file is part of the Nova-Context library source code.
* Copyright (c) 2023 - The Nova Project
*/
#ifndef NOVA_CONTEXT_ASAN_H
#define NOVA_CONTEXT_ASAN_H
#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
#define NOVA_CONTEXT_ASAN
#ifdef __cplusplus
extern "C" {
#endif
void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
#ifdef __cplusplus
}
#endif
#endif
#endif //NOVA_CONTEXT_ASAN_H

View File

@ -0,0 +1,34 @@
/*
* Nova-Context
* This file is part of the Nova-Context library source code.
* Copyright (c) 2023 - The Nova Project
*/
#ifndef NOVA_CONTEXT_CONFIG_H
#define NOVA_CONTEXT_CONFIG_H
#ifndef NOVA_CONTEXT_STATIC
#ifdef nova_context_EXPORTS
#if defined(_MSC_VER) || defined(__MINGW32__)
#define NOVA_CONTEXT_API __declspec(dllexport)
#else
#define NOVA_CONTEXT_API __attribute__((__visibility__("default")))
#endif
#elif defined(_MSC_VER)
#define NOVA_CONTEXT_API __declspec(dllimport)
#endif
#else
#define NOVA_CONTEXT_API
#endif
#if (defined(i386) || defined(__i386__) || defined(__i386) || \
defined(__i486__) || defined(__i586__) || defined(__i686__) || \
defined(__X86__) || defined(_X86_) || defined(__THW_INTEL__) || \
defined(__I86__) || defined(__INTEL__) || defined(__IA32__) || \
defined(_M_IX86) || defined(_I86_)) && defined(BOOST_WINDOWS)
#define NOVA_CONTEXT_CALLDECL __cdecl
#else
#define NOVA_CONTEXT_CALLDECL
#endif
#endif //NOVA_CONTEXT_CONFIG_H

View File

@ -0,0 +1,42 @@
/*
* Nova-Context
* This file is part of the Nova-Context library source code.
* Copyright (c) 2023 - The Nova Project
*/
#ifndef NOVA_CONTEXT_FCONTEXT_H
#define NOVA_CONTEXT_FCONTEXT_H
#include <stdint.h>
#include <stddef.h>
#include "config.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void *fcontext_t;
typedef struct fcontext_transfer
{
fcontext_t fctx;
void *data;
} fcontext_transfer_t;
NOVA_CONTEXT_API
fcontext_t NOVA_CONTEXT_CALLDECL
make_fcontext(void *sp, size_t size, void (*fn)(fcontext_transfer_t));
NOVA_CONTEXT_API
fcontext_transfer_t NOVA_CONTEXT_CALLDECL
jump_fcontext(fcontext_t const to, void *vp);
NOVA_CONTEXT_API
fcontext_transfer_t NOVA_CONTEXT_CALLDECL
ontop_fcontext(fcontext_t const to, void *vp, fcontext_transfer_t (*fn)(fcontext_transfer_t));
#ifdef __cplusplus
}
#endif
#endif //NOVA_CONTEXT_FCONTEXT_H

View File

@ -0,0 +1,28 @@
/*
* Nova-Context
* This file is part of the Nova-Context library source code.
* Copyright (c) 2023 - The Nova Project
*/
#ifndef NOVA_CONTEXT_TSAN_H
#define NOVA_CONTEXT_TSAN_H
#if defined(__SANITIZER_THREAD__) || __has_feature(thread_sanitizer)
#define NOVA_CONTEXT_TSAN
#ifdef __cplusplus
extern "C" {
#endif
void *__tsan_get_current_fiber(void);
void *__tsan_create_fiber(unsigned flags);
void __tsan_destroy_fiber(void *fiber);
void __tsan_switch_to_fiber(void *fiber, unsigned flags);
#ifdef __cplusplus
}
#endif
#endif
#endif //NOVA_CONTEXT_TSAN_H

View File

@ -0,0 +1,114 @@
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | d8 | d9 | d10 | d11 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | d12 | d13 | d14 | d15 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | | | *
* ------------------------------------------------- *
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_arm64_aapcs_elf_gas.S"
.text
.align 2
.global jump_fcontext
.type jump_fcontext, %function
jump_fcontext:
# prepare stack for GP + FPU
sub sp, sp, #0xb0
# save d8 - d15
stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30]
# save x19-x30
stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80]
stp x29, x30, [sp, #0x90]
# save LR as PC
str x30, [sp, #0xa0]
# store RSP (pointing to context-data) in X0
mov x4, sp
# restore RSP (pointing to context-data) from X1
mov sp, x0
# load d8 - d15
ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30]
# load x19-x30
ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80]
ldp x29, x30, [sp, #0x90]
# return transfer_t from jump
# pass transfer_t as first arg in context function
# X0 == FCTX, X1 == DATA
mov x0, x4
# load pc
ldr x4, [sp, #0xa0]
# restore stack from GP + FPU
add sp, sp, #0xb0
ret x4
.size jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,109 @@
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | d8 | d9 | d10 | d11 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | d12 | d13 | d14 | d15 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | | | *
* ------------------------------------------------- *
* | 0xa0| 0xa4| 0xa8| 0xac| | | *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.balign 16
_jump_fcontext:
; prepare stack for GP + FPU
sub sp, sp, #0xb0
; save d8 - d15
stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30]
; save x19-x30
stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80]
stp fp, lr, [sp, #0x90]
; save LR as PC
str lr, [sp, #0xa0]
; store RSP (pointing to context-data) in X0
mov x4, sp
; restore RSP (pointing to context-data) from X1
mov sp, x0
; load d8 - d15
ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30]
; load x19-x30
ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80]
ldp fp, lr, [sp, #0x90]
; return transfer_t from jump
; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA
mov x0, x4
; load pc
ldr x4, [sp, #0xa0]
; restore stack from GP + FPU
add sp, sp, #0xb0
ret x4

View File

@ -0,0 +1,133 @@
; Copyright Edward Nevill + Oliver Kowalke 2015
; 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)
;*******************************************************
;* *
;* ------------------------------------------------- *
;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
;* ------------------------------------------------- *
;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- *
;* | fiber data| base | limit | dealloc | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- *
;* | PC | align | | | *
;* ------------------------------------------------- *
;* *
;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT jump_fcontext
jump_fcontext proc
; prepare stack for GP + FPU
sub sp, sp, #0xd0
; save d8 - d15
stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30]
; save x19-x30
stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80]
stp x29, x30, [sp, #0x90]
; save LR as PC
str x30, [sp, #0xc0]
; save current stack base and limit
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
stp x5, x6, [sp, #0xa0]
; save current fiber data and deallocation stack
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
stp x5, x6, [sp, #0xb0]
; store RSP (pointing to context-data) in X0
mov x4, sp
; restore RSP (pointing to context-data) from X1
mov sp, x0
; restore stack base and limit
ldp x5, x6, [sp, #0xa0]
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
; restore fiber data and deallocation stack
ldp x5, x6, [sp, #0xb0]
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
; load d8 - d15
ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30]
; load x19-x30
ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80]
ldp x29, x30, [sp, #0x90]
; return transfer_t from jump
; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA
mov x0, x4
; load pc
ldr x4, [sp, #0xc0]
; restore stack from GP + FPU
add sp, sp, #0xd0
ret x4
ENDP
END

View File

@ -0,0 +1,88 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_arm_aapcs_elf_gas.S"
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,%function
.syntax unified
jump_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ prepare stack for FPU
sub sp, sp, #64
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ save S16-S31
vstmia sp, {d8-d15}
#endif
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ restore S16-S31
vldmia sp, {d8-d15}
#endif
@ prepare stack for FPU
add sp, sp, #64
@ restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
@ return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
@ pass transfer_t as first arg in context function
@ A1 == FCTX, A2 == DATA
mov a2, a3
@ restore PC
pop {pc}
.size jump_fcontext,.-jump_fcontext
@ Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,95 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v7 | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ locate TLS to save/restore SjLj handler
mrc p15, 0, v2, c13, c0, #3
bic v2, v2, #3
@ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key]
ldr v1, [v2, #72]
@ save SjLj handler
push {v1}
@ prepare stack for FPU
sub sp, sp, #64
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ save S16-S31
vstmia sp, {d8-d15}
#endif
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ restore S16-S31
vldmia sp, {d8-d15}
#endif
@ prepare stack for FPU
add sp, sp, #64
@ r#estore SjLj handler
pop {v1}
@ store SjLj handler in TLS
str v1, [v2, #72]
@ restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
@ return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
@ pass transfer_t as first arg in context function
@ A1 == FCTX, A2 == DATA
mov a2, a3
@ restore PC
pop {pc}

View File

@ -0,0 +1,81 @@
;/*
; Copyright Oliver Kowalke 2009.
; 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)
;*/
; *******************************************************
; * *
; * ------------------------------------------------- *
; * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
; * ------------------------------------------------- *
; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
; * ------------------------------------------------- *
; * |deall|limit| base|hiddn| v1 | v2 | v3 | v4 | *
; * ------------------------------------------------- *
; * ------------------------------------------------- *
; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
; * ------------------------------------------------- *
; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
; * ------------------------------------------------- *
; * | v5 | v6 | v7 | v8 | lr | pc | FCTX| DATA| *
; * ------------------------------------------------- *
; * *
; *******************************************************
AREA |.text|, CODE
ALIGN 4
EXPORT jump_fcontext
jump_fcontext PROC
; save LR as PC
push {lr}
; save hidden,V1-V8,LR
push {a1,v1-v8,lr}
; load TIB to save/restore thread size and limit.
; we do not need preserve CPU flag and can use it's arg register
mrc p15, #0, v1, c13, c0, #2
; save current stack base
ldr a5, [v1, #0x04]
push {a5}
; save current stack limit
ldr a5, [v1, #0x08]
push {a5}
; save current deallocation stack
ldr a5, [v1, #0xe0c]
push {a5}
; store RSP (pointing to context-data) in A1
mov a1, sp
; restore RSP (pointing to context-data) from A2
mov sp, a2
; restore deallocation stack
pop {a5}
str a5, [v1, #0xe0c]
; restore stack limit
pop {a5}
str a5, [v1, #0x08]
; restore stack base
pop {a5}
str a5, [v1, #0x04]
; restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
; return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
; pass transfer_t as first arg in context function
; A1 == FCTX, A2 == DATA
mov a2, a3
; restore PC
pop {pc}
ENDP
END

View File

@ -0,0 +1,24 @@
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "jump_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "jump_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "jump_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "jump_ppc64_sysv_macho_gas.S"
#elif defined(__arm__)
#include "jump_arm_aapcs_macho_gas.S"
#elif defined(__arm64__)
#include "jump_arm64_aapcs_macho_gas.S"
#else
#error "No arch's"
#endif

View File

@ -0,0 +1,123 @@
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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)
*/
/*************************************************************************************
* --------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* --------------------------------------------------------------------------------- *
* | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | *
* --------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | *
* --------------------------------------------------------------------------------- *
* --------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* --------------------------------------------------------------------------------- *
* | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | *
* --------------------------------------------------------------------------------- *
* | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR| *
* --------------------------------------------------------------------------------- *
**************************************************************************************/
.file "jump_i386_ms_pe_clang_gas.S"
.text
.p2align 4,,15
/* mark as using no unregistered SEH handlers */
.globl @feat.00
.def @feat.00; .scl 3; .type 0; .endef
.set @feat.00, 1
.globl _jump_fcontext
.def _jump_fcontext; .scl 2; .type 32; .endef
_jump_fcontext:
/* prepare stack */
leal -0x2c(%esp), %esp
#if !defined(BOOST_USE_TSX)
/* save MMX control- and status-word */
stmxcsr (%esp)
/* save x87 control-word */
fnstcw 0x4(%esp)
#endif
/* load NT_TIB */
movl %fs:(0x18), %edx
/* load fiber local storage */
movl 0x10(%edx), %eax
movl %eax, 0x8(%esp)
/* load current dealloction stack */
movl 0xe0c(%edx), %eax
movl %eax, 0xc(%esp)
/* load current stack limit */
movl 0x8(%edx), %eax
movl %eax, 0x10(%esp)
/* load current stack base */
movl 0x4(%edx), %eax
movl %eax, 0x14(%esp)
/* load current SEH exception list */
movl (%edx), %eax
movl %eax, 0x18(%esp)
movl %edi, 0x1c(%esp) /* save EDI */
movl %esi, 0x20(%esp) /* save ESI */
movl %ebx, 0x24(%esp) /* save EBX */
movl %ebp, 0x28(%esp) /* save EBP */
/* store ESP (pointing to context-data) in EAX */
movl %esp, %eax
/* firstarg of jump_fcontext() == fcontext to jump to */
movl 0x30(%esp), %ecx
/* restore ESP (pointing to context-data) from ECX */
movl %ecx, %esp
#if !defined(BOOST_USE_TSX)
/* restore MMX control- and status-word */
ldmxcsr (%esp)
/* restore x87 control-word */
fldcw 0x4(%esp)
#endif
/* restore NT_TIB into EDX */
movl %fs:(0x18), %edx
/* restore fiber local storage */
movl 0x8(%esp), %ecx
movl %ecx, 0x10(%edx)
/* restore current deallocation stack */
movl 0xc(%esp), %ecx
movl %ecx, 0xe0c(%edx)
/* restore current stack limit */
movl 0x10(%esp), %ecx
movl %ecx, 0x8(%edx)
/* restore current stack base */
movl 0x14(%esp), %ecx
movl %ecx, 0x4(%edx)
/* restore current SEH exception list */
movl 0x18(%esp), %ecx
movl %ecx, (%edx)
movl 0x2c(%esp), %ecx /* restore EIP */
movl 0x1c(%esp), %edi /* restore EDI */
movl 0x20(%esp), %esi /* restore ESI */
movl 0x24(%esp), %ebx /* restore EBX */
movl 0x28(%esp), %ebp /* restore EBP */
/* prepare stack */
leal 0x30(%esp), %esp
/* return transfer_t */
/* FCTX == EAX, DATA == EDX */
movl 0x34(%eax), %edx
/* jump to context */
jmp *%ecx
.section .drectve
.ascii " -export:\"_jump_fcontext\""

View File

@ -0,0 +1,123 @@
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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)
*/
/*************************************************************************************
* --------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* --------------------------------------------------------------------------------- *
* | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | *
* --------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | *
* --------------------------------------------------------------------------------- *
* --------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* --------------------------------------------------------------------------------- *
* | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | *
* --------------------------------------------------------------------------------- *
* | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR| *
* --------------------------------------------------------------------------------- *
**************************************************************************************/
.file "jump_i386_ms_pe_gas.asm"
.text
.p2align 4,,15
/* mark as using no unregistered SEH handlers */
.globl @feat.00
.def @feat.00; .scl 3; .type 0; .endef
.set @feat.00, 1
.globl _jump_fcontext
.def _jump_fcontext; .scl 2; .type 32; .endef
_jump_fcontext:
/* prepare stack */
leal -0x2c(%esp), %esp
#if !defined(BOOST_USE_TSX)
/* save MMX control- and status-word */
stmxcsr (%esp)
/* save x87 control-word */
fnstcw 0x4(%esp)
#endif
/* load NT_TIB */
movl %fs:(0x18), %edx
/* load fiber local storage */
movl 0x10(%edx), %eax
movl %eax, 0x8(%esp)
/* load current dealloction stack */
movl 0xe0c(%edx), %eax
movl %eax, 0xc(%esp)
/* load current stack limit */
movl 0x8(%edx), %eax
movl %eax, 0x10(%esp)
/* load current stack base */
movl 0x4(%edx), %eax
movl %eax, 0x14(%esp)
/* load current SEH exception list */
movl (%edx), %eax
movl %eax, 0x18(%esp)
movl %edi, 0x1c(%esp) /* save EDI */
movl %esi, 0x20(%esp) /* save ESI */
movl %ebx, 0x24(%esp) /* save EBX */
movl %ebp, 0x28(%esp) /* save EBP */
/* store ESP (pointing to context-data) in EAX */
movl %esp, %eax
/* firstarg of jump_fcontext() == fcontext to jump to */
movl 0x30(%esp), %ecx
/* restore ESP (pointing to context-data) from ECX */
movl %ecx, %esp
#if !defined(BOOST_USE_TSX)
/* restore MMX control- and status-word */
ldmxcsr (%esp)
/* restore x87 control-word */
fldcw 0x4(%esp)
#endif
/* restore NT_TIB into EDX */
movl %fs:(0x18), %edx
/* restore fiber local storage */
movl 0x8(%esp), %ecx
movl %ecx, 0x10(%edx)
/* restore current deallocation stack */
movl 0xc(%esp), %ecx
movl %ecx, 0xe0c(%edx)
/* restore current stack limit */
movl 0x10(%esp), %ecx
movl %ecx, 0x8(%edx)
/* restore current stack base */
movl 0x14(%esp), %ecx
movl %ecx, 0x4(%edx)
/* restore current SEH exception list */
movl 0x18(%esp), %ecx
movl %ecx, (%edx)
movl 0x2c(%esp), %ecx /* restore EIP */
movl 0x1c(%esp), %edi /* restore EDI */
movl 0x20(%esp), %esi /* restore ESI */
movl 0x24(%esp), %ebx /* restore EBX */
movl 0x28(%esp), %ebp /* restore EBP */
/* prepare stack */
leal 0x30(%esp), %esp
/* return transfer_t */
/* FCTX == EAX, DATA == EDX */
movl 0x34(%eax), %edx
/* jump to context */
jmp *%ecx
.section .drectve
.ascii " -export:\"jump_fcontext\""

View File

@ -0,0 +1,116 @@
; Copyright Oliver Kowalke 2009.
; 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)
; ---------------------------------------------------------------------------------
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
; ---------------------------------------------------------------------------------
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
; ---------------------------------------------------------------------------------
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
; ---------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ---------------------------------------------------------------------------------
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
; ---------------------------------------------------------------------------------
; | ESI | EBX | EBP | EIP | to | data | EH NXT |SEH HNDLR|
; ---------------------------------------------------------------------------------
.386
.XMM
.model flat, c
.code
jump_fcontext PROC BOOST_CONTEXT_EXPORT
; prepare stack
lea esp, [esp-02ch]
IFNDEF BOOST_USE_TSX
; save MMX control- and status-word
stmxcsr [esp]
; save x87 control-word
fnstcw [esp+04h]
ENDIF
assume fs:nothing
; load NT_TIB into ECX
mov edx, fs:[018h]
assume fs:error
; load fiber local storage
mov eax, [edx+010h]
mov [esp+08h], eax
; load current deallocation stack
mov eax, [edx+0e0ch]
mov [esp+0ch], eax
; load current stack limit
mov eax, [edx+08h]
mov [esp+010h], eax
; load current stack base
mov eax, [edx+04h]
mov [esp+014h], eax
; load current SEH exception list
mov eax, [edx]
mov [esp+018h], eax
mov [esp+01ch], edi ; save EDI
mov [esp+020h], esi ; save ESI
mov [esp+024h], ebx ; save EBX
mov [esp+028h], ebp ; save EBP
; store ESP (pointing to context-data) in EAX
mov eax, esp
; firstarg of jump_fcontext() == fcontext to jump to
mov ecx, [esp+030h]
; restore ESP (pointing to context-data) from ECX
mov esp, ecx
IFNDEF BOOST_USE_TSX
; restore MMX control- and status-word
ldmxcsr [esp]
; restore x87 control-word
fldcw [esp+04h]
ENDIF
assume fs:nothing
; load NT_TIB into EDX
mov edx, fs:[018h]
assume fs:error
; restore fiber local storage
mov ecx, [esp+08h]
mov [edx+010h], ecx
; restore current deallocation stack
mov ecx, [esp+0ch]
mov [edx+0e0ch], ecx
; restore current stack limit
mov ecx, [esp+010h]
mov [edx+08h], ecx
; restore current stack base
mov ecx, [esp+014h]
mov [edx+04h], ecx
; restore current SEH exception list
mov ecx, [esp+018h]
mov [edx], ecx
mov ecx, [esp+02ch] ; restore EIP
mov edi, [esp+01ch] ; restore EDI
mov esi, [esp+020h] ; restore ESI
mov ebx, [esp+024h] ; restore EBX
mov ebp, [esp+028h] ; restore EBP
; prepare stack
lea esp, [esp+030h]
; return transfer_t
; FCTX == EAX, DATA == EDX
mov edx, [eax+034h]
; jump to context
jmp ecx
jump_fcontext ENDP
END

View File

@ -0,0 +1,93 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| guard | EDI | ESI | EBX | EBP | EIP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | | *
* ---------------------------------------------------------------------------------- *
* | hidden | to | data | | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.file "jump_i386_sysv_elf_gas.S"
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
jump_fcontext:
leal -0x1c(%esp), %esp /* prepare stack */
#if !defined(BOOST_USE_TSX)
stmxcsr (%esp) /* save MMX control- and status-word */
fnstcw 0x4(%esp) /* save x87 control-word */
#endif
#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR)
movl %gs:0x14, %ecx /* read stack guard from TLS record */
movl %ecx, 0x8(%esp) /* save stack guard */
#endif
movl %edi, 0xc(%esp) /* save EDI */
movl %esi, 0x10(%esp) /* save ESI */
movl %ebx, 0x14(%esp) /* save EBX */
movl %ebp, 0x18(%esp) /* save EBP */
/* store ESP (pointing to context-data) in ECX */
movl %esp, %ecx
/* first arg of jump_fcontext() == fcontext to jump to */
movl 0x24(%esp), %eax
/* second arg of jump_fcontext() == data to be transferred */
movl 0x28(%esp), %edx
/* restore ESP (pointing to context-data) from EAX */
movl %eax, %esp
/* address of returned transport_t */
movl 0x20(%esp), %eax
/* return parent fcontext_t */
movl %ecx, (%eax)
/* return data */
movl %edx, 0x4(%eax)
movl 0x1c(%esp), %ecx /* restore EIP */
#if !defined(BOOST_USE_TSX)
ldmxcsr (%esp) /* restore MMX control- and status-word */
fldcw 0x4(%esp) /* restore x87 control-word */
#endif
#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR)
movl 0x8(%esp), %edx /* load stack guard */
movl %edx, %gs:0x14 /* restore stack guard to TLS record */
#endif
movl 0xc(%esp), %edi /* restore EDI */
movl 0x10(%esp), %esi /* restore ESI */
movl 0x14(%esp), %ebx /* restore EBX */
movl 0x18(%esp), %ebp /* restore EBP */
leal 0x24(%esp), %esp /* prepare stack */
/* jump to context */
jmp *%ecx
.size jump_fcontext,.-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,74 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | to | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | | *
* ---------------------------------------------------------------------------------- *
* | data | | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
leal -0x18(%esp), %esp /* prepare stack */
#if !defined(BOOST_USE_TSX)
stmxcsr (%esp) /* save MMX control- and status-word */
fnstcw 0x4(%esp) /* save x87 control-word */
#endif
movl %edi, 0x8(%esp) /* save EDI */
movl %esi, 0xc(%esp) /* save ESI */
movl %ebx, 0x10(%esp) /* save EBX */
movl %ebp, 0x14(%esp) /* save EBP */
/* store ESP (pointing to context-data) in ECX */
movl %esp, %ecx
/* first arg of jump_fcontext() == fcontext to jump to */
movl 0x1c(%esp), %eax
/* second arg of jump_fcontext() == data to be transferred */
movl 0x20(%esp), %edx
/* restore ESP (pointing to context-data) from EAX */
movl %eax, %esp
/* return parent fcontext_t */
movl %ecx, %eax
/* returned data is stored in EDX */
movl 0x18(%esp), %ecx /* restore EIP */
#if !defined(BOOST_USE_TSX)
ldmxcsr (%esp) /* restore MMX control- and status-word */
fldcw 0x4(%esp) /* restore x87 control-word */
#endif
movl 0x8(%esp), %edi /* restore EDI */
movl 0xc(%esp), %esi /* restore ESI */
movl 0x10(%esp), %ebx /* restore EBX */
movl 0x14(%esp), %ebp /* restore EBP */
leal 0x1c(%esp), %esp /* prepare stack */
/* jump to context */
jmp *%ecx

View File

@ -0,0 +1,16 @@
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "jump_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "jump_x86_64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif

View File

@ -0,0 +1,121 @@
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 8 | 16 | 24 | *
* ------------------------------------------------- *
* | FS0 | FS1 | FS2 | FS3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 40 | 48 | 56 | *
* ------------------------------------------------- *
* | FS4 | FS5 | FS6 | FS7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 72 | 80 | 88 | *
* ------------------------------------------------- *
* | S0 | S1 | S2 | S3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | S4 | S5 | S6 | S7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | S8 | FP | RA | PC | *
* ------------------------------------------------- *
* *
* *****************************************************/
.file "jump_loongarch64_sysv_elf_gas.S"
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
jump_fcontext:
# reserve space on stack
addi.d $sp, $sp, -160
# save fs0 - fs7
fst.d $fs0, $sp, 0
fst.d $fs1, $sp, 8
fst.d $fs2, $sp, 16
fst.d $fs3, $sp, 24
fst.d $fs4, $sp, 32
fst.d $fs5, $sp, 40
fst.d $fs6, $sp, 48
fst.d $fs7, $sp, 56
# save s0 - s8, fp, ra
st.d $s0, $sp, 64
st.d $s1, $sp, 72
st.d $s2, $sp, 80
st.d $s3, $sp, 88
st.d $s4, $sp, 96
st.d $s5, $sp, 104
st.d $s6, $sp, 112
st.d $s7, $sp, 120
st.d $s8, $sp, 128
st.d $fp, $sp, 136
st.d $ra, $sp, 144
# save RA as PC
st.d $ra, $sp, 152
# store SP (pointing to context-data) in A2
move $a2, $sp
# restore SP (pointing to context-data) from A0
move $sp, $a0
# load fs0 - fs7
fld.d $fs0, $sp, 0
fld.d $fs1, $sp, 8
fld.d $fs2, $sp, 16
fld.d $fs3, $sp, 24
fld.d $fs4, $sp, 32
fld.d $fs5, $sp, 40
fld.d $fs6, $sp, 48
fld.d $fs7, $sp, 56
#load s0 - s7
ld.d $s0, $sp, 64
ld.d $s1, $sp, 72
ld.d $s2, $sp, 80
ld.d $s3, $sp, 88
ld.d $s4, $sp, 96
ld.d $s5, $sp, 104
ld.d $s6, $sp, 112
ld.d $s7, $sp, 120
ld.d $s8, $sp, 128
ld.d $fp, $sp, 136
ld.d $ra, $sp, 144
# return transfer_t from jump
# pass transfer_t as first arg in context function
# a0 == FCTX, a1 == DATA
move $a0, $a2
# load PC
ld.d $a2, $sp, 152
# restore stack
addi.d $sp, $sp, 160
# jump to context
jr $a2
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,119 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | F20 | F22 | F24 | F26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | F28 | F30 | S0 | S1 | S2 | S3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | S4 | S5 | S6 | S7 | FP |hiddn| RA | PC | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | ABI ARGS | GP | FCTX| DATA| | *
* ------------------------------------------------- *
* *
* *****************************************************/
.file "jump_mips32_o32_elf_gas.S"
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
.ent jump_fcontext
jump_fcontext:
# reserve space on stack
addiu $sp, $sp, -96
sw $s0, 48($sp) # save S0
sw $s1, 52($sp) # save S1
sw $s2, 56($sp) # save S2
sw $s3, 60($sp) # save S3
sw $s4, 64($sp) # save S4
sw $s5, 68($sp) # save S5
sw $s6, 72($sp) # save S6
sw $s7, 76($sp) # save S7
sw $fp, 80($sp) # save FP
sw $a0, 84($sp) # save hidden, address of returned transfer_t
sw $ra, 88($sp) # save RA
sw $ra, 92($sp) # save RA as PC
#if defined(__mips_hard_float)
s.d $f20, ($sp) # save F20
s.d $f22, 8($sp) # save F22
s.d $f24, 16($sp) # save F24
s.d $f26, 24($sp) # save F26
s.d $f28, 32($sp) # save F28
s.d $f30, 40($sp) # save F30
#endif
# store SP (pointing to context-data) in A0
move $a0, $sp
# restore SP (pointing to context-data) from A1
move $sp, $a1
#if defined(__mips_hard_float)
l.d $f20, ($sp) # restore F20
l.d $f22, 8($sp) # restore F22
l.d $f24, 16($sp) # restore F24
l.d $f26, 24($sp) # restore F26
l.d $f28, 32($sp) # restore F28
l.d $f30, 40($sp) # restore F30
#endif
lw $s0, 48($sp) # restore S0
lw $s1, 52($sp) # restore S1
lw $s2, 56($sp) # restore S2
lw $s3, 60($sp) # restore S3
lw $s4, 64($sp) # restore S4
lw $s5, 68($sp) # restore S5
lw $s6, 72($sp) # restore S6
lw $s7, 76($sp) # restore S7
lw $fp, 80($sp) # restore FP
lw $v0, 84($sp) # restore hidden, address of returned transfer_t
lw $ra, 88($sp) # restore RA
# load PC
lw $t9, 92($sp)
# adjust stack
addiu $sp, $sp, 96
# return transfer_t from jump
sw $a0, ($v0) # fctx of transfer_t
sw $a2, 4($v0) # data of transfer_t
# pass transfer_t as first arg in context function
# A0 == fctx, A1 == data
move $a1, $a2
# jump to context
jr $t9
.end jump_fcontext
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,124 @@
/*
Copyright Jiaxun Yang 2018.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 8 | 16 | 24 | *
* ------------------------------------------------- *
* | F24 | F25 | F26 | F27 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 40 | 48 | 56 | *
* ------------------------------------------------- *
* | F28 | F29 | F30 | F31 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 72 | 80 | 88 | *
* ------------------------------------------------- *
* | S0 | S1 | S2 | S3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | S4 | S5 | S6 | S7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | FP | GP | RA | PC | *
* ------------------------------------------------- *
* *
* *****************************************************/
.file "jump_mips64_n64_elf_gas.S"
.text
.globl jump_fcontext
.align 3
.type jump_fcontext,@function
.ent jump_fcontext
jump_fcontext:
# reserve space on stack
daddiu $sp, $sp, -160
sd $s0, 64($sp) # save S0
sd $s1, 72($sp) # save S1
sd $s2, 80($sp) # save S2
sd $s3, 88($sp) # save S3
sd $s4, 96($sp) # save S4
sd $s5, 104($sp) # save S5
sd $s6, 112($sp) # save S6
sd $s7, 120($sp) # save S7
sd $fp, 128($sp) # save FP
sd $ra, 144($sp) # save RA
sd $ra, 152($sp) # save RA as PC
#if defined(__mips_hard_float)
s.d $f24, 0($sp) # save F24
s.d $f25, 8($sp) # save F25
s.d $f26, 16($sp) # save F26
s.d $f27, 24($sp) # save F27
s.d $f28, 32($sp) # save F28
s.d $f29, 40($sp) # save F29
s.d $f30, 48($sp) # save F30
s.d $f31, 56($sp) # save F31
#endif
# store SP (pointing to old context-data) in v0 as return
move $v0, $sp
# get SP (pointing to new context-data) from a0 param
move $sp, $a0
#if defined(__mips_hard_float)
l.d $f24, 0($sp) # restore F24
l.d $f25, 8($sp) # restore F25
l.d $f26, 16($sp) # restore F26
l.d $f27, 24($sp) # restore F27
l.d $f28, 32($sp) # restore F28
l.d $f29, 40($sp) # restore F29
l.d $f30, 48($sp) # restore F30
l.d $f31, 56($sp) # restore F31
#endif
ld $s0, 64($sp) # restore S0
ld $s1, 72($sp) # restore S1
ld $s2, 80($sp) # restore S2
ld $s3, 88($sp) # restore S3
ld $s4, 96($sp) # restore S4
ld $s5, 104($sp) # restore S5
ld $s6, 112($sp) # restore S6
ld $s7, 120($sp) # restore S7
ld $fp, 128($sp) # restore FP
ld $ra, 144($sp) # restore RAa
# load PC
ld $t9, 152($sp)
# adjust stack
daddiu $sp, $sp, 160
move $a0, $v0 # move old sp from v0 to a0 as param
move $v1, $a1 # move *data from a1 to v1 as return
# jump to context
jr $t9
.end jump_fcontext
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,16 @@
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__ppc__)
#include "jump_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "jump_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif

View File

@ -0,0 +1,201 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* |bchai|hiddn| fpscr | PC | CR | R14 | R15 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | F14 | F15 | F16 | F17 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | F18 | F19 | F20 | F21 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | F22 | F23 | F24 | F25 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | F26 | F27 | F28 | F29 | *
* ------------------------------------------------- *
* ------------------------|------------ *
* | 224 | 228 | 232 | 236 | 240 | 244 | *
* ------------------------|------------ *
* | F30 | F31 |bchai| LR | *
* ------------------------|------------ *
* *
*******************************************************/
.file "jump_ppc32_sysv_elf_gas.S"
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
jump_fcontext:
# Linux: jump_fcontext( hidden transfer_t * R3, R4, R5)
# Other: transfer_t R3:R4 = jump_fcontext( R3, R4)
mflr %r0 # return address from LR
mffs %f0 # FPSCR
mfcr %r8 # condition register
stwu %r1, -240(%r1) # allocate stack space, R1 % 16 == 0
stw %r0, 244(%r1) # save LR in caller's frame
#ifdef __linux__
stw %r3, 4(%r1) # hidden pointer
#endif
stfd %f0, 8(%r1) # FPSCR
stw %r0, 16(%r1) # LR as PC
stw %r8, 20(%r1) # CR
# Save registers R14 to R31.
# Don't change R2, the thread-local storage pointer.
# Don't change R13, the small data pointer.
stw %r14, 24(%r1)
stw %r15, 28(%r1)
stw %r16, 32(%r1)
stw %r17, 36(%r1)
stw %r18, 40(%r1)
stw %r19, 44(%r1)
stw %r20, 48(%r1)
stw %r21, 52(%r1)
stw %r22, 56(%r1)
stw %r23, 60(%r1)
stw %r24, 64(%r1)
stw %r25, 68(%r1)
stw %r26, 72(%r1)
stw %r27, 76(%r1)
stw %r28, 80(%r1)
stw %r29, 84(%r1)
stw %r30, 88(%r1)
stw %r31, 92(%r1)
# Save registers F14 to F31 in slots with 8-byte alignment.
# 4-byte alignment may stall the pipeline of some processors.
# Less than 4 may cause alignment traps.
stfd %f14, 96(%r1)
stfd %f15, 104(%r1)
stfd %f16, 112(%r1)
stfd %f17, 120(%r1)
stfd %f18, 128(%r1)
stfd %f19, 136(%r1)
stfd %f20, 144(%r1)
stfd %f21, 152(%r1)
stfd %f22, 160(%r1)
stfd %f23, 168(%r1)
stfd %f24, 176(%r1)
stfd %f25, 184(%r1)
stfd %f26, 192(%r1)
stfd %f27, 200(%r1)
stfd %f28, 208(%r1)
stfd %f29, 216(%r1)
stfd %f30, 224(%r1)
stfd %f31, 232(%r1)
# store RSP (pointing to context-data) in R7/R6
# restore RSP (pointing to context-data) from R4/R3
#ifdef __linux__
mr %r7, %r1
mr %r1, %r4
lwz %r3, 4(%r1) # hidden pointer
#else
mr %r6, %r1
mr %r1, %r3
#endif
lfd %f0, 8(%r1) # FPSCR
lwz %r0, 16(%r1) # PC
lwz %r8, 20(%r1) # CR
mtfsf 0xff, %f0 # restore FPSCR
mtctr %r0 # load CTR with PC
mtcr %r8 # restore CR
# restore R14 to R31
lwz %r14, 24(%r1)
lwz %r15, 28(%r1)
lwz %r16, 32(%r1)
lwz %r17, 36(%r1)
lwz %r18, 40(%r1)
lwz %r19, 44(%r1)
lwz %r20, 48(%r1)
lwz %r21, 52(%r1)
lwz %r22, 56(%r1)
lwz %r23, 60(%r1)
lwz %r24, 64(%r1)
lwz %r25, 68(%r1)
lwz %r26, 72(%r1)
lwz %r27, 76(%r1)
lwz %r28, 80(%r1)
lwz %r29, 84(%r1)
lwz %r30, 88(%r1)
lwz %r31, 92(%r1)
# restore F14 to F31
lfd %f14, 96(%r1)
lfd %f15, 104(%r1)
lfd %f16, 112(%r1)
lfd %f17, 120(%r1)
lfd %f18, 128(%r1)
lfd %f19, 136(%r1)
lfd %f20, 144(%r1)
lfd %f21, 152(%r1)
lfd %f22, 160(%r1)
lfd %f23, 168(%r1)
lfd %f24, 176(%r1)
lfd %f25, 184(%r1)
lfd %f26, 192(%r1)
lfd %f27, 200(%r1)
lfd %f28, 208(%r1)
lfd %f29, 216(%r1)
lfd %f30, 224(%r1)
lfd %f31, 232(%r1)
# restore LR from caller's frame
lwz %r0, 244(%r1)
mtlr %r0
# adjust stack
addi %r1, %r1, 240
# return transfer_t
#ifdef __linux__
stw %r7, 0(%r3)
stw %r5, 4(%r3)
#else
mr %r3, %r6
# %r4, %r4
#endif
# jump to context
bctr
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,201 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | F14 | F15 | F16 | F17 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | F18 | F19 | F20 | F21 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | F22 | F23 | F24 | F25 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | F26 | F27 | F28 | F29 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | F30 | F31 | fpscr | R13 | R14 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | R31 |hiddn| CR | LR | PC |bchai|linkr| FCTX| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 64 | | *
* ------------------------------------------------- *
* | 256 | | *
* ------------------------------------------------- *
* | DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
; reserve space on stack
subi r1, r1, 244
stfd f14, 0(r1) ; save F14
stfd f15, 8(r1) ; save F15
stfd f16, 16(r1) ; save F16
stfd f17, 24(r1) ; save F17
stfd f18, 32(r1) ; save F18
stfd f19, 40(r1) ; save F19
stfd f20, 48(r1) ; save F20
stfd f21, 56(r1) ; save F21
stfd f22, 64(r1) ; save F22
stfd f23, 72(r1) ; save F23
stfd f24, 80(r1) ; save F24
stfd f25, 88(r1) ; save F25
stfd f26, 96(r1) ; save F26
stfd f27, 104(r1) ; save F27
stfd f28, 112(r1) ; save F28
stfd f29, 120(r1) ; save F29
stfd f30, 128(r1) ; save F30
stfd f31, 136(r1) ; save F31
mffs f0 ; load FPSCR
stfd f0, 144(r1) ; save FPSCR
stw r13, 152(r1) ; save R13
stw r14, 156(r1) ; save R14
stw r15, 160(r1) ; save R15
stw r16, 164(r1) ; save R16
stw r17, 168(r1) ; save R17
stw r18, 172(r1) ; save R18
stw r19, 176(r1) ; save R19
stw r20, 180(r1) ; save R20
stw r21, 184(r1) ; save R21
stw r22, 188(r1) ; save R22
stw r23, 192(r1) ; save R23
stw r24, 196(r1) ; save R24
stw r25, 200(r1) ; save R25
stw r26, 204(r1) ; save R26
stw r27, 208(r1) ; save R27
stw r28, 212(r1) ; save R28
stw r29, 216(r1) ; save R29
stw r30, 220(r1) ; save R30
stw r31, 224(r1) ; save R31
stw r3, 228(r1) ; save hidden
; save CR
mfcr r0
stw r0, 232(r1)
; save LR
mflr r0
stw r0, 236(r1)
; save LR as PC
stw r0, 240(r1)
; store RSP (pointing to context-data) in R6
mr r6, r1
; restore RSP (pointing to context-data) from R4
mr r1, r4
lfd f14, 0(r1) ; restore F14
lfd f15, 8(r1) ; restore F15
lfd f16, 16(r1) ; restore F16
lfd f17, 24(r1) ; restore F17
lfd f18, 32(r1) ; restore F18
lfd f19, 40(r1) ; restore F19
lfd f20, 48(r1) ; restore F20
lfd f21, 56(r1) ; restore F21
lfd f22, 64(r1) ; restore F22
lfd f23, 72(r1) ; restore F23
lfd f24, 80(r1) ; restore F24
lfd f25, 88(r1) ; restore F25
lfd f26, 96(r1) ; restore F26
lfd f27, 104(r1) ; restore F27
lfd f28, 112(r1) ; restore F28
lfd f29, 120(r1) ; restore F29
lfd f30, 128(r1) ; restore F30
lfd f31, 136(r1) ; restore F31
lfd f0, 144(r1) ; load FPSCR
mtfsf 0xff, f0 ; restore FPSCR
lwz r13, 152(r1) ; restore R13
lwz r14, 156(r1) ; restore R14
lwz r15, 160(r1) ; restore R15
lwz r16, 164(r1) ; restore R16
lwz r17, 168(r1) ; restore R17
lwz r18, 172(r1) ; restore R18
lwz r19, 176(r1) ; restore R19
lwz r20, 180(r1) ; restore R20
lwz r21, 184(r1) ; restore R21
lwz r22, 188(r1) ; restore R22
lwz r23, 192(r1) ; restore R23
lwz r24, 196(r1) ; restore R24
lwz r25, 200(r1) ; restore R25
lwz r26, 204(r1) ; restore R26
lwz r27, 208(r1) ; restore R27
lwz r28, 212(r1) ; restore R28
lwz r29, 216(r1) ; restore R29
lwz r30, 220(r1) ; restore R30
lwz r31, 224(r1) ; restore R31
lwz r3, 228(r1) ; restore hidden
; restore CR
lwz r0, 232(r1)
mtcr r0
; restore LR
lwz r0, 236(r1)
mtlr r0
; load PC
lwz r0, 240(r1)
; restore CTR
mtctr r0
; adjust stack
addi r1, r1, 244
; return transfer_t
stw r6, 0(r3)
stw r5, 4(r3)
; jump to context
bctr

View File

@ -0,0 +1,216 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* |bchai| CR | LR |compl| link| TOC | R14 | R15 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | F14 | F15 | F16 | F17 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | F18 | F19 | F20 | F21 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | F22 | F23 | F24 | F25 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | F26 | F27 | F28 | F29 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | F30 | F31 | PC |hiddn| fpscr | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | *
* ------------------------------------------------- *
* |bchai|savCR|savLR|compl| link|svTOC| FCTX| DATA| *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_ppc32_sysv_xcoff_gas.S"
.toc
.csect .text[PR], 5
.globl jump_fcontext[DS]
.globl .jump_fcontext
.csect jump_fcontext[DS]
jump_fcontext:
.long .jump_fcontext[PR], TOC[tc0], 0
.csect .text[PR], 5
.jump_fcontext:
# reserve space on stack
subi 1, 1, 256
# save CR
mfcr 0
stw 0, 4(1)
# save LR
mflr 0
stw 0, 8(1)
# save LR as PC
stw 0, 240(1)
# save TOC
stw 2, 20(1)
# Save registers R14 to R31.
stw 14, 24(1)
stw 15, 28(1)
stw 16, 32(1)
stw 17, 36(1)
stw 18, 40(1)
stw 19, 44(1)
stw 20, 48(1)
stw 21, 52(1)
stw 22, 56(1)
stw 23, 60(1)
stw 24, 64(1)
stw 25, 68(1)
stw 26, 72(1)
stw 27, 76(1)
stw 28, 80(1)
stw 29, 84(1)
stw 30, 88(1)
stw 31, 92(1)
# Save registers F14 to F31 in slots with 8-byte alignment.
# 4-byte alignment may stall the pipeline of some processors.
# Less than 4 may cause alignment traps.
stfd 14, 96(1)
stfd 15, 104(1)
stfd 16, 112(1)
stfd 17, 120(1)
stfd 18, 128(1)
stfd 19, 136(1)
stfd 20, 144(1)
stfd 21, 152(1)
stfd 22, 160(1)
stfd 23, 168(1)
stfd 24, 176(1)
stfd 25, 184(1)
stfd 26, 192(1)
stfd 27, 200(1)
stfd 28, 208(1)
stfd 29, 216(1)
stfd 30, 224(1)
stfd 31, 232(1)
# hidden pointer
stw 3, 244(1)
mffs 0 # load FPSCR
stfd 0, 248(1) # save FPSCR
# store RSP (pointing to context-data) in R6
mr 6, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
# restore CR
lwz 0, 4(1)
mtcr 0
# restore LR
lwz 0, 8(1)
mtlr 0
# load PC
lwz 0, 240(1)
mtctr 0
# restore TOC
lwz 2, 20(1)
# restore R14 to R31
lwz 14, 24(1)
lwz 15, 28(1)
lwz 16, 32(1)
lwz 17, 36(1)
lwz 18, 40(1)
lwz 19, 44(1)
lwz 20, 48(1)
lwz 21, 52(1)
lwz 22, 56(1)
lwz 23, 60(1)
lwz 24, 64(1)
lwz 25, 68(1)
lwz 26, 72(1)
lwz 27, 76(1)
lwz 28, 80(1)
lwz 29, 84(1)
lwz 30, 88(1)
lwz 31, 92(1)
# restore F14 to F31
lfd 14, 96(1)
lfd 15, 104(1)
lfd 16, 112(1)
lfd 17, 120(1)
lfd 18, 128(1)
lfd 19, 136(1)
lfd 20, 144(1)
lfd 21, 152(1)
lfd 22, 160(1)
lfd 23, 168(1)
lfd 24, 176(1)
lfd 25, 184(1)
lfd 26, 192(1)
lfd 27, 200(1)
lfd 28, 208(1)
lfd 29, 216(1)
lfd 30, 224(1)
lfd 31, 232(1)
# hidden pointer
lwz 3, 244(1)
lfd 0, 248(1) # load FPSCR
mtfsf 0xff, 0 # restore FPSCR
# adjust stack
addi 1, 1, 256
# zero in r3 indicates first jump to context-function
cmpdi 3, 0
beq use_entry_arg
# return transfer_t
stw 6, 0(3)
stw 5, 4(3)
# jump to context
bctr
use_entry_arg:
# copy transfer_t into transfer_fn arg registers
mr 3, 6
mr 4, 5
# jump to context
bctr

View File

@ -0,0 +1,221 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_ppc64_sysv_elf_gas.S"
.globl jump_fcontext
#if _CALL_ELF == 2
.text
.align 2
jump_fcontext:
addis %r2, %r12, .TOC.-jump_fcontext@ha
addi %r2, %r2, .TOC.-jump_fcontext@l
.localentry jump_fcontext, . - jump_fcontext
#else
.section ".opd","aw"
.align 3
jump_fcontext:
# ifdef _CALL_LINUX
.quad .L.jump_fcontext,.TOC.@tocbase,0
.type jump_fcontext,@function
.text
.align 2
.L.jump_fcontext:
# else
.hidden .jump_fcontext
.globl .jump_fcontext
.quad .jump_fcontext,.TOC.@tocbase,0
.size jump_fcontext,24
.type .jump_fcontext,@function
.text
.align 2
.jump_fcontext:
# endif
#endif
# reserve space on stack
subi %r1, %r1, 184
#if _CALL_ELF != 2
std %r2, 0(%r1) # save TOC
#endif
std %r14, 8(%r1) # save R14
std %r15, 16(%r1) # save R15
std %r16, 24(%r1) # save R16
std %r17, 32(%r1) # save R17
std %r18, 40(%r1) # save R18
std %r19, 48(%r1) # save R19
std %r20, 56(%r1) # save R20
std %r21, 64(%r1) # save R21
std %r22, 72(%r1) # save R22
std %r23, 80(%r1) # save R23
std %r24, 88(%r1) # save R24
std %r25, 96(%r1) # save R25
std %r26, 104(%r1) # save R26
std %r27, 112(%r1) # save R27
std %r28, 120(%r1) # save R28
std %r29, 128(%r1) # save R29
std %r30, 136(%r1) # save R30
std %r31, 144(%r1) # save R31
#if _CALL_ELF != 2
std %r3, 152(%r1) # save hidden
#endif
# save CR
mfcr %r0
std %r0, 160(%r1)
# save LR
mflr %r0
std %r0, 168(%r1)
# save LR as PC
std %r0, 176(%r1)
# store RSP (pointing to context-data) in R6
mr %r6, %r1
#if _CALL_ELF == 2
# restore RSP (pointing to context-data) from R3
mr %r1, %r3
#else
# restore RSP (pointing to context-data) from R4
mr %r1, %r4
ld %r2, 0(%r1) # restore TOC
#endif
ld %r14, 8(%r1) # restore R14
ld %r15, 16(%r1) # restore R15
ld %r16, 24(%r1) # restore R16
ld %r17, 32(%r1) # restore R17
ld %r18, 40(%r1) # restore R18
ld %r19, 48(%r1) # restore R19
ld %r20, 56(%r1) # restore R20
ld %r21, 64(%r1) # restore R21
ld %r22, 72(%r1) # restore R22
ld %r23, 80(%r1) # restore R23
ld %r24, 88(%r1) # restore R24
ld %r25, 96(%r1) # restore R25
ld %r26, 104(%r1) # restore R26
ld %r27, 112(%r1) # restore R27
ld %r28, 120(%r1) # restore R28
ld %r29, 128(%r1) # restore R29
ld %r30, 136(%r1) # restore R30
ld %r31, 144(%r1) # restore R31
#if _CALL_ELF != 2
ld %r3, 152(%r1) # restore hidden
#endif
# restore CR
ld %r0, 160(%r1)
mtcr %r0
# restore LR
ld %r0, 168(%r1)
mtlr %r0
# load PC
ld %r12, 176(%r1)
# restore CTR
mtctr %r12
# adjust stack
addi %r1, %r1, 184
#if _CALL_ELF == 2
# copy transfer_t into transfer_fn arg registers
mr %r3, %r6
# arg pointer already in %r4
# jump to context
bctr
.size jump_fcontext, .-jump_fcontext
#else
# zero in r3 indicates first jump to context-function
cmpdi %r3, 0
beq use_entry_arg
# return transfer_t
std %r6, 0(%r3)
std %r5, 8(%r3)
# jump to context
bctr
use_entry_arg:
# copy transfer_t into transfer_fn arg registers
mr %r3, %r6
mr %r4, %r5
# jump to context
bctr
# ifdef _CALL_LINUX
.size .jump_fcontext, .-.L.jump_fcontext
# else
.size .jump_fcontext, .-.jump_fcontext
# endif
#endif
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,164 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | FCTX | DATA | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.align 2
.globl _jump_fcontext
_jump_fcontext:
; reserve space on stack
subi r1, r1, 184
std r14, 8(r1) ; save R14
std r15, 16(r1) ; save R15
std r16, 24(r1) ; save R16
std r17, 32(r1) ; save R17
std r18, 40(r1) ; save R18
std r19, 48(r1) ; save R19
std r20, 56(r1) ; save R20
std r21, 64(r1) ; save R21
std r22, 72(r1) ; save R22
std r23, 80(r1) ; save R23
std r24, 88(r1) ; save R24
std r25, 96(r1) ; save R25
std r26, 104(r1) ; save R26
std r27, 112(r1) ; save R27
std r28, 120(r1) ; save R28
std r29, 128(r1) ; save R29
std r30, 136(r1) ; save R30
std r31, 144(r1) ; save R31
std r3, 152(r1) ; save hidden
; save CR
mfcr r0
std r0, 160(r1)
; save LR
mflr r0
std r0, 168(r1)
; save LR as PC
std r0, 176(r1)
; store RSP (pointing to context-data) in R6
mr r6, r1
; restore RSP (pointing to context-data) from R4
mr r1, r4
ld r14, 8(r1) ; restore R14
ld r15, 16(r1) ; restore R15
ld r16, 24(r1) ; restore R16
ld r17, 32(r1) ; restore R17
ld r18, 40(r1) ; restore R18
ld r19, 48(r1) ; restore R19
ld r20, 56(r1) ; restore R20
ld r21, 64(r1) ; restore R21
ld r22, 72(r1) ; restore R22
ld r23, 80(r1) ; restore R23
ld r24, 88(r1) ; restore R24
ld r25, 96(r1) ; restore R25
ld r26, 104(r1) ; restore R26
ld r27, 112(r1) ; restore R27
ld r28, 120(r1) ; restore R28
ld r29, 128(r1) ; restore R29
ld r30, 136(r1) ; restore R30
ld r31, 144(r1) ; restore R31
ld r3, 152(r1) ; restore hidden
; restore CR
ld r0, 160(r1)
mtcr r0
; restore LR
ld r0, 168(r1)
mtlr r0
; load PC
ld r12, 176(r1)
; restore CTR
mtctr r12
; adjust stack
addi r1, r1, 184
; zero in r3 indicates first jump to context-function
cmpdi r3, 0
beq use_entry_arg
; return transfer_t
std r6, 0(r3)
std r5, 8(r3)
; jump to context
bctr
use_entry_arg:
; copy transfer_t into transfer_fn arg registers
mr r3, r6
mr r4, r5
; jump to context
bctr

View File

@ -0,0 +1,173 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_ppc64_sysv_xcoff_gas.S"
.toc
.csect .text[PR], 5
.align 2
.globl jump_fcontext[DS]
.globl .jump_fcontext
.csect jump_fcontext[DS], 3
jump_fcontext:
.llong .jump_fcontext[PR], TOC[tc0], 0
.csect .text[PR], 5
.jump_fcontext:
# reserve space on stack
subi 1, 1, 184
std 2, 0(1) # save TOC
std 14, 8(1) # save R14
std 15, 16(1) # save R15
std 16, 24(1) # save R16
std 17, 32(1) # save R17
std 18, 40(1) # save R18
std 19, 48(1) # save R19
std 20, 56(1) # save R20
std 21, 64(1) # save R21
std 22, 72(1) # save R22
std 23, 80(1) # save R23
std 24, 88(1) # save R24
std 25, 96(1) # save R25
std 26, 104(1) # save R26
std 27, 112(1) # save R27
std 28, 120(1) # save R28
std 29, 128(1) # save R29
std 30, 136(1) # save R30
std 31, 144(1) # save R31
std 3, 152(1) # save hidden
# save CR
mfcr 0
std 0, 160(1)
# save LR
mflr 0
std 0, 168(1)
# save LR as PC
std 0, 176(1)
# store RSP (pointing to context-data) in R6
mr 6, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
ld 2, 0(1) # restore TOC
ld 14, 8(1) # restore R14
ld 15, 16(1) # restore R15
ld 16, 24(1) # restore R16
ld 17, 32(1) # restore R17
ld 18, 40(1) # restore R18
ld 19, 48(1) # restore R19
ld 20, 56(1) # restore R20
ld 21, 64(1) # restore R21
ld 22, 72(1) # restore R22
ld 23, 80(1) # restore R23
ld 24, 88(1) # restore R24
ld 25, 96(1) # restore R25
ld 26, 104(1) # restore R26
ld 27, 112(1) # restore R27
ld 28, 120(1) # restore R28
ld 29, 128(1) # restore R29
ld 30, 136(1) # restore R30
ld 31, 144(1) # restore R31
ld 3, 152(1) # restore hidden
# restore CR
ld 0, 160(1)
mtcr 0
# restore LR
ld 0, 168(1)
mtlr 0
# load PC
ld 0, 176(1)
# restore CTR
mtctr 0
# adjust stack
addi 1, 1, 184
# zero in r3 indicates first jump to context-function
cmpdi 3, 0
beq use_entry_arg
# return transfer_t
std 6, 0(3)
std 5, 8(3)
# jump to context
bctr
use_entry_arg:
# copy transfer_t into transfer_fn arg registers
mr 3, 6
mr 4, 5
# jump to context
bctr

View File

@ -0,0 +1,150 @@
/*
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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | fs0 | fs1 | fs2 | fs3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | fs4 | fs5 | fs6 | fs7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | fs8 | fs9 | fs10 | fs11 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | s0 | s1 | s2 | s3 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
* ------------------------------------------------- *
* | s4 | s5 | s6 | s7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
* ------------------------------------------------- *
* | s8 | s9 | s10 | s11 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | | | | | *
* ------------------------------------------------- *
* | 0xc0| 0xc4| 0xc8| 0xcc| | | | | *
* ------------------------------------------------- *
* | ra | pc | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.file "jump_riscv64_sysv_elf_gas.S"
.text
.align 1
.global jump_fcontext
.type jump_fcontext, %function
jump_fcontext:
# prepare stack for GP + FPU
addi sp, sp, -0xd0
# save fs0 - fs11
fsd fs0, 0x00(sp)
fsd fs1, 0x08(sp)
fsd fs2, 0x10(sp)
fsd fs3, 0x18(sp)
fsd fs4, 0x20(sp)
fsd fs5, 0x28(sp)
fsd fs6, 0x30(sp)
fsd fs7, 0x38(sp)
fsd fs8, 0x40(sp)
fsd fs9, 0x48(sp)
fsd fs10, 0x50(sp)
fsd fs11, 0x58(sp)
# save s0-s11, ra
sd s0, 0x60(sp)
sd s1, 0x68(sp)
sd s2, 0x70(sp)
sd s3, 0x78(sp)
sd s4, 0x80(sp)
sd s5, 0x88(sp)
sd s6, 0x90(sp)
sd s7, 0x98(sp)
sd s8, 0xa0(sp)
sd s9, 0xa8(sp)
sd s10, 0xb0(sp)
sd s11, 0xb8(sp)
sd ra, 0xc0(sp)
# save RA as PC
sd ra, 0xc8(sp)
# store SP (pointing to context-data) in A2
mv a2, sp
# restore SP (pointing to context-data) from A0
mv sp, a0
# load fs0 - fs11
fld fs0, 0x00(sp)
fld fs1, 0x08(sp)
fld fs2, 0x10(sp)
fld fs3, 0x18(sp)
fld fs4, 0x20(sp)
fld fs5, 0x28(sp)
fld fs6, 0x30(sp)
fld fs7, 0x38(sp)
fld fs8, 0x40(sp)
fld fs9, 0x48(sp)
fld fs10, 0x50(sp)
fld fs11, 0x58(sp)
# load s0-s11,ra
ld s0, 0x60(sp)
ld s1, 0x68(sp)
ld s2, 0x70(sp)
ld s3, 0x78(sp)
ld s4, 0x80(sp)
ld s5, 0x88(sp)
ld s6, 0x90(sp)
ld s7, 0x98(sp)
ld s8, 0xa0(sp)
ld s9, 0xa8(sp)
ld s10, 0xb0(sp)
ld s11, 0xb8(sp)
ld ra, 0xc0(sp)
# return transfer_t from jump
# pass transfer_t as first arg in context function
# a0 == FCTX, a1 == DATA
mv a0, a2
# load pc
ld a2, 0xc8(sp)
# restore stack from GP + FPU
addi sp, sp, 0xd0
jr a2
.size jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,156 @@
/*******************************************************
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 8 | 16 | 24 | *
* ------------------------------------------------- *
* | t.fctx | t.data | r2 | r6 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 40 | 48 | 56 | *
* ------------------------------------------------- *
* | r7 | r8 | r9 | r10 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 72 | 80 | 88 | *
* ------------------------------------------------- *
* | r11 | r12 | r13 | r14 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 104 | 112 | 120 | *
* ------------------------------------------------- *
* | f8 | f9 | f10 | f11 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 136 | 144 | 152 | *
* ------------------------------------------------- *
* | f12 | f13 | f14 | f15 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 168 | 176 | | *
* ------------------------------------------------- *
* | fpc | pc | | | *
* ------------------------------------------------- *
*******************************************************/
.text
.align 8
.global jump_fcontext
.type jump_fcontext, @function
#define ARG_OFFSET 0
#define GR_OFFSET 16
#define FP_OFFSET 96
#define FPC_OFFSET 160
#define PC_OFFSET 168
#define CONTEXT_SIZE 176
#define REG_SAVE_AREA_SIZE 160
/*
typedef void* fcontext_t;
struct transfer_t {
fcontext_t fctx;
void * data;
};
transfer_t jump_fcontext( fcontext_t const to,
void * data);
Incoming args
r2 - Hidden argument to the location where the return transfer_t needs to be returned
r3 - Context we want to switch to
r4 - Data pointer
*/
jump_fcontext:
.machine "z10"
/* Reserve stack space to store the current context. */
aghi %r15,-CONTEXT_SIZE
/* Save the argument register holding the location of the return value. */
stg %r2,GR_OFFSET(%r15)
/* Save the call-saved general purpose registers. */
stmg %r6,%r14,GR_OFFSET+8(%r15)
/* Save call-saved floating point registers. */
std %f8,FP_OFFSET(%r15)
std %f9,FP_OFFSET+8(%r15)
std %f10,FP_OFFSET+16(%r15)
std %f11,FP_OFFSET+24(%r15)
std %f12,FP_OFFSET+32(%r15)
std %f13,FP_OFFSET+40(%r15)
std %f14,FP_OFFSET+48(%r15)
std %f15,FP_OFFSET+56(%r15)
/* Save the return address as current pc. */
stg %r14,PC_OFFSET(%r15)
/* Save the floating point control register. */
stfpc FPC_OFFSET(%r15)
/* Backup the stack pointer pointing to the old context-data into r1. */
lgr %r1,%r15
/* Load the new context pointer as stack pointer. */
lgr %r15,%r3
/* Restore the call-saved GPRs from the new context. */
lmg %r6,%r14,GR_OFFSET+8(%r15)
/* Restore call-saved floating point registers. */
ld %f8,FP_OFFSET(%r15)
ld %f9,FP_OFFSET+8(%r15)
ld %f10,FP_OFFSET+16(%r15)
ld %f11,FP_OFFSET+24(%r15)
ld %f12,FP_OFFSET+32(%r15)
ld %f13,FP_OFFSET+40(%r15)
ld %f14,FP_OFFSET+48(%r15)
ld %f15,FP_OFFSET+56(%r15)
/* Load the floating point control register. */
lfpc FPC_OFFSET(%r15)
/* Restore PC - the location where we will jump to at the end. */
lg %r5,PC_OFFSET(%r15)
ltg %r2,GR_OFFSET(%r15)
jnz use_return_slot
/* We restore a make_fcontext context. Use the function
argument slot in the context we just saved and allocate the
register save area for the target function. */
la %r2,ARG_OFFSET(%r1)
aghi %r15,-REG_SAVE_AREA_SIZE
use_return_slot:
/* Save the two fields in transfer_t. When calling a
make_fcontext function this becomes the function argument of
the target function, otherwise it will be the return value of
jump_fcontext. */
stg %r1,0(%r2)
stg %r4,8(%r2)
/* Free the restored context. */
aghi %r15,CONTEXT_SIZE
/* Jump to the PC loaded from the new context. */
br %r5
.size jump_fcontext,.-jump_fcontext
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,209 @@
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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)
*/
/*************************************************************************************
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ---------------------------------------------------------------------------------- *
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
* ---------------------------------------------------------------------------------- *
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
* ---------------------------------------------------------------------------------- *
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | *
* ---------------------------------------------------------------------------------- *
* | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | *
* ---------------------------------------------------------------------------------- *
* | limit | base | R12 | R13 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | *
* ---------------------------------------------------------------------------------- *
* | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | *
* ---------------------------------------------------------------------------------- *
* | R14 | R15 | RDI | RSI | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | *
* ---------------------------------------------------------------------------------- *
* | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | hidden | RIP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | *
* ---------------------------------------------------------------------------------- *
* | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | *
* ---------------------------------------------------------------------------------- *
* | parameter area | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | *
* ---------------------------------------------------------------------------------- *
* | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | *
* ---------------------------------------------------------------------------------- *
* | FCTX | DATA | | *
* ---------------------------------------------------------------------------------- *
**************************************************************************************/
.file "jump_x86_64_ms_pe_clang_gas.S"
.text
.p2align 4,,15
.globl jump_fcontext
.def jump_fcontext; .scl 2; .type 32; .endef
.seh_proc jump_fcontext
jump_fcontext:
.seh_endprologue
leaq -0x118(%rsp), %rsp /* prepare stack */
#if !defined(BOOST_USE_TSX)
/* save XMM storage */
movaps %xmm6, 0x0(%rsp)
movaps %xmm7, 0x10(%rsp)
movaps %xmm8, 0x20(%rsp)
movaps %xmm9, 0x30(%rsp)
movaps %xmm10, 0x40(%rsp)
movaps %xmm11, 0x50(%rsp)
movaps %xmm12, 0x60(%rsp)
movaps %xmm13, 0x70(%rsp)
movaps %xmm14, 0x80(%rsp)
movaps %xmm15, 0x90(%rsp)
stmxcsr 0xa0(%rsp) /* save MMX control- and status-word */
fnstcw 0xa4(%rsp) /* save x87 control-word */
#endif
/* load NT_TIB */
movq %gs:(0x30), %r10
/* save fiber local storage */
movq 0x20(%r10), %rax
movq %rax, 0xb0(%rsp)
/* save current deallocation stack */
movq 0x1478(%r10), %rax
movq %rax, 0xb8(%rsp)
/* save current stack limit */
movq 0x10(%r10), %rax
movq %rax, 0xc0(%rsp)
/* save current stack base */
movq 0x08(%r10), %rax
movq %rax, 0xc8(%rsp)
movq %r12, 0xd0(%rsp) /* save R12 */
movq %r13, 0xd8(%rsp) /* save R13 */
movq %r14, 0xe0(%rsp) /* save R14 */
movq %r15, 0xe8(%rsp) /* save R15 */
movq %rdi, 0xf0(%rsp) /* save RDI */
movq %rsi, 0xf8(%rsp) /* save RSI */
movq %rbx, 0x100(%rsp) /* save RBX */
movq %rbp, 0x108(%rsp) /* save RBP */
movq %rcx, 0x110(%rsp) /* save hidden address of transport_t */
/* preserve RSP (pointing to context-data) in R9 */
movq %rsp, %r9
/* restore RSP (pointing to context-data) from RDX */
movq %rdx, %rsp
#if !defined(BOOST_USE_TSX)
/* restore XMM storage */
movaps 0x0(%rsp), %xmm6
movaps 0x10(%rsp), %xmm7
movaps 0x20(%rsp), %xmm8
movaps 0x30(%rsp), %xmm9
movaps 0x40(%rsp), %xmm10
movaps 0x50(%rsp), %xmm11
movaps 0x60(%rsp), %xmm12
movaps 0x70(%rsp), %xmm13
movaps 0x80(%rsp), %xmm14
movaps 0x90(%rsp), %xmm15
ldmxcsr 0xa0(%rsp) /* restore MMX control- and status-word */
fldcw 0xa4(%rsp) /* restore x87 control-word */
#endif
/* load NT_TIB */
movq %gs:(0x30), %r10
/* restore fiber local storage */
movq 0xb0(%rsp), %rax
movq %rax, 0x20(%r10)
/* restore current deallocation stack */
movq 0xb8(%rsp), %rax
movq %rax, 0x1478(%r10)
/* restore current stack limit */
movq 0xc0(%rsp), %rax
movq %rax, 0x10(%r10)
/* restore current stack base */
movq 0xc8(%rsp), %rax
movq %rax, 0x08(%r10)
movq 0xd0(%rsp), %r12 /* restore R12 */
movq 0xd8(%rsp), %r13 /* restore R13 */
movq 0xe0(%rsp), %r14 /* restore R14 */
movq 0xe8(%rsp), %r15 /* restore R15 */
movq 0xf0(%rsp), %rdi /* restore RDI */
movq 0xf8(%rsp), %rsi /* restore RSI */
movq 0x100(%rsp), %rbx /* restore RBX */
movq 0x108(%rsp), %rbp /* restore RBP */
movq 0x110(%rsp), %rax /* restore hidden address of transport_t */
leaq 0x118(%rsp), %rsp /* prepare stack */
/* restore return-address */
popq %r10
/* transport_t returned in RAX */
/* return parent fcontext_t */
movq %r9, 0x0(%rax)
/* return data */
movq %r8, 0x8(%rax)
/* transport_t as 1.arg of context-function */
movq %rax, %rcx
/* indirect jump to context */
jmp *%r10
.seh_endproc
.section .drectve
.ascii " -export:\"jump_fcontext\""

View File

@ -0,0 +1,209 @@
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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)
*/
/*************************************************************************************
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ---------------------------------------------------------------------------------- *
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
* ---------------------------------------------------------------------------------- *
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
* ---------------------------------------------------------------------------------- *
* | SEE registers (XMM6-XMM15) | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
* ---------------------------------------------------------------------------------- *
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | *
* ---------------------------------------------------------------------------------- *
* | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | *
* ---------------------------------------------------------------------------------- *
* | limit | base | R12 | R13 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | *
* ---------------------------------------------------------------------------------- *
* | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | *
* ---------------------------------------------------------------------------------- *
* | R14 | R15 | RDI | RSI | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | *
* ---------------------------------------------------------------------------------- *
* | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | hidden | RIP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | *
* ---------------------------------------------------------------------------------- *
* | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | *
* ---------------------------------------------------------------------------------- *
* | parameter area | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | *
* ---------------------------------------------------------------------------------- *
* | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | *
* ---------------------------------------------------------------------------------- *
* | FCTX | DATA | | *
* ---------------------------------------------------------------------------------- *
**************************************************************************************/
.file "jump_x86_64_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl jump_fcontext
.def jump_fcontext; .scl 2; .type 32; .endef
.seh_proc jump_fcontext
jump_fcontext:
.seh_endprologue
leaq -0x118(%rsp), %rsp /* prepare stack */
#if !defined(BOOST_USE_TSX)
/* save XMM storage */
movaps %xmm6, 0x0(%rsp)
movaps %xmm7, 0x10(%rsp)
movaps %xmm8, 0x20(%rsp)
movaps %xmm9, 0x30(%rsp)
movaps %xmm10, 0x40(%rsp)
movaps %xmm11, 0x50(%rsp)
movaps %xmm12, 0x60(%rsp)
movaps %xmm13, 0x70(%rsp)
movaps %xmm14, 0x80(%rsp)
movaps %xmm15, 0x90(%rsp)
stmxcsr 0xa0(%rsp) /* save MMX control- and status-word */
fnstcw 0xa4(%rsp) /* save x87 control-word */
#endif
/* load NT_TIB */
movq %gs:(0x30), %r10
/* save fiber local storage */
movq 0x20(%r10), %rax
movq %rax, 0xb0(%rsp)
/* save current deallocation stack */
movq 0x1478(%r10), %rax
movq %rax, 0xb8(%rsp)
/* save current stack limit */
movq 0x10(%r10), %rax
movq %rax, 0xc0(%rsp)
/* save current stack base */
movq 0x08(%r10), %rax
movq %rax, 0xc8(%rsp)
movq %r12, 0xd0(%rsp) /* save R12 */
movq %r13, 0xd8(%rsp) /* save R13 */
movq %r14, 0xe0(%rsp) /* save R14 */
movq %r15, 0xe8(%rsp) /* save R15 */
movq %rdi, 0xf0(%rsp) /* save RDI */
movq %rsi, 0xf8(%rsp) /* save RSI */
movq %rbx, 0x100(%rsp) /* save RBX */
movq %rbp, 0x108(%rsp) /* save RBP */
movq %rcx, 0x110(%rsp) /* save hidden address of transport_t */
/* preserve RSP (pointing to context-data) in R9 */
movq %rsp, %r9
/* restore RSP (pointing to context-data) from RDX */
movq %rdx, %rsp
#if !defined(BOOST_USE_TSX)
/* restore XMM storage */
movaps 0x0(%rsp), %xmm6
movaps 0x10(%rsp), %xmm7
movaps 0x20(%rsp), %xmm8
movaps 0x30(%rsp), %xmm9
movaps 0x40(%rsp), %xmm10
movaps 0x50(%rsp), %xmm11
movaps 0x60(%rsp), %xmm12
movaps 0x70(%rsp), %xmm13
movaps 0x80(%rsp), %xmm14
movaps 0x90(%rsp), %xmm15
ldmxcsr 0xa0(%rsp) /* restore MMX control- and status-word */
fldcw 0xa4(%rsp) /* restore x87 control-word */
#endif
/* load NT_TIB */
movq %gs:(0x30), %r10
/* restore fiber local storage */
movq 0xb0(%rsp), %rax
movq %rax, 0x20(%r10)
/* restore current deallocation stack */
movq 0xb8(%rsp), %rax
movq %rax, 0x1478(%r10)
/* restore current stack limit */
movq 0xc0(%rsp), %rax
movq %rax, 0x10(%r10)
/* restore current stack base */
movq 0xc8(%rsp), %rax
movq %rax, 0x08(%r10)
movq 0xd0(%rsp), %r12 /* restore R12 */
movq 0xd8(%rsp), %r13 /* restore R13 */
movq 0xe0(%rsp), %r14 /* restore R14 */
movq 0xe8(%rsp), %r15 /* restore R15 */
movq 0xf0(%rsp), %rdi /* restore RDI */
movq 0xf8(%rsp), %rsi /* restore RSI */
movq 0x100(%rsp), %rbx /* restore RBX */
movq 0x108(%rsp), %rbp /* restore RBP */
movq 0x110(%rsp), %rax /* restore hidden address of transport_t */
leaq 0x118(%rsp), %rsp /* prepare stack */
/* restore return-address */
popq %r10
/* transport_t returned in RAX */
/* return parent fcontext_t */
movq %r9, 0x0(%rax)
/* return data */
movq %r8, 0x8(%rax)
/* transport_t as 1.arg of context-function */
movq %rax, %rcx
/* indirect jump to context */
jmp *%r10
.seh_endproc
.section .drectve
.ascii " -export:\"jump_fcontext\""

View File

@ -0,0 +1,205 @@
; Copyright Oliver Kowalke 2009.
; 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)
; ----------------------------------------------------------------------------------
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
; ----------------------------------------------------------------------------------
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
; ----------------------------------------------------------------------------------
; | SEE registers (XMM6-XMM15) |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ----------------------------------------------------------------------------------
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
; ----------------------------------------------------------------------------------
; | SEE registers (XMM6-XMM15) |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
; ----------------------------------------------------------------------------------
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
; ----------------------------------------------------------------------------------
; | SEE registers (XMM6-XMM15) |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
; ----------------------------------------------------------------------------------
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
; ----------------------------------------------------------------------------------
; | SEE registers (XMM6-XMM15) |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
; ----------------------------------------------------------------------------------
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
; ----------------------------------------------------------------------------------
; | SEE registers (XMM6-XMM15) |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
; ----------------------------------------------------------------------------------
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
; ----------------------------------------------------------------------------------
; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
; ----------------------------------------------------------------------------------
; | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc |
; ----------------------------------------------------------------------------------
; | limit | base | R12 | R13 |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
; ----------------------------------------------------------------------------------
; | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc |
; ----------------------------------------------------------------------------------
; | R14 | R15 | RDI | RSI |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
; ----------------------------------------------------------------------------------
; | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c |
; ----------------------------------------------------------------------------------
; | RBX | RBP | hidden | RIP |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
; ----------------------------------------------------------------------------------
; | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c |
; ----------------------------------------------------------------------------------
; | parameter area |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
; ----------------------------------------------------------------------------------
; | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c |
; ----------------------------------------------------------------------------------
; | FCTX | DATA | |
; ----------------------------------------------------------------------------------
.code
jump_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
.endprolog
; prepare stack
lea rsp, [rsp-0118h]
IFNDEF BOOST_USE_TSX
; save XMM storage
movaps [rsp], xmm6
movaps [rsp+010h], xmm7
movaps [rsp+020h], xmm8
movaps [rsp+030h], xmm9
movaps [rsp+040h], xmm10
movaps [rsp+050h], xmm11
movaps [rsp+060h], xmm12
movaps [rsp+070h], xmm13
movaps [rsp+080h], xmm14
movaps [rsp+090h], xmm15
; save MMX control- and status-word
stmxcsr [rsp+0a0h]
; save x87 control-word
fnstcw [rsp+0a4h]
ENDIF
; load NT_TIB
mov r10, gs:[030h]
; save fiber local storage
mov rax, [r10+020h]
mov [rsp+0b0h], rax
; save current deallocation stack
mov rax, [r10+01478h]
mov [rsp+0b8h], rax
; save current stack limit
mov rax, [r10+010h]
mov [rsp+0c0h], rax
; save current stack base
mov rax, [r10+08h]
mov [rsp+0c8h], rax
mov [rsp+0d0h], r12 ; save R12
mov [rsp+0d8h], r13 ; save R13
mov [rsp+0e0h], r14 ; save R14
mov [rsp+0e8h], r15 ; save R15
mov [rsp+0f0h], rdi ; save RDI
mov [rsp+0f8h], rsi ; save RSI
mov [rsp+0100h], rbx ; save RBX
mov [rsp+0108h], rbp ; save RBP
mov [rsp+0110h], rcx ; save hidden address of transport_t
; preserve RSP (pointing to context-data) in R9
mov r9, rsp
; restore RSP (pointing to context-data) from RDX
mov rsp, rdx
IFNDEF BOOST_USE_TSX
; restore XMM storage
movaps xmm6, [rsp]
movaps xmm7, [rsp+010h]
movaps xmm8, [rsp+020h]
movaps xmm9, [rsp+030h]
movaps xmm10, [rsp+040h]
movaps xmm11, [rsp+050h]
movaps xmm12, [rsp+060h]
movaps xmm13, [rsp+070h]
movaps xmm14, [rsp+080h]
movaps xmm15, [rsp+090h]
; restore MMX control- and status-word
ldmxcsr [rsp+0a0h]
; save x87 control-word
fldcw [rsp+0a4h]
ENDIF
; load NT_TIB
mov r10, gs:[030h]
; restore fiber local storage
mov rax, [rsp+0b0h]
mov [r10+020h], rax
; restore current deallocation stack
mov rax, [rsp+0b8h]
mov [r10+01478h], rax
; restore current stack limit
mov rax, [rsp+0c0h]
mov [r10+010h], rax
; restore current stack base
mov rax, [rsp+0c8h]
mov [r10+08h], rax
mov r12, [rsp+0d0h] ; restore R12
mov r13, [rsp+0d8h] ; restore R13
mov r14, [rsp+0e0h] ; restore R14
mov r15, [rsp+0e8h] ; restore R15
mov rdi, [rsp+0f0h] ; restore RDI
mov rsi, [rsp+0f8h] ; restore RSI
mov rbx, [rsp+0100h] ; restore RBX
mov rbp, [rsp+0108h] ; restore RBP
mov rax, [rsp+0110h] ; restore hidden address of transport_t
; prepare stack
lea rsp, [rsp+0118h]
; load return-address
pop r10
; transport_t returned in RAX
; return parent fcontext_t
mov [rax], r9
; return data
mov [rax+08h], r8
; transport_t as 1.arg of context-function
mov rcx, rax
; indirect jump to context
jmp r10
jump_fcontext ENDP
END

View File

@ -0,0 +1,142 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| guard | R12 | R13 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | R14 | R15 | RBX | RBP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0x40 | 0x44 | | *
* ---------------------------------------------------------------------------------- *
* | RIP | | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
# if defined __CET__
# include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# define _CET_ENDBR
# endif
.file "jump_x86_64_sysv_elf_gas.S"
.text
.globl jump_fcontext
.type jump_fcontext,@function
.align 16
jump_fcontext:
_CET_ENDBR
leaq -0x40(%rsp), %rsp /* prepare stack */
#if !defined(BOOST_USE_TSX)
stmxcsr (%rsp) /* save MMX control- and status-word */
fnstcw 0x4(%rsp) /* save x87 control-word */
#endif
#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR)
movq %fs:0x28, %rcx /* read stack guard from TLS record */
movq %rcx, 0x8(%rsp) /* save stack guard */
#endif
movq %r12, 0x10(%rsp) /* save R12 */
movq %r13, 0x18(%rsp) /* save R13 */
movq %r14, 0x20(%rsp) /* save R14 */
movq %r15, 0x28(%rsp) /* save R15 */
movq %rbx, 0x30(%rsp) /* save RBX */
movq %rbp, 0x38(%rsp) /* save RBP */
#if BOOST_CONTEXT_SHADOW_STACK
/* grow the stack to reserve space for shadow stack pointer(SSP) */
leaq -0x8(%rsp), %rsp
/* read the current SSP and store it */
rdsspq %rcx
movq %rcx, (%rsp)
#endif
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
#if BOOST_CONTEXT_SHADOW_STACK
/* first 8 bytes are SSP */
movq (%rsp), %rcx
leaq 0x8(%rsp), %rsp
/* Restore target(new) shadow stack */
rstorssp -8(%rcx)
/* restore token for previous shadow stack is pushed */
/* on previous shadow stack after saveprevssp */
saveprevssp
/* when return, jump_fcontext jump to restored return address */
/* (r8) instead of RET. This miss of RET implies us to unwind */
/* shadow stack accordingly. Otherwise mismatch occur */
movq $1, %rcx
incsspq %rcx
#endif
movq 0x40(%rsp), %r8 /* restore return-address */
#if !defined(BOOST_USE_TSX)
ldmxcsr (%rsp) /* restore MMX control- and status-word */
fldcw 0x4(%rsp) /* restore x87 control-word */
#endif
#if defined(BOOST_CONTEXT_TLS_STACK_PROTECTOR)
movq 0x8(%rsp), %rdx /* load stack guard */
movq %rdx, %fs:0x28 /* restore stack guard to TLS record */
#endif
movq 0x10(%rsp), %r12 /* restore R12 */
movq 0x18(%rsp), %r13 /* restore R13 */
movq 0x20(%rsp), %r14 /* restore R14 */
movq 0x28(%rsp), %r15 /* restore R15 */
movq 0x30(%rsp), %rbx /* restore RBX */
movq 0x38(%rsp), %rbp /* restore RBP */
leaq 0x48(%rsp), %rsp /* prepare stack */
/* return transfer_t from jump */
#if !defined(_ILP32)
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
#else
/* RAX == data:fctx */
salq $32, %rsi
orq %rsi, %rax
#endif
/* pass transfer_t as first arg in context function */
#if !defined(_ILP32)
/* RDI == fctx, RSI == data */
#else
/* RDI == data:fctx */
#endif
movq %rax, %rdi
/* indirect jump to context */
jmp *%r8
.size jump_fcontext,.-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits

View File

@ -0,0 +1,75 @@
/*
Copyright Oliver Kowalke 2009.
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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | R15 | RBX | RBP | RIP | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl _jump_fcontext
.align 8
_jump_fcontext:
leaq -0x38(%rsp), %rsp /* prepare stack */
#if !defined(BOOST_USE_TSX)
stmxcsr (%rsp) /* save MMX control- and status-word */
fnstcw 0x4(%rsp) /* save x87 control-word */
#endif
movq %r12, 0x8(%rsp) /* save R12 */
movq %r13, 0x10(%rsp) /* save R13 */
movq %r14, 0x18(%rsp) /* save R14 */
movq %r15, 0x20(%rsp) /* save R15 */
movq %rbx, 0x28(%rsp) /* save RBX */
movq %rbp, 0x30(%rsp) /* save RBP */
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
movq 0x38(%rsp), %r8 /* restore return-address */
#if !defined(BOOST_USE_TSX)
ldmxcsr (%rsp) /* restore MMX control- and status-word */
fldcw 0x4(%rsp) /* restore x87 control-word */
#endif
movq 0x8(%rsp), %r12 /* restore R12 */
movq 0x10(%rsp), %r13 /* restore R13 */
movq 0x18(%rsp), %r14 /* restore R14 */
movq 0x20(%rsp), %r15 /* restore R15 */
movq 0x28(%rsp), %rbx /* restore RBX */
movq 0x30(%rsp), %rbp /* restore RBP */
leaq 0x40(%rsp), %rsp /* prepare stack */
/* return transfer_t from jump */
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
/* pass transfer_t as first arg in context function */
/* RDI == fctx, RSI == data */
movq %rax, %rdi
/* indirect jump to context */
jmp *%r8

Some files were not shown because too many files have changed in this diff Show More