<commit_before>/*
* Byte Swapping Operations
* (C) 1999-2008 <NAME>
* (C) 2007 <NAME>
*
* Distributed under the terms of the Botan license
*/

#ifndef BOTAN_BYTE_SWAP_H__
#define BOTAN_BYTE_SWAP_H__

#include <botan/types.h>
#include <botan/rotate.h>

#if defined(BOTAN_TARGET_CPU_HAS_SSE2)
  #include <emmintrin.h>
#endif

namespace Botan {

/*
* Byte Swapping Functions
*/
inline u16bit reverse_bytes(u16bit input)
   {
   return rotate_left(input, 8);
   }

inline u32bit reverse_bytes(u32bit input)
   {
#if BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)

   // GCC-style inline assembly for x86 or x86-64
   asm("bswapl %0" : "=r" (input) : "0" (input));
   return input;

#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_IA32)
   // Visual C++ inline asm for 32-bit x86, by <NAME>
   __asm mov eax, input;
   __asm bswap eax;

#else
   // Generic implementation
   return (rotate_right(input, 8) & 0xFF00FF00) |
          (rotate_left (input, 8) & 0x00FF00FF);
#endif
   }

inline u64bit reverse_bytes(u64bit input)
   {
#if BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_AMD64)
   // GCC-style inline assembly for x86-64
   asm("bswapq %0" : "=r" (input) : "0" (input));
   return input;

#else
   /* Generic implementation. Defined in terms of 32-bit bswap so any
    * optimizations in that version can help here (particularly
    * useful for 32-bit x86).
    */

   u32bit hi = static_cast<u32bit>(input >> 32);
   u32bit lo = static_cast<u32bit>(input);

   hi = reverse_bytes(hi);
   lo = reverse_bytes(lo);

   return (static_cast<u64bit>(lo) << 32) | hi;
#endif
   }

template<typename T>
inline void bswap_4(T x[4])
   {
   x[0] = reverse_bytes(x[0]);
   x[1] = reverse_bytes(x[1]);
   x[2] = reverse_bytes(x[2]);
   x[3] = reverse_bytes(x[3]);
   }

#if defined(BOTAN_TARGET_CPU_HAS_SSE2)

template<>
inline void bswap_4(u32bit x[4])
   {
   __m128i T = _mm_loadu_si128(reinterpret_cast<const __m128i*>(x));

   T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
   T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
<commit_msg>Add support for GCC's byteswap builtins. They were added in 4.3 and work for 32 and 64 bit integers. Using these instead of inline asm may offer better scheduling on x86, and additionally offers native byteswapping on other platforms (PPC, ARM, etc).<commit_after>/*
* Byte Swapping Operations
* (C) 1999-2008 <NAME>
* (C) 2007 <NAME>
*
* Distributed under the terms of the Botan license
*/

#ifndef BOTAN_BYTE_SWAP_H__
#define BOTAN_BYTE_SWAP_H__

#include <botan/types.h>
#include <botan/rotate.h>

#if defined(BOTAN_TARGET_CPU_HAS_SSE2)
  #include <emmintrin.h>
#endif

namespace Botan {

/**
* Swap a 16 bit integer
*/
inline u16bit reverse_bytes(u16bit input)
   {
   return rotate_left(input, 8);
   }

/**
* Swap a 32 bit integer
*/
inline u32bit reverse_bytes(u32bit input)
   {
#if BOTAN_GCC_VERSION >= 420

   // GCC intrinsic added in 4.3, works for a number of CPUs
   return __builtin_bswap32(input);

#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)

   // GCC-style inline assembly for x86 or x86-64
   asm("bswapl %0" : "=r" (input) : "0" (input));
   return input;

#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_IA32)

   // Visual C++ inline asm for 32-bit x86, by <NAME>
   __asm mov eax, input;
   __asm bswap eax;

#else

   // Generic implementation
   return (rotate_right(input, 8) & 0xFF00FF00) |
          (rotate_left (input, 8) & 0x00FF00FF);

#endif
   }

/**
* Swap a 64 bit integer
*/
inline u64bit reverse_bytes(u64bit input)
   {
#if BOTAN_GCC_VERSION >= 430

   // GCC intrinsic added in 4.3, works for a number of CPUs
   return __builtin_bswap64(input);

#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_AMD64)
   // GCC-style inline assembly for x86-64
   asm("bswapq %0" : "=r" (input) : "0" (input));
   return input;

#else
   /* Generic implementation. Defined in terms of 32-bit bswap so any
    * optimizations in that version can help here (particularly
    * useful for 32-bit x86).
    */

   u32bit hi = static_cast<u32bit>(input >> 32);
   u32bit lo = static_cast<u32bit>(input);

   hi = reverse_bytes(hi);
   lo = reverse_bytes(lo);

   return (static_cast<u64bit>(lo) << 32) | hi;
#endif
   }

/**
* Swap 4 Ts in an array
*/
template<typename T>
inline void bswap_4(T x[4])
   {
   x[0] = reverse_bytes(x[0]);
   x[1] = reverse_bytes(x[1]);
   x[2] = reverse_bytes(x[2]);
   x[3] = reverse_bytes(x[3]);
   }

#if defined(BOTAN_TARGET_CPU_HAS_SSE2)

/**
* Swap 4 u32bits in an array using SSE2 shuffle instructions
*/
template<>
inline void bswap_4(u32bit x[4])
   {
   __m128i T = _mm_loadu_si128(reinterpret_cast<const __m128i*>(x));

   T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
   T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));

{'fraction_non_alphanumeric': 0.12634408602150538, 'fraction_numerical': 0.05562448304383788, 'mean_word_length': 3.900709219858156, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6298242', 'n_tokens_mistral': 2122, 'n_tokens_neox': 1906, 'n_words': 485}