diff --git a/doc/index.html b/doc/index.html index 2d2c965..ed49cbb 100644 --- a/doc/index.html +++ b/doc/index.html @@ -632,6 +632,11 @@ review uint8_t have been added for improved generality. (Pierre Talbot)
  • Overloads of endian_reverse_inplace() have been replaced with a single endian_reverse_inplace() template. (Pierre Talbot)
  • +
  • For X86 and X64 architectures, which permit unaligned loads and stores, + unaligned little endian buffer and arithmetic types use regular loads and + stores when the size is exact. This makes unaligned little endian buffer and + arithmetic types significantly more efficient on these architectures. (Jeremy + Maitin-Shepard)
  • C++11 features affecting interfaces, such as noexcept, are now used. C++03 compilers are still supported.
  • @@ -641,15 +646,15 @@ review

    Acknowledgements

    Comments and suggestions were received from Adder, Benaka Moorthi, Christopher Kohlhoff, Cliff Green, Daniel James, Gennaro Proto, Giovanni Piero -Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jeff Flinn, John Filo, John +Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jeff Flinn, Jeremy Maitin-Shepard, John Filo, John Maddock, Kim Barrett, Marsh Ray, Martin Bonner, Mathias Gaunard, Matias Capeletto, Neil Mayhew, Paul Bristow, Pierre Talbot, Phil Endecott, Pyry Jahkola, Rene Rivera, Robert Stewart, Roland Schwarz, Scott McMurray, Sebastian Redl, Tim Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and -Vitaly Budovski,.

    +Vitaly Budovsk. Apologies if anyone has been missed.


    Last revised: -04 January, 2015

    +06 January, 2015

    © Copyright Beman Dawes, 2011, 2013

    Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

    diff --git a/include/boost/endian/buffers.hpp b/include/boost/endian/buffers.hpp index 5d539df..fbd8364 100644 --- a/include/boost/endian/buffers.hpp +++ b/include/boost/endian/buffers.hpp @@ -291,6 +291,16 @@ namespace endian inline T load_little_endian(const void* bytes) BOOST_NOEXCEPT { +# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) + // On x86 (which is little endian), unaligned loads are permitted + if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this + // test and generate code only for the applicable return + // case since sizeof(T) and n_bytes are known at compile + // time. + { + return *reinterpret_cast(bytes); + } +# endif return unrolled_byte_loops::load_little (static_cast(bytes)); } @@ -307,6 +317,17 @@ namespace endian inline void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT { +# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) + // On x86 (which is little endian), unaligned stores are permitted + if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this + // test and generate code only for the applicable return + // case since sizeof(T) and n_bytes are known at compile + // time. + { + *reinterpret_cast(bytes) = value; + return; + } +# endif unrolled_byte_loops::store_little (static_cast(bytes), value); } diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp index d57934c..616e422 100644 --- a/test/buffer_test.cpp +++ b/test/buffer_test.cpp @@ -26,16 +26,26 @@ int cpp_main(int, char *[]) { cout << "byte swap intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG << endl; - cout << " construct" << endl; + cout << " construct big endian aligned" << endl; bel::big_int32_buf_t x(1122334455); - cout << " assign from built-in integer" << endl; + cout << " assign to buffer from built-in integer" << endl; x = 1234567890; - cout << " operator==(buffer, built-in)" << endl; + cout << " operator==(buffer.value(), built-in)" << endl; bool b1(x.value() == 1234567890); BOOST_TEST(b1); + cout << " construct little endian unaligned" << endl; + bel::little_int32_buf_ut x2(1122334455); + + cout << " assign to buffer from built-in integer" << endl; + x2 = 1234567890; + + cout << " operator==(buffer.value(), built-in)" << endl; + bool b2(x2.value() == 1234567890); + BOOST_TEST(b2); + cout << " done" << endl; return ::boost::report_errors(); diff --git a/test/msvc/buffer_test/buffer_test.vcxproj b/test/msvc/buffer_test/buffer_test.vcxproj index 401449f..2bb1bf2 100644 --- a/test/msvc/buffer_test/buffer_test.vcxproj +++ b/test/msvc/buffer_test/buffer_test.vcxproj @@ -92,6 +92,7 @@ Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + AssemblyAndSourceCode Console @@ -122,6 +123,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + AssemblyAndSourceCode Console @@ -140,6 +142,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + AssemblyAndSourceCode Console