diff --git a/1010-boost-add-sw.patch b/1010-boost-add-sw.patch new file mode 100644 index 0000000000000000000000000000000000000000..4164f55ee6f20e53ca18006789565d08ddd42157 --- /dev/null +++ b/1010-boost-add-sw.patch @@ -0,0 +1,1725 @@ +From 2784d4c78d5a96edffdc1a5c74bf8d3a45293ce0 Mon Sep 17 00:00:00 2001 +From: wxiat +Date: Fri, 28 Jul 2023 16:47:53 +0800 +Subject: [PATCH] add sw + +Signed-off-by: wxiat +--- + boost/atomic/detail/caps_gcc_sw_64.hpp | 34 + + boost/atomic/detail/ops_gcc_sw_64.hpp | 876 ++++++++++++++++++ + boost/atomic/detail/platform.hpp | 4 + + .../detail/sw_64_rounding_control.hpp | 113 +++ + boost/numeric/interval/hw_rounding.hpp | 2 + + boost/predef/architecture.h | 1 + + boost/predef/architecture/sw_64.h | 51 + + .../systems/si/codata/sw_64_constants.hpp | 66 ++ + boost/wave/wave_config.hpp | 2 +- + boostcpp.jam | 6 +- + libs/atomic/test/lockfree.cpp | 2 +- + libs/config/checks/architecture/Jamroot.jam | 1 + + libs/config/checks/architecture/sw_64.cpp | 15 + + libs/config/test/config_info.cpp | 1 + + libs/context/build/Jamfile.v2 | 24 + + libs/context/build/architecture.jam | 4 + + libs/context/doc/architectures.qbk | 1 + + .../src/asm/jump_sw_64_aapcs_elf_gas.S | 86 ++ + .../src/asm/make_sw_64_aapcs_elf_gas.S | 37 + + .../src/asm/ontop_sw_64_aapcs_elf_gas.S | 86 ++ + libs/log/build/log-architecture.jam | 4 + + tools/build/doc/src/reference.xml | 1 + + tools/build/src/engine/jam.h | 5 + + tools/build/src/tools/builtin.py | 3 + + .../tools/features/architecture-feature.jam | 3 + + tools/build/tutorial.html | 2 +- + 26 files changed, 1426 insertions(+), 4 deletions(-) + create mode 100644 boost/atomic/detail/caps_gcc_sw_64.hpp + create mode 100644 boost/atomic/detail/ops_gcc_sw_64.hpp + create mode 100644 boost/numeric/interval/detail/sw_64_rounding_control.hpp + create mode 100644 boost/predef/architecture/sw_64.h + create mode 100644 boost/units/systems/si/codata/sw_64_constants.hpp + create mode 100644 libs/config/checks/architecture/sw_64.cpp + create mode 100644 libs/context/src/asm/jump_sw_64_aapcs_elf_gas.S + create mode 100644 libs/context/src/asm/make_sw_64_aapcs_elf_gas.S + create mode 100644 libs/context/src/asm/ontop_sw_64_aapcs_elf_gas.S + +diff --git a/boost/atomic/detail/caps_gcc_sw_64.hpp b/boost/atomic/detail/caps_gcc_sw_64.hpp +new file mode 100644 +index 00000000..8cb7b949 +--- /dev/null ++++ b/boost/atomic/detail/caps_gcc_sw_64.hpp +@@ -0,0 +1,34 @@ ++/* ++ * 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) ++ * ++ * Copyright (c) 2009 Helge Bahmann ++ * Copyright (c) 2013 Tim Blechmann ++ * Copyright (c) 2014 Andrey Semashev ++ */ ++/*! ++ * \file atomic/detail/caps_gcc_sw_64.hpp ++ * ++ * This header defines feature capabilities macros ++ */ ++ ++#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SW_64_HPP_INCLUDED_ ++#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SW_64_HPP_INCLUDED_ ++ ++#include ++ ++#ifdef BOOST_HAS_PRAGMA_ONCE ++#pragma once ++#endif ++ ++#define BOOST_ATOMIC_INT8_LOCK_FREE 2 ++#define BOOST_ATOMIC_INT16_LOCK_FREE 2 ++#define BOOST_ATOMIC_INT32_LOCK_FREE 2 ++#define BOOST_ATOMIC_INT64_LOCK_FREE 2 ++#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 ++ ++#define BOOST_ATOMIC_THREAD_FENCE 2 ++#define BOOST_ATOMIC_SIGNAL_FENCE 2 ++ ++#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SW_64_HPP_INCLUDED_ +diff --git a/boost/atomic/detail/ops_gcc_sw_64.hpp b/boost/atomic/detail/ops_gcc_sw_64.hpp +new file mode 100644 +index 00000000..5f8c5681 +--- /dev/null ++++ b/boost/atomic/detail/ops_gcc_sw_64.hpp +@@ -0,0 +1,876 @@ ++/* ++ * 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) ++ * ++ * Copyright (c) 2009 Helge Bahmann ++ * Copyright (c) 2013 Tim Blechmann ++ * Copyright (c) 2014 Andrey Semashev ++ */ ++/*! ++ * \file atomic/detail/ops_gcc_sw_64.hpp ++ * ++ * This header contains implementation of the \c operations template. ++ */ ++ ++#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SW_64_HPP_INCLUDED_ ++#define BOOST_ATOMIC_DETAIL_OPS_GCC_SW_64_HPP_INCLUDED_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef BOOST_HAS_PRAGMA_ONCE ++#pragma once ++#endif ++ ++namespace boost { ++namespace atomics { ++namespace detail { ++ ++/* ++ Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html ++ (HP OpenVMS systems documentation) and the Sw_64 Architecture Reference Manual. ++ */ ++ ++/* ++ NB: The most natural thing would be to write the increment/decrement ++ operators along the following lines: ++ ++ __asm__ __volatile__ ++ ( ++ "1: ldl_l %0,%1 \n" ++ "addl %0,1,%0 \n" ++ "stl_c %0,%1 \n" ++ "beq %0,1b\n" ++ : "=&b" (tmp) ++ : "m" (value) ++ : "cc" ++ ); ++ ++ However according to the comments on the HP website and matching ++ comments in the Linux kernel sources this defies branch prediction, ++ as the cpu assumes that backward branches are always taken; so ++ instead copy the trick from the Linux kernel, introduce a forward ++ branch and back again. ++ ++ I have, however, had a hard time measuring the difference between ++ the two versions in microbenchmarks -- I am leaving it in nevertheless ++ as it apparently does not hurt either. ++*/ ++ ++struct gcc_sw_64_operations_base ++{ ++ static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; ++ static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; ++ ++ static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT ++ { ++ if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) ++ __asm__ __volatile__ ("memb" ::: "memory"); ++ } ++ ++ static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT ++ { ++ if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) ++ __asm__ __volatile__ ("memb" ::: "memory"); ++ } ++ ++ static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT ++ { ++ if (order == memory_order_seq_cst) ++ __asm__ __volatile__ ("memb" ::: "memory"); ++ } ++}; ++ ++ ++template< bool Signed > ++struct operations< 4u, Signed > : ++ public gcc_sw_64_operations_base ++{ ++ typedef typename storage_traits< 4u >::type storage_type; ++ ++ static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; ++ static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u; ++ static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; ++ ++ static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ fence_before(order); ++ storage = v; ++ fence_after_store(order); ++ } ++ ++ static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type v = storage; ++ fence_after(order); ++ return v; ++ } ++ ++ static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, tmp; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "mov %3, %1\n" ++ "ldl_l %0, %2\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (tmp) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE bool compare_exchange_weak( ++ storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT ++ { ++ fence_before(success_order); ++ int success; ++ storage_type current; ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %2, %4\n" // current = *(&storage) ++ "cmpeq %2, %0, %3\n" // success = current == expected ++ "mov %2, %0\n" // expected = current ++ "beq %3, 2f\n" // if (success == 0) goto end ++ "stl_c %1, %4\n" // storage = desired; desired = store succeeded ++ "mov %1, %3\n" // success = desired ++ "2:\n" ++ : "+&r" (expected), // %0 ++ "+&r" (desired), // %1 ++ "=&r" (current), // %2 ++ "=&r" (success) // %3 ++ : "m" (storage) // %4 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ if (success) ++ fence_after(success_order); ++ else ++ fence_after(failure_order); ++ return !!success; ++ } ++ ++ static BOOST_FORCEINLINE bool compare_exchange_strong( ++ storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT ++ { ++ int success; ++ storage_type current, tmp; ++ fence_before(success_order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "mov %5, %1\n" // tmp = desired ++ "ldl_l %2, %4\n" // current = *(&storage) ++ "cmpeq %2, %0, %3\n" // success = current == expected ++ "mov %2, %0\n" // expected = current ++ "beq %3, 2f\n" // if (success == 0) goto end ++ "stl_c %1, %4\n" // storage = tmp; tmp = store succeeded ++ "beq %1, 3f\n" // if (tmp == 0) goto retry ++ "mov %1, %3\n" // success = tmp ++ "2:\n" ++ ++ ".subsection 2\n" ++ "3: br 1b\n" ++ ".previous\n" ++ ++ : "+&r" (expected), // %0 ++ "=&r" (tmp), // %1 ++ "=&r" (current), // %2 ++ "=&r" (success) // %3 ++ : "m" (storage), // %4 ++ "r" (desired) // %5 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ if (success) ++ fence_after(success_order); ++ else ++ fence_after(failure_order); ++ return !!success; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "addl %0, %3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "subl %0, %3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "and %0, %3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "bis %0, %3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "xor %0, %3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ return !!exchange(storage, (storage_type)1, order); ++ } ++ ++ static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ store(storage, 0, order); ++ } ++}; ++ ++ ++template< > ++struct operations< 1u, false > : ++ public operations< 4u, false > ++{ ++ typedef operations< 4u, false > base_type; ++ typedef base_type::storage_type storage_type; ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "addl %0, %3, %1\n" ++ "zapnot %1, #1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "subl %0, %3, %1\n" ++ "zapnot %1, #1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++}; ++ ++template< > ++struct operations< 1u, true > : ++ public operations< 4u, true > ++{ ++ typedef operations< 4u, true > base_type; ++ typedef base_type::storage_type storage_type; ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "addl %0, %3, %1\n" ++ "sextb %1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "subl %0, %3, %1\n" ++ "sextb %1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++}; ++ ++ ++template< > ++struct operations< 2u, false > : ++ public operations< 4u, false > ++{ ++ typedef operations< 4u, false > base_type; ++ typedef base_type::storage_type storage_type; ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "addl %0, %3, %1\n" ++ "zapnot %1, #3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "subl %0, %3, %1\n" ++ "zapnot %1, #3, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++}; ++ ++template< > ++struct operations< 2u, true > : ++ public operations< 4u, true > ++{ ++ typedef operations< 4u, true > base_type; ++ typedef base_type::storage_type storage_type; ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "addl %0, %3, %1\n" ++ "sextw %1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldl_l %0, %2\n" ++ "subl %0, %3, %1\n" ++ "sextw %1, %1\n" ++ "stl_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++}; ++ ++ ++template< bool Signed > ++struct operations< 8u, Signed > : ++ public gcc_sw_64_operations_base ++{ ++ typedef typename storage_traits< 8u >::type storage_type; ++ ++ static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; ++ static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u; ++ static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; ++ ++ static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ fence_before(order); ++ storage = v; ++ fence_after_store(order); ++ } ++ ++ static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type v = storage; ++ fence_after(order); ++ return v; ++ } ++ ++ static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, tmp; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "mov %3, %1\n" ++ "ldq_l %0, %2\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (tmp) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE bool compare_exchange_weak( ++ storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT ++ { ++ fence_before(success_order); ++ int success; ++ storage_type current; ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %2, %4\n" // current = *(&storage) ++ "cmpeq %2, %0, %3\n" // success = current == expected ++ "mov %2, %0\n" // expected = current ++ "beq %3, 2f\n" // if (success == 0) goto end ++ "stq_c %1, %4\n" // storage = desired; desired = store succeeded ++ "mov %1, %3\n" // success = desired ++ "2:\n" ++ : "+&r" (expected), // %0 ++ "+&r" (desired), // %1 ++ "=&r" (current), // %2 ++ "=&r" (success) // %3 ++ : "m" (storage) // %4 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ if (success) ++ fence_after(success_order); ++ else ++ fence_after(failure_order); ++ return !!success; ++ } ++ ++ static BOOST_FORCEINLINE bool compare_exchange_strong( ++ storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT ++ { ++ int success; ++ storage_type current, tmp; ++ fence_before(success_order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "mov %5, %1\n" // tmp = desired ++ "ldq_l %2, %4\n" // current = *(&storage) ++ "cmpeq %2, %0, %3\n" // success = current == expected ++ "mov %2, %0\n" // expected = current ++ "beq %3, 2f\n" // if (success == 0) goto end ++ "stq_c %1, %4\n" // storage = tmp; tmp = store succeeded ++ "beq %1, 3f\n" // if (tmp == 0) goto retry ++ "mov %1, %3\n" // success = tmp ++ "2:\n" ++ ++ ".subsection 2\n" ++ "3: br 1b\n" ++ ".previous\n" ++ ++ : "+&r" (expected), // %0 ++ "=&r" (tmp), // %1 ++ "=&r" (current), // %2 ++ "=&r" (success) // %3 ++ : "m" (storage), // %4 ++ "r" (desired) // %5 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ if (success) ++ fence_after(success_order); ++ else ++ fence_after(failure_order); ++ return !!success; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %0, %2\n" ++ "addq %0, %3, %1\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %0, %2\n" ++ "subq %0, %3, %1\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %0, %2\n" ++ "and %0, %3, %1\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %0, %2\n" ++ "bis %0, %3, %1\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT ++ { ++ storage_type original, modified; ++ fence_before(order); ++ __asm__ __volatile__ ++ ( ++ "1:\n" ++ "ldq_l %0, %2\n" ++ "xor %0, %3, %1\n" ++ "stq_c %1, %2\n" ++ "beq %1, 2f\n" ++ ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous\n" ++ ++ : "=&r" (original), // %0 ++ "=&r" (modified) // %1 ++ : "m" (storage), // %2 ++ "r" (v) // %3 ++ : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC ++ ); ++ fence_after(order); ++ return original; ++ } ++ ++ static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ return !!exchange(storage, (storage_type)1, order); ++ } ++ ++ static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT ++ { ++ store(storage, (storage_type)0, order); ++ } ++}; ++ ++ ++BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT ++{ ++ if (order != memory_order_relaxed) ++ __asm__ __volatile__ ("memb" ::: "memory"); ++} ++ ++BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT ++{ ++ if (order != memory_order_relaxed) ++ __asm__ __volatile__ ("" ::: "memory"); ++} ++ ++} // namespace detail ++} // namespace atomics ++} // namespace boost ++ ++#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SW_64_HPP_INCLUDED_ +diff --git a/boost/atomic/detail/platform.hpp b/boost/atomic/detail/platform.hpp +index 117dff27..501b8143 100644 +--- a/boost/atomic/detail/platform.hpp ++++ b/boost/atomic/detail/platform.hpp +@@ -68,6 +68,10 @@ + + #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sparc + ++#elif defined(__GNUC__) && defined(__sw_64__) ++ ++#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sw_64 ++ + #elif defined(__GNUC__) && defined(__alpha__) + + #define BOOST_ATOMIC_DETAIL_PLATFORM gcc_alpha +diff --git a/boost/numeric/interval/detail/sw_64_rounding_control.hpp b/boost/numeric/interval/detail/sw_64_rounding_control.hpp +new file mode 100644 +index 00000000..01b41024 +--- /dev/null ++++ b/boost/numeric/interval/detail/sw_64_rounding_control.hpp +@@ -0,0 +1,113 @@ ++/* Boost interval/detail/sw_64_rounding_control.hpp file ++ * ++ * Copyright 2005 Felix Höfling, Guillaume Melquiond ++ * ++ * Distributed under the Boost Software License, Version 1.0. ++ * (See accompanying file LICENSE_1_0.txt or ++ * copy at http://www.boost.org/LICENSE_1_0.txt) ++ */ ++ ++#ifndef BOOST_NUMERIC_INTERVAL_DETAIL_SW_64_ROUNDING_CONTROL_HPP ++#define BOOST_NUMERIC_INTERVAL_DETAIL_SW_64_ROUNDING_CONTROL_HPP ++ ++#if !defined(sw_64) && !defined(__sw_64__) ++#error This header only works on Sw_64 CPUs. ++#endif ++ ++#if defined(__GNUC__) || defined(__digital__) || defined(__DECCXX) ++ ++#include // write_rnd() and read_rnd() ++ ++namespace boost { ++namespace numeric { ++namespace interval_lib { ++ ++namespace detail { ++#if defined(__GNUC__ ) ++ typedef union { ++ ::boost::long_long_type imode; ++ double dmode; ++ } rounding_mode_struct; ++ ++ // set bits 59-58 (DYN), ++ // clear all exception bits and disable overflow (51) and inexact exceptions (62) ++ static const rounding_mode_struct mode_upward = { 0x4C08000000000000LL }; ++ static const rounding_mode_struct mode_downward = { 0x4408000000000000LL }; ++ static const rounding_mode_struct mode_to_nearest = { 0x4808000000000000LL }; ++ static const rounding_mode_struct mode_toward_zero = { 0x4008000000000000LL }; ++ ++ struct sw_64_rounding_control ++ { ++ typedef double rounding_mode; ++ ++ static void set_rounding_mode(const rounding_mode mode) ++ { __asm__ __volatile__ ("wfpcr %0" : : "f"(mode)); } ++ ++ static void get_rounding_mode(rounding_mode& mode) ++ { __asm__ __volatile__ ("rfpcr %0" : "=f"(mode)); } ++ ++ static void downward() { set_rounding_mode(mode_downward.dmode); } ++ static void upward() { set_rounding_mode(mode_upward.dmode); } ++ static void to_nearest() { set_rounding_mode(mode_to_nearest.dmode); } ++ static void toward_zero() { set_rounding_mode(mode_toward_zero.dmode); } ++ }; ++#elif defined(__digital__) || defined(__DECCXX) ++ ++#if defined(__DECCXX) && !(defined(__FLT_ROUNDS) && __FLT_ROUNDS == -1) ++#error Dynamic rounding mode not enabled. See cxx man page for details. ++#endif ++ ++ struct sw_64_rounding_control ++ { ++ typedef unsigned int rounding_mode; ++ ++ static void set_rounding_mode(const rounding_mode& mode) { write_rnd(mode); } ++ static void get_rounding_mode(rounding_mode& mode) { mode = read_rnd(); } ++ ++ static void downward() { set_rounding_mode(FP_RND_RM); } ++ static void upward() { set_rounding_mode(FP_RND_RP); } ++ static void to_nearest() { set_rounding_mode(FP_RND_RN); } ++ static void toward_zero() { set_rounding_mode(FP_RND_RZ); } ++ }; ++#endif ++} // namespace detail ++ ++extern "C" { ++ float rintf(float); ++ double rint(double); ++ long double rintl(long double); ++} ++ ++template<> ++struct rounding_control: ++ detail::sw_64_rounding_control ++{ ++ static float force_rounding(const float r) ++ { volatile float _r = r; return _r; } ++ static float to_int(const float& x) { return rintf(x); } ++}; ++ ++template<> ++struct rounding_control: ++ detail::sw_64_rounding_control ++{ ++ static const double & force_rounding(const double& r) { return r; } ++ static double to_int(const double& r) { return rint(r); } ++}; ++ ++template<> ++struct rounding_control: ++ detail::sw_64_rounding_control ++{ ++ static const long double & force_rounding(const long double& r) { return r; } ++ static long double to_int(const long double& r) { return rintl(r); } ++}; ++ ++} // namespace interval_lib ++} // namespace numeric ++} // namespace boost ++ ++#undef BOOST_NUMERIC_INTERVAL_NO_HARDWARE ++#endif ++ ++#endif /* BOOST_NUMERIC_INTERVAL_DETAIL_SW_64_ROUNDING_CONTROL_HPP */ +diff --git a/boost/numeric/interval/hw_rounding.hpp b/boost/numeric/interval/hw_rounding.hpp +index 574b2433..addf0253 100644 +--- a/boost/numeric/interval/hw_rounding.hpp ++++ b/boost/numeric/interval/hw_rounding.hpp +@@ -27,6 +27,8 @@ + # include + #elif defined(sparc) || defined(__sparc__) + # include ++#elif defined(sw_64) || defined(__sw_64__) ++# include + #elif defined(alpha) || defined(__alpha__) + # include + #elif defined(ia64) || defined(__ia64) || defined(__ia64__) +diff --git a/boost/predef/architecture.h b/boost/predef/architecture.h +index c433d437..16ec8527 100644 +--- a/boost/predef/architecture.h ++++ b/boost/predef/architecture.h +@@ -11,6 +11,7 @@ http://www.boost.org/LICENSE_1_0.txt) + #endif + + #include ++#include + #include + #include + #include +diff --git a/boost/predef/architecture/sw_64.h b/boost/predef/architecture/sw_64.h +new file mode 100644 +index 00000000..9ae5e7b3 +--- /dev/null ++++ b/boost/predef/architecture/sw_64.h +@@ -0,0 +1,51 @@ ++/* ++Copyright Rene Rivera 2008-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) ++*/ ++ ++#ifndef BOOST_PREDEF_ARCHITECTURE_SW_64_H ++#define BOOST_PREDEF_ARCHITECTURE_SW_64_H ++ ++#include ++#include ++ ++/* tag::reference[] ++= `BOOST_ARCH_SW_64` ++ ++http://en.wikipedia.org/wiki/DEC_Sw_64[DEC Sw_64] architecture. ++ ++[options="header"] ++|=== ++| {predef_symbol} | {predef_version} ++| `+__sw_64__+` | {predef_detection} ++| `+__sw_64+` | {predef_detection} ++| `+_M_SW_64+` | {predef_detection} ++ ++| `+__sw_64_ev4__+` | 4.0.0 ++| `+__sw_64_ev5__+` | 5.0.0 ++| `+__sw_64_ev6__+` | 6.0.0 ++|=== ++*/ // end::reference[] ++ ++#define BOOST_ARCH_SW_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE ++ ++#if defined(__sw_64__) || defined(__sw_64) || \ ++ defined(_M_SW_64) ++# undef BOOST_ARCH_SW_64 ++# if !defined(BOOST_ARCH_SW_64) && defined(__sw_64_sw6b__) ++# define BOOST_ARCH_SW_64 BOOST_VERSION_NUMBER(6,0,0) ++# endif ++#endif ++ ++#if BOOST_ARCH_SW_64 ++# define BOOST_ARCH_SW_64_AVAILABLE ++#endif ++ ++#define BOOST_ARCH_SW_64_NAME "DEC Sw_64" ++ ++#endif ++ ++#include ++BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SW_64,BOOST_ARCH_SW_64_NAME) +diff --git a/boost/units/systems/si/codata/sw_64_constants.hpp b/boost/units/systems/si/codata/sw_64_constants.hpp +new file mode 100644 +index 00000000..98112313 +--- /dev/null ++++ b/boost/units/systems/si/codata/sw_64_constants.hpp +@@ -0,0 +1,66 @@ ++// Boost.Units - A C++ library for zero-overhead dimensional analysis and ++// unit/quantity manipulation and conversion ++// ++// Copyright (C) 2003-2008 Matthias Christian Schabel ++// Copyright (C) 2008 Steven Watanabe ++// ++// Distributed under the Boost Software License, Version 1.0. (See ++// accompanying file LICENSE_1_0.txt or copy at ++// http://www.boost.org/LICENSE_1_0.txt) ++ ++#ifndef BOOST_UNITS_CODATA_SW_64_CONSTANTS_HPP ++#define BOOST_UNITS_CODATA_SW_64_CONSTANTS_HPP ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/// \file ++/// CODATA recommended values of fundamental atomic and nuclear constants ++/// CODATA 2006 values as of 2007/03/30 ++ ++namespace boost { ++ ++namespace units { ++ ++namespace si { ++ ++namespace constants { ++ ++namespace codata { ++ ++/// CODATA recommended values of the fundamental physical constants: NIST SP 961 ++ ++/// sw_64 particle mass ++BOOST_UNITS_PHYSICAL_CONSTANT(m_sw_64,quantity,6.64465620e-27*kilograms,3.3e-34*kilograms); ++/// sw_64-electron mass ratio ++BOOST_UNITS_PHYSICAL_CONSTANT(m_sw_64_over_m_e,quantity,7294.2995365*dimensionless(),3.1e-6*dimensionless()); ++/// sw_64-proton mass ratio ++BOOST_UNITS_PHYSICAL_CONSTANT(m_sw_64_over_m_p,quantity,3.97259968951*dimensionless(),4.1e-10*dimensionless()); ++/// sw_64 molar mass ++BOOST_UNITS_PHYSICAL_CONSTANT(M_sw_64,quantity,4.001506179127e-3*kilograms/mole,6.2e-14*kilograms/mole); ++ ++} // namespace codata ++ ++} // namespace constants ++ ++} // namespace si ++ ++} // namespace units ++ ++} // namespace boost ++ ++#endif // BOOST_UNITS_CODATA_SW_64_CONSTANTS_HPP +diff --git a/boost/wave/wave_config.hpp b/boost/wave/wave_config.hpp +index 6e4b15d1..28ce2fff 100644 +--- a/boost/wave/wave_config.hpp ++++ b/boost/wave/wave_config.hpp +@@ -205,7 +205,7 @@ + // CW up to 8.3 chokes as well *sigh* + // Tru64/CXX has linker problems when using flex_string + #if BOOST_WORKAROUND(__MWERKS__, < 0x3200) || \ +- (defined(__DECCXX) && defined(__alpha)) || \ ++ (defined(__DECCXX) && (defined(__alpha) || defined(__sw_64))) || \ + defined(BOOST_WAVE_STRINGTYPE_USE_STDSTRING) + + #define BOOST_WAVE_STRINGTYPE std::string +diff --git a/boostcpp.jam b/boostcpp.jam +index 85a4cb32..d4fc832f 100644 +--- a/boostcpp.jam ++++ b/boostcpp.jam +@@ -678,7 +678,7 @@ rule address-model ( ) + return @boostcpp.deduce-address-model ; + } + +-local deducable-architectures = arm mips1 power sparc x86 combined ; ++local deducable-architectures = sw_64 arm mips1 power sparc x86 combined ; + feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ; + for a in $(deducable-architectures) + { +@@ -705,6 +705,10 @@ rule deduce-architecture ( properties * ) + { + result = sparc ; + } ++ else if [ configure.builds /boost/architecture//sw_64 : $(filtered) : sw_64 ] ++ { ++ result = sw_64 ; ++ } + else if [ configure.builds /boost/architecture//x86 : $(filtered) : x86 ] + { + result = x86 ; +diff --git a/libs/atomic/test/lockfree.cpp b/libs/atomic/test/lockfree.cpp +index 33c62e2a..a022def6 100644 +--- a/libs/atomic/test/lockfree.cpp ++++ b/libs/atomic/test/lockfree.cpp +@@ -88,7 +88,7 @@ verify_lock_free(const char * type_name, int lock_free_macro_val, int lock_free_ + #define EXPECT_POINTER_LOCK_FREE 2 + #define EXPECT_BOOL_LOCK_FREE 2 + +-#elif defined(__GNUC__) && defined(__alpha__) ++#elif defined(__GNUC__) && (defined(__alpha__) || defined(__sw_64__)) + + #define EXPECT_CHAR_LOCK_FREE 2 + #define EXPECT_CHAR16_T_LOCK_FREE 2 +diff --git a/libs/config/checks/architecture/Jamroot.jam b/libs/config/checks/architecture/Jamroot.jam +index ca653b75..0e1df50d 100644 +--- a/libs/config/checks/architecture/Jamroot.jam ++++ b/libs/config/checks/architecture/Jamroot.jam +@@ -16,6 +16,7 @@ obj 32 : 32.cpp ; + obj 64 : 64.cpp ; + + obj arm : arm.cpp ; ++obj sw_64 : sw_64.cpp ; + obj combined : combined.cpp ; + obj mips1 : mips1.cpp ; + obj power : power.cpp ; +diff --git a/libs/config/checks/architecture/sw_64.cpp b/libs/config/checks/architecture/sw_64.cpp +new file mode 100644 +index 00000000..8200abde +--- /dev/null ++++ b/libs/config/checks/architecture/sw_64.cpp +@@ -0,0 +1,15 @@ ++// sw_64.cpp ++// ++// Copyright (c) 2012 Steven Watanabe ++// ++// 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) ++ ++#if !defined(__sw_64__) && !defined(__thumb__) && \ ++ !defined(__TARGET_ARCH_SW_64) && !defined(__TARGET_ARCH_THUMB) && \ ++ !defined(_SW_64) && !defined(_M_SW_64) && \ ++ !defined(__aarch64__) ++#error "Not SW_64" ++#endif ++ +diff --git a/libs/config/test/config_info.cpp b/libs/config/test/config_info.cpp +index 89f6b07b..32a19e03 100644 +--- a/libs/config/test/config_info.cpp ++++ b/libs/config/test/config_info.cpp +@@ -146,6 +146,7 @@ void print_compiler_macros() + PRINT_MACRO(_CPPRTTI); + PRINT_MACRO(_DLL); + PRINT_MACRO(_M_ALPHA); ++ PRINT_MACRO(_M_SW_64); + PRINT_MACRO(_M_MPPC); + PRINT_MACRO(_M_MRX000); + PRINT_MACRO(_M_PPC); +diff --git a/libs/context/build/Jamfile.v2 b/libs/context/build/Jamfile.v2 +index 719ca91e..abca0193 100644 +--- a/libs/context/build/Jamfile.v2 ++++ b/libs/context/build/Jamfile.v2 +@@ -234,6 +234,30 @@ alias asm_sources + msvc + ; + ++# SW_64 ++# SW_64/AAPCS/ELF ++alias asm_sources ++ : asm/make_sw_64_aapcs_elf_gas.S ++ asm/jump_sw_64_aapcs_elf_gas.S ++ asm/ontop_sw_64_aapcs_elf_gas.S ++ : aapcs ++ 64 ++ sw_64 ++ elf ++ clang ++ ; ++ ++alias asm_sources ++ : asm/make_sw_64_aapcs_elf_gas.S ++ asm/jump_sw_64_aapcs_elf_gas.S ++ asm/ontop_sw_64_aapcs_elf_gas.S ++ : aapcs ++ 64 ++ sw_64 ++ elf ++ gcc ++ ; ++ + # ARM64 + # ARM64/AAPCS/ELF + alias asm_sources +diff --git a/libs/context/build/architecture.jam b/libs/context/build/architecture.jam +index 81dcb497..b80a7eab 100644 +--- a/libs/context/build/architecture.jam ++++ b/libs/context/build/architecture.jam +@@ -59,6 +59,10 @@ rule deduce-architecture ( properties * ) + { + return mips1 ; + } ++ else if [ configure.builds /boost/architecture//sw_64 : $(properties) : sw_64 ] ++ { ++ return sw_64 ; ++ } + else if [ configure.builds /boost/architecture//power : $(properties) : power ] + { + return power ; +diff --git a/libs/context/doc/architectures.qbk b/libs/context/doc/architectures.qbk +index 893c5b39..1e9555a1 100644 +--- a/libs/context/doc/architectures.qbk ++++ b/libs/context/doc/architectures.qbk +@@ -20,6 +20,7 @@ architectures: + [[ppc64] [SYSV|ELF,XCOFF] [-] [SYSV|MACH-O] [-]] + [[sparc] [-] [-] [-] [-]] + [[x86_64] [SYSV,X32|ELF] [MS|PE] [SYSV|MACH-O] [-]] ++ [[sw_64] [SYSV,X64|ELF] [MS|PE] [SYSV|MACH-O] [-]] + ] + + [note If the architecture is not supported but the platform provides +diff --git a/libs/context/src/asm/jump_sw_64_aapcs_elf_gas.S b/libs/context/src/asm/jump_sw_64_aapcs_elf_gas.S +new file mode 100644 +index 00000000..913b4d8d +--- /dev/null ++++ b/libs/context/src/asm/jump_sw_64_aapcs_elf_gas.S +@@ -0,0 +1,86 @@ ++.text ++.align 2 ++.global jump_fcontext ++.type jump_fcontext, %function ++jump_fcontext: ++ # prepare stack for GP + FPU ++ #ldih $29,0($27) ++ #ldi $29,0($29) ++ subl $sp, 0x98, $sp ++ ++ # save $f2-$f9 ++ fstd $f2, 0x00($sp) ++ fstd $f3, 0x08($sp) ++ fstd $f4, 0x10($sp) ++ fstd $f5, 0x18($sp) ++ fstd $f6, 0x20($sp) ++ fstd $f7, 0x28($sp) ++ fstd $f8, 0x30($sp) ++ fstd $f9, 0x38($sp) ++ ++ # save $9-$15, fp,$26 ++ stl $9, 0x40($sp) ++ stl $10, 0x48($sp) ++ stl $11, 0x50($sp) ++ stl $12, 0x58($sp) ++ stl $13, 0x60($sp) ++ stl $14, 0x68($sp) ++ stl $15, 0x70($sp) ++ stl $fp, 0x78($sp) ++ stl $16, 0x80($sp) #save jump_fcontext return address ++ stl $26, 0x88($sp) ++ ++ # save LR as PC ++ stl $26, 0x90($sp) ++ ++ # store RSP (pointing to context-data) in $16 ++ mov $sp, $20 ++ ++ ++ # restore RSP (pointing to context-data) from $17 ++ mov $17, $sp ++ ++ # load $f2-$f9 ++ fldd $f2, 0x00($sp) ++ fldd $f3, 0x08($sp) ++ fldd $f4, 0x10($sp) ++ fldd $f5, 0x18($sp) ++ fldd $f6, 0x20($sp) ++ fldd $f7, 0x28($sp) ++ fldd $f8, 0x30($sp) ++ fldd $f9, 0x38($sp) ++ ++ # load $9-$15, fp,$26 ++ ldl $9, 0x40($sp) ++ ldl $10, 0x48($sp) ++ ldl $11, 0x50($sp) ++ ldl $12, 0x58($sp) ++ ldl $13, 0x60($sp) ++ ldl $14, 0x68($sp) ++ ldl $15, 0x70($sp) ++ ldl $fp, 0x78($sp) ++ ldl $26, 0x88($sp) ++ ++ # pass transfer_t as first arg in context function ++ # to store $1,$2 to $16 address ++ ldl $16, 0x80($sp) #load $16, store return struct do return address ++ stl $20,0($16) ++ stl $18,8($16) ++ ++ # pass transfer_t as first arg in context function,such as f1,f2,f3 ++ # $16 == FCTX, $17 == DATA ++ mov $20,$16 #$16 $17 as first and second arg ++ mov $18,$17 ++ ++ ++ # load pc ++ ldl $27, 0x90($sp) ++ ++ ++ # restore stack from GP + FPU ++ addl $sp, 0x98, $sp ++ ++ ret $31,($27),0x1 //jmp $31, ($27) //ret ($27) ++.size jump_fcontext,.-jump_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/libs/context/src/asm/make_sw_64_aapcs_elf_gas.S b/libs/context/src/asm/make_sw_64_aapcs_elf_gas.S +new file mode 100644 +index 00000000..7f7d6917 +--- /dev/null ++++ b/libs/context/src/asm/make_sw_64_aapcs_elf_gas.S +@@ -0,0 +1,37 @@ ++.text ++.align 2 ++.global make_fcontext ++.type make_fcontext, %function ++make_fcontext: ++ #ldih $29,0($27) ++ #ldi $29,0($29) ++ # shift address in $16 (allocated stack) to lower 16 byte boundary ++ bic $16, 0xf,$16 ++ ++ # reserve space for context-data on context-stack ++ subl $16, 0x98,$16 ++ ++ # third arg of make_fcontext() == address of context-function ++ # store address as a PC to jump in ++ stl $18, 0x90($16) ++ ++ # save address of finish as return-address for context-function ++ # will be entered after context-function returns (LR register) ++ ldi $17, finish ++ stl $17, 0x88($16) ++ ++ stl $16, 0x80($16) ++ ++ mov $16, $0 ++ ++ ret $31,($26),1 //jump ($26) // return pointer to context-data ($16) ++ ++finish: ++ # exit code is zero ++ mov 0, $0 ++ # exit application ++ call _exit #ldi $27,_exit #jmp ($27) ++ ++.size make_fcontext,.-make_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/libs/context/src/asm/ontop_sw_64_aapcs_elf_gas.S b/libs/context/src/asm/ontop_sw_64_aapcs_elf_gas.S +new file mode 100644 +index 00000000..1e647646 +--- /dev/null ++++ b/libs/context/src/asm/ontop_sw_64_aapcs_elf_gas.S +@@ -0,0 +1,86 @@ ++.text ++.align 2 ++.global ontop_fcontext ++.type ontop_fcontext, %function ++ontop_fcontext: ++ # prepare stack for GP + FPU ++ #ldih $29,0($27) ++ #ldi $29,0($29) ++ subl $sp, 0x98, $sp ++ ++ # save $f2-$f9 ++ fstd $f2, 0x00($sp) ++ fstd $f3, 0x08($sp) ++ fstd $f4, 0x10($sp) ++ fstd $f5, 0x18($sp) ++ fstd $f6, 0x20($sp) ++ fstd $f7, 0x28($sp) ++ fstd $f8, 0x30($sp) ++ fstd $f9, 0x38($sp) ++ ++ # save $9-$15, fp,$26 ++ stl $9, 0x40($sp) ++ stl $10, 0x48($sp) ++ stl $11, 0x50($sp) ++ stl $12, 0x58($sp) ++ stl $13, 0x60($sp) ++ stl $14, 0x68($sp) ++ stl $15, 0x70($sp) ++ stl $fp, 0x78($sp) ++ stl $16, 0x80($sp) #save ontop_fcontext return address ++ stl $26, 0x88($sp) ++ ++ # save LR as PC ++ stl $26, 0x90($sp) ++ ++ # store RSP (pointing to context-data) in $16 ++ mov $sp, $20 ++ ++ ++ # restore RSP (pointing to context-data) from $17 ++ mov $17, $sp ++ ++ # load $f2-$f9 ++ fldd $f2, 0x00($sp) ++ fldd $f3, 0x08($sp) ++ fldd $f4, 0x10($sp) ++ fldd $f5, 0x18($sp) ++ fldd $f6, 0x20($sp) ++ fldd $f7, 0x28($sp) ++ fldd $f8, 0x30($sp) ++ fldd $f9, 0x38($sp) ++ ++ # load $9-$15, fp,$26 ++ ldl $9, 0x40($sp) ++ ldl $10, 0x48($sp) ++ ldl $11, 0x50($sp) ++ ldl $12, 0x58($sp) ++ ldl $13, 0x60($sp) ++ ldl $14, 0x68($sp) ++ ldl $15, 0x70($sp) ++ ldl $fp, 0x78($sp) ++ ldl $26, 0x88($sp) ++ ++ # pass transfer_t as first arg in context function ++ # to store $1,$2 to $16 address ++ ldl $16, 0x80($sp) #load $16, store return struct do return address ++ stl $20,0($16) ++ stl $18,8($16) ++ ++ # pass transfer_t as first arg in context function,such as f1,f2,f3 ++ # $16 == FCTX, $17 == DATA ++ mov $20,$16 #$16 $17 $18 as first and second arg ++ mov $18,$17 ++ ++ ++ # skip pc ++ mov $19, $27 ++ ++ ++ # restore stack from GP + FPU ++ addl $sp, 0x98, $sp ++ ++ ret $31,($27),0x1 //jmp $31, ($27) //ret ($27) ++.size ontop_fcontext,.-ontop_fcontext ++# Mark that we don't need executable stack. ++.section .note.GNU-stack,"",%progbits +diff --git a/libs/log/build/log-architecture.jam b/libs/log/build/log-architecture.jam +index 785dda0f..a63b4816 100644 +--- a/libs/log/build/log-architecture.jam ++++ b/libs/log/build/log-architecture.jam +@@ -69,6 +69,10 @@ rule deduce-architecture ( properties * ) + { + return mips1 ; + } ++ else if [ configure.builds /boost/architecture//sw_64 : $(properties) : sw_64 ] ++ { ++ return sw_64 ; ++ } + else if [ configure.builds /boost/architecture//power : $(properties) : power ] + { + return power ; +diff --git a/tools/build/doc/src/reference.xml b/tools/build/doc/src/reference.xml +index 24652f15..74d6eba0 100644 +--- a/tools/build/doc/src/reference.xml ++++ b/tools/build/doc/src/reference.xml +@@ -728,6 +728,7 @@ path-constant DATA : data/a.txt ; + + Allowed values: + x86, ++ sw_64, + ia64, + sparc, + power, +diff --git a/tools/build/src/engine/jam.h b/tools/build/src/engine/jam.h +index a6abf410..5703a6b7 100644 +--- a/tools/build/src/engine/jam.h ++++ b/tools/build/src/engine/jam.h +@@ -379,6 +379,11 @@ + #define OSPLAT "OSPLAT=PPC" + #endif + ++#if defined( _SW_64_ ) || \ ++ defined( __sw_64__ ) ++ #define OSPLAT "OSPLAT=AXP" ++#endif ++ + #if defined( _ALPHA_ ) || \ + defined( __alpha__ ) + #define OSPLAT "OSPLAT=AXP" +diff --git a/tools/build/src/tools/builtin.py b/tools/build/src/tools/builtin.py +index ee6474b7..dd5c797b 100644 +--- a/tools/build/src/tools/builtin.py ++++ b/tools/build/src/tools/builtin.py +@@ -247,6 +247,9 @@ def register_globals (): + # x86 and x86-64 + 'x86', + ++ # sw_64 ++ 'sw_64', ++ + # ia64 + 'ia64', + +diff --git a/tools/build/src/tools/features/architecture-feature.jam b/tools/build/src/tools/features/architecture-feature.jam +index b8f7fbcb..20532181 100644 +--- a/tools/build/src/tools/features/architecture-feature.jam ++++ b/tools/build/src/tools/features/architecture-feature.jam +@@ -12,6 +12,9 @@ feature.feature architecture + # x86 and x86-64 + x86 + ++ # sw_64 ++ sw_64 ++ + # ia64 + ia64 + +diff --git a/tools/build/tutorial.html b/tools/build/tutorial.html +index f50586e4..84e76f46 100644 +--- a/tools/build/tutorial.html ++++ b/tools/build/tutorial.html +@@ -1254,7 +1254,7 @@ exe hello : hello.cpp : <library>/boost//thread ; + + <architecture> + +- x86, ia64, sparc, power, mips1, mips2, mips3, mips4, mips32, ++ x86, sw_64, ia64, sparc, power, mips1, mips2, mips3, mips4, mips32, + mips32r2, mips64, parisc, arm, combined, combined-x86-power + + Set processor family to generate code for. +-- +2.31.1 + diff --git a/boost.spec b/boost.spec index 7421a2c23266a77531c35e0a91cc007290ceeccf..85830c2221be7cd6243afcf6230c58ed99580164 100644 --- a/boost.spec +++ b/boost.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.1 +%define anolis_release .0.2 # Support for documentation installation As the %%doc macro erases the # target directory ($RPM_BUILD_ROOT%%{_docdir}/%%{name}), manually # installed documentation must be saved into a temporary dedicated @@ -166,6 +166,7 @@ Patch1007: 1007-Improve-C++11-allocator-support.patch Patch1008: 1008-Use-boost::allocator_rebind-instead-of-A::template-rebind.patch Patch1009: 1009-Implement-allocator-access-utilities.patch # End Anolis customized patches +Patch1010: 1010-boost-add-sw.patch %bcond_with tests %bcond_with docs_generated @@ -683,6 +684,7 @@ find ./boost -name '*.hpp' -perm /111 | xargs chmod a-x %patch1007 -p2 %patch1008 -p2 %patch1009 -p2 +%patch1010 -p1 %build PYTHON3_ABIFLAGS=$(/usr/bin/python3-config --abiflags) @@ -1342,6 +1344,9 @@ fi %{_mandir}/man1/bjam.1* %changelog +* Tue Mar 19 2024 wxiat - 1.66.0-13.0.2 +- cherry-pick `add sw patch #ca22c7e4c2f3f6e491647752c2ddda1be280209a`. + * Wed Jul 05 2023 Liwei Ge - 1.66.0-13.0.1 - backport patches to fit with C++20 until upstream chase up: * Replace-std::allocate-with-std::allocator_traits.patch