/* $Id: sph_types.h 260 2011-07-21 01:02:38Z tp $ */1/**2* Basic type definitions.3*4* This header file defines the generic integer types that will be used5* for the implementation of hash functions; it also contains helper6* functions which encode and decode multi-byte integer values, using7* either little-endian or big-endian conventions.8*9* This file contains a compile-time test on the size of a byte10* (the <code>unsigned char</code> C type). If bytes are not octets,11* i.e. if they do not have a size of exactly 8 bits, then compilation12* is aborted. Architectures where bytes are not octets are relatively13* rare, even in the embedded devices market. We forbid non-octet bytes14* because there is no clear convention on how octet streams are encoded15* on such systems.16*17* ==========================(LICENSE BEGIN)============================18*19* Copyright (c) 2007-2010 Projet RNRT SAPHIR20*21* Permission is hereby granted, free of charge, to any person obtaining22* a copy of this software and associated documentation files (the23* "Software"), to deal in the Software without restriction, including24* without limitation the rights to use, copy, modify, merge, publish,25* distribute, sublicense, and/or sell copies of the Software, and to26* permit persons to whom the Software is furnished to do so, subject to27* the following conditions:28*29* The above copyright notice and this permission notice shall be30* included in all copies or substantial portions of the Software.31*32* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,33* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF34* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.35* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY36* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,37* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE38* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.39*40* ===========================(LICENSE END)=============================41*42* @file sph_types.h43* @author Thomas Pornin <[email protected]>44*/4546#ifndef SPH_TYPES_H__47#define SPH_TYPES_H__4849#include <limits.h>5051/*52* All our I/O functions are defined over octet streams. We do not know53* how to handle input data if bytes are not octets.54*/55#if CHAR_BIT != 856#error This code requires 8-bit bytes57#endif5859/* ============= BEGIN documentation block for Doxygen ============ */6061#ifdef DOXYGEN_IGNORE6263/** @mainpage sphlib C code documentation64*65* @section overview Overview66*67* <code>sphlib</code> is a library which contains implementations of68* various cryptographic hash functions. These pages have been generated69* with <a href="http://www.doxygen.org/index.html">doxygen</a> and70* document the API for the C implementations.71*72* The API is described in appropriate header files, which are available73* in the "Files" section. Each hash function family has its own header,74* whose name begins with <code>"sph_"</code> and contains the family75* name. For instance, the API for the RIPEMD hash functions is available76* in the header file <code>sph_ripemd.h</code>.77*78* @section principles API structure and conventions79*80* @subsection io Input/output conventions81*82* In all generality, hash functions operate over strings of bits.83* Individual bits are rarely encountered in C programming or actual84* communication protocols; most protocols converge on the ubiquitous85* "octet" which is a group of eight bits. Data is thus expressed as a86* stream of octets. The C programming language contains the notion of a87* "byte", which is a data unit managed under the type <code>"unsigned88* char"</code>. The C standard prescribes that a byte should hold at89* least eight bits, but possibly more. Most modern architectures, even90* in the embedded world, feature eight-bit bytes, i.e. map bytes to91* octets.92*93* Nevertheless, for some of the implemented hash functions, an extra94* API has been added, which allows the input of arbitrary sequences of95* bits: when the computation is about to be closed, 1 to 7 extra bits96* can be added. The functions for which this API is implemented include97* the SHA-2 functions and all SHA-3 candidates.98*99* <code>sphlib</code> defines hash function which may hash octet streams,100* i.e. streams of bits where the number of bits is a multiple of eight.101* The data input functions in the <code>sphlib</code> API expect data102* as anonymous pointers (<code>"const void *"</code>) with a length103* (of type <code>"size_t"</code>) which gives the input data chunk length104* in bytes. A byte is assumed to be an octet; the <code>sph_types.h</code>105* header contains a compile-time test which prevents compilation on106* architectures where this property is not met.107*108* The hash function output is also converted into bytes. All currently109* implemented hash functions have an output width which is a multiple of110* eight, and this is likely to remain true for new designs.111*112* Most hash functions internally convert input data into 32-bit of 64-bit113* words, using either little-endian or big-endian conversion. The hash114* output also often consists of such words, which are encoded into output115* bytes with a similar endianness convention. Some hash functions have116* been only loosely specified on that subject; when necessary,117* <code>sphlib</code> has been tested against published "reference"118* implementations in order to use the same conventions.119*120* @subsection shortname Function short name121*122* Each implemented hash function has a "short name" which is used123* internally to derive the identifiers for the functions and context124* structures which the function uses. For instance, MD5 has the short125* name <code>"md5"</code>. Short names are listed in the next section,126* for the implemented hash functions. In subsequent sections, the127* short name will be assumed to be <code>"XXX"</code>: replace with the128* actual hash function name to get the C identifier.129*130* Note: some functions within the same family share the same core131* elements, such as update function or context structure. Correspondingly,132* some of the defined types or functions may actually be macros which133* transparently evaluate to another type or function name.134*135* @subsection context Context structure136*137* Each implemented hash fonction has its own context structure, available138* under the type name <code>"sph_XXX_context"</code> for the hash function139* with short name <code>"XXX"</code>. This structure holds all needed140* state for a running hash computation.141*142* The contents of these structures are meant to be opaque, and private143* to the implementation. However, these contents are specified in the144* header files so that application code which uses <code>sphlib</code>145* may access the size of those structures.146*147* The caller is responsible for allocating the context structure,148* whether by dynamic allocation (<code>malloc()</code> or equivalent),149* static allocation (a global permanent variable), as an automatic150* variable ("on the stack"), or by any other mean which ensures proper151* structure alignment. <code>sphlib</code> code performs no dynamic152* allocation by itself.153*154* The context must be initialized before use, using the155* <code>sph_XXX_init()</code> function. This function sets the context156* state to proper initial values for hashing.157*158* Since all state data is contained within the context structure,159* <code>sphlib</code> is thread-safe and reentrant: several hash160* computations may be performed in parallel, provided that they do not161* operate on the same context. Moreover, a running computation can be162* cloned by copying the context (with a simple <code>memcpy()</code>):163* the context and its clone are then independant and may be updated164* with new data and/or closed without interfering with each other.165* Similarly, a context structure can be moved in memory at will:166* context structures contain no pointer, in particular no pointer to167* themselves.168*169* @subsection dataio Data input170*171* Hashed data is input with the <code>sph_XXX()</code> fonction, which172* takes as parameters a pointer to the context, a pointer to the data173* to hash, and the number of data bytes to hash. The context is updated174* with the new data.175*176* Data can be input in one or several calls, with arbitrary input lengths.177* However, it is best, performance wise, to input data by relatively big178* chunks (say a few kilobytes), because this allows <code>sphlib</code> to179* optimize things and avoid internal copying.180*181* When all data has been input, the context can be closed with182* <code>sph_XXX_close()</code>. The hash output is computed and written183* into the provided buffer. The caller must take care to provide a184* buffer of appropriate length; e.g., when using SHA-1, the output is185* a 20-byte word, therefore the output buffer must be at least 20-byte186* long.187*188* For some hash functions, the <code>sph_XXX_addbits_and_close()</code>189* function can be used instead of <code>sph_XXX_close()</code>. This190* function can take a few extra <strong>bits</strong> to be added at191* the end of the input message. This allows hashing messages with a192* bit length which is not a multiple of 8. The extra bits are provided193* as an unsigned integer value, and a bit count. The bit count must be194* between 0 and 7, inclusive. The extra bits are provided as bits 7 to195* 0 (bits of numerical value 128, 64, 32... downto 0), in that order.196* For instance, to add three bits of value 1, 1 and 0, the unsigned197* integer will have value 192 (1*128 + 1*64 + 0*32) and the bit count198* will be 3.199*200* The <code>SPH_SIZE_XXX</code> macro is defined for each hash function;201* it evaluates to the function output size, expressed in bits. For instance,202* <code>SPH_SIZE_sha1</code> evaluates to <code>160</code>.203*204* When closed, the context is automatically reinitialized and can be205* immediately used for another computation. It is not necessary to call206* <code>sph_XXX_init()</code> after a close. Note that207* <code>sph_XXX_init()</code> can still be called to "reset" a context,208* i.e. forget previously input data, and get back to the initial state.209*210* @subsection alignment Data alignment211*212* "Alignment" is a property of data, which is said to be "properly213* aligned" when its emplacement in memory is such that the data can214* be optimally read by full words. This depends on the type of access;215* basically, some hash functions will read data by 32-bit or 64-bit216* words. <code>sphlib</code> does not mandate such alignment for input217* data, but using aligned data can substantially improve performance.218*219* As a rule, it is best to input data by chunks whose length (in bytes)220* is a multiple of eight, and which begins at "generally aligned"221* addresses, such as the base address returned by a call to222* <code>malloc()</code>.223*224* @section functions Implemented functions225*226* We give here the list of implemented functions. They are grouped by227* family; to each family corresponds a specific header file. Each228* individual function has its associated "short name". Please refer to229* the documentation for that header file to get details on the hash230* function denomination and provenance.231*232* Note: the functions marked with a '(64)' in the list below are233* available only if the C compiler provides an integer type of length234* 64 bits or more. Such a type is mandatory in the latest C standard235* (ISO 9899:1999, aka "C99") and is present in several older compilers236* as well, so chances are that such a type is available.237*238* - HAVAL family: file <code>sph_haval.h</code>239* - HAVAL-128/3 (128-bit, 3 passes): short name: <code>haval128_3</code>240* - HAVAL-128/4 (128-bit, 4 passes): short name: <code>haval128_4</code>241* - HAVAL-128/5 (128-bit, 5 passes): short name: <code>haval128_5</code>242* - HAVAL-160/3 (160-bit, 3 passes): short name: <code>haval160_3</code>243* - HAVAL-160/4 (160-bit, 4 passes): short name: <code>haval160_4</code>244* - HAVAL-160/5 (160-bit, 5 passes): short name: <code>haval160_5</code>245* - HAVAL-192/3 (192-bit, 3 passes): short name: <code>haval192_3</code>246* - HAVAL-192/4 (192-bit, 4 passes): short name: <code>haval192_4</code>247* - HAVAL-192/5 (192-bit, 5 passes): short name: <code>haval192_5</code>248* - HAVAL-224/3 (224-bit, 3 passes): short name: <code>haval224_3</code>249* - HAVAL-224/4 (224-bit, 4 passes): short name: <code>haval224_4</code>250* - HAVAL-224/5 (224-bit, 5 passes): short name: <code>haval224_5</code>251* - HAVAL-256/3 (256-bit, 3 passes): short name: <code>haval256_3</code>252* - HAVAL-256/4 (256-bit, 4 passes): short name: <code>haval256_4</code>253* - HAVAL-256/5 (256-bit, 5 passes): short name: <code>haval256_5</code>254* - MD2: file <code>sph_md2.h</code>, short name: <code>md2</code>255* - MD4: file <code>sph_md4.h</code>, short name: <code>md4</code>256* - MD5: file <code>sph_md5.h</code>, short name: <code>md5</code>257* - PANAMA: file <code>sph_panama.h</code>, short name: <code>panama</code>258* - RadioGatun family: file <code>sph_radiogatun.h</code>259* - RadioGatun[32]: short name: <code>radiogatun32</code>260* - RadioGatun[64]: short name: <code>radiogatun64</code> (64)261* - RIPEMD family: file <code>sph_ripemd.h</code>262* - RIPEMD: short name: <code>ripemd</code>263* - RIPEMD-128: short name: <code>ripemd128</code>264* - RIPEMD-160: short name: <code>ripemd160</code>265* - SHA-0: file <code>sph_sha0.h</code>, short name: <code>sha0</code>266* - SHA-1: file <code>sph_sha1.h</code>, short name: <code>sha1</code>267* - SHA-2 family, 32-bit hashes: file <code>sph_sha2.h</code>268* - SHA-224: short name: <code>sha224</code>269* - SHA-256: short name: <code>sha256</code>270* - SHA-384: short name: <code>sha384</code> (64)271* - SHA-512: short name: <code>sha512</code> (64)272* - Tiger family: file <code>sph_tiger.h</code>273* - Tiger: short name: <code>tiger</code> (64)274* - Tiger2: short name: <code>tiger2</code> (64)275* - WHIRLPOOL family: file <code>sph_whirlpool.h</code>276* - WHIRLPOOL-0: short name: <code>whirlpool0</code> (64)277* - WHIRLPOOL-1: short name: <code>whirlpool1</code> (64)278* - WHIRLPOOL: short name: <code>whirlpool</code> (64)279*280* The fourteen second-round SHA-3 candidates are also implemented;281* when applicable, the implementations follow the "final" specifications282* as published for the third round of the SHA-3 competition (BLAKE,283* Groestl, JH, Keccak and Skein have been tweaked for third round).284*285* - BLAKE family: file <code>sph_blake.h</code>286* - BLAKE-224: short name: <code>blake224</code>287* - BLAKE-256: short name: <code>blake256</code>288* - BLAKE-384: short name: <code>blake384</code>289* - BLAKE-512: short name: <code>blake512</code>290* - BMW (Blue Midnight Wish) family: file <code>sph_bmw.h</code>291* - BMW-224: short name: <code>bmw224</code>292* - BMW-256: short name: <code>bmw256</code>293* - BMW-384: short name: <code>bmw384</code> (64)294* - BMW-512: short name: <code>bmw512</code> (64)295* - CubeHash family: file <code>sph_cubehash.h</code> (specified as296* CubeHash16/32 in the CubeHash specification)297* - CubeHash-224: short name: <code>cubehash224</code>298* - CubeHash-256: short name: <code>cubehash256</code>299* - CubeHash-384: short name: <code>cubehash384</code>300* - CubeHash-512: short name: <code>cubehash512</code>301* - ECHO family: file <code>sph_echo.h</code>302* - ECHO-224: short name: <code>echo224</code>303* - ECHO-256: short name: <code>echo256</code>304* - ECHO-384: short name: <code>echo384</code>305* - ECHO-512: short name: <code>echo512</code>306* - Fugue family: file <code>sph_fugue.h</code>307* - Fugue-224: short name: <code>fugue224</code>308* - Fugue-256: short name: <code>fugue256</code>309* - Fugue-384: short name: <code>fugue384</code>310* - Fugue-512: short name: <code>fugue512</code>311* - Groestl family: file <code>sph_groestl.h</code>312* - Groestl-224: short name: <code>groestl224</code>313* - Groestl-256: short name: <code>groestl256</code>314* - Groestl-384: short name: <code>groestl384</code>315* - Groestl-512: short name: <code>groestl512</code>316* - Hamsi family: file <code>sph_hamsi.h</code>317* - Hamsi-224: short name: <code>hamsi224</code>318* - Hamsi-256: short name: <code>hamsi256</code>319* - Hamsi-384: short name: <code>hamsi384</code>320* - Hamsi-512: short name: <code>hamsi512</code>321* - JH family: file <code>sph_jh.h</code>322* - JH-224: short name: <code>jh224</code>323* - JH-256: short name: <code>jh256</code>324* - JH-384: short name: <code>jh384</code>325* - JH-512: short name: <code>jh512</code>326* - Keccak family: file <code>sph_keccak.h</code>327* - Keccak-224: short name: <code>keccak224</code>328* - Keccak-256: short name: <code>keccak256</code>329* - Keccak-384: short name: <code>keccak384</code>330* - Keccak-512: short name: <code>keccak512</code>331* - Luffa family: file <code>sph_luffa.h</code>332* - Luffa-224: short name: <code>luffa224</code>333* - Luffa-256: short name: <code>luffa256</code>334* - Luffa-384: short name: <code>luffa384</code>335* - Luffa-512: short name: <code>luffa512</code>336* - Shabal family: file <code>sph_shabal.h</code>337* - Shabal-192: short name: <code>shabal192</code>338* - Shabal-224: short name: <code>shabal224</code>339* - Shabal-256: short name: <code>shabal256</code>340* - Shabal-384: short name: <code>shabal384</code>341* - Shabal-512: short name: <code>shabal512</code>342* - SHAvite-3 family: file <code>sph_shavite.h</code>343* - SHAvite-224 (nominally "SHAvite-3 with 224-bit output"):344* short name: <code>shabal224</code>345* - SHAvite-256 (nominally "SHAvite-3 with 256-bit output"):346* short name: <code>shabal256</code>347* - SHAvite-384 (nominally "SHAvite-3 with 384-bit output"):348* short name: <code>shabal384</code>349* - SHAvite-512 (nominally "SHAvite-3 with 512-bit output"):350* short name: <code>shabal512</code>351* - SIMD family: file <code>sph_simd.h</code>352* - SIMD-224: short name: <code>simd224</code>353* - SIMD-256: short name: <code>simd256</code>354* - SIMD-384: short name: <code>simd384</code>355* - SIMD-512: short name: <code>simd512</code>356* - Skein family: file <code>sph_skein.h</code>357* - Skein-224 (nominally specified as Skein-512-224): short name:358* <code>skein224</code> (64)359* - Skein-256 (nominally specified as Skein-512-256): short name:360* <code>skein256</code> (64)361* - Skein-384 (nominally specified as Skein-512-384): short name:362* <code>skein384</code> (64)363* - Skein-512 (nominally specified as Skein-512-512): short name:364* <code>skein512</code> (64)365*366* For the second-round SHA-3 candidates, the functions are as specified367* for round 2, i.e. with the "tweaks" that some candidates added368* between round 1 and round 2. Also, some of the submitted packages for369* round 2 contained errors, in the specification, reference code, or370* both. <code>sphlib</code> implements the corrected versions.371*/372373/** @hideinitializer374* Unsigned integer type whose length is at least 32 bits; on most375* architectures, it will have a width of exactly 32 bits. Unsigned C376* types implement arithmetics modulo a power of 2; use the377* <code>SPH_T32()</code> macro to ensure that the value is truncated378* to exactly 32 bits. Unless otherwise specified, all macros and379* functions which accept <code>sph_u32</code> values assume that these380* values fit on 32 bits, i.e. do not exceed 2^32-1, even on architectures381* where <code>sph_u32</code> is larger than that.382*/383typedef __arch_dependant__ sph_u32;384385/** @hideinitializer386* Signed integer type corresponding to <code>sph_u32</code>; it has387* width 32 bits or more.388*/389typedef __arch_dependant__ sph_s32;390391/** @hideinitializer392* Unsigned integer type whose length is at least 64 bits; on most393* architectures which feature such a type, it will have a width of394* exactly 64 bits. C99-compliant platform will have this type; it395* is also defined when the GNU compiler (gcc) is used, and on396* platforms where <code>unsigned long</code> is large enough. If this397* type is not available, then some hash functions which depends on398* a 64-bit type will not be available (most notably SHA-384, SHA-512,399* Tiger and WHIRLPOOL).400*/401typedef __arch_dependant__ sph_u64;402403/** @hideinitializer404* Signed integer type corresponding to <code>sph_u64</code>; it has405* width 64 bits or more.406*/407typedef __arch_dependant__ sph_s64;408409/**410* This macro expands the token <code>x</code> into a suitable411* constant expression of type <code>sph_u32</code>. Depending on412* how this type is defined, a suffix such as <code>UL</code> may413* be appended to the argument.414*415* @param x the token to expand into a suitable constant expression416*/417#define SPH_C32(x)418419/**420* Truncate a 32-bit value to exactly 32 bits. On most systems, this is421* a no-op, recognized as such by the compiler.422*423* @param x the value to truncate (of type <code>sph_u32</code>)424*/425#define SPH_T32(x)426427/**428* Rotate a 32-bit value by a number of bits to the left. The rotate429* count must reside between 1 and 31. This macro assumes that its430* first argument fits in 32 bits (no extra bit allowed on machines where431* <code>sph_u32</code> is wider); both arguments may be evaluated432* several times.433*434* @param x the value to rotate (of type <code>sph_u32</code>)435* @param n the rotation count (between 1 and 31, inclusive)436*/437#define SPH_ROTL32(x, n)438439/**440* Rotate a 32-bit value by a number of bits to the left. The rotate441* count must reside between 1 and 31. This macro assumes that its442* first argument fits in 32 bits (no extra bit allowed on machines where443* <code>sph_u32</code> is wider); both arguments may be evaluated444* several times.445*446* @param x the value to rotate (of type <code>sph_u32</code>)447* @param n the rotation count (between 1 and 31, inclusive)448*/449#define SPH_ROTR32(x, n)450451/**452* This macro is defined on systems for which a 64-bit type has been453* detected, and is used for <code>sph_u64</code>.454*/455#define SPH_64456457/**458* This macro is defined on systems for the "native" integer size is459* 64 bits (64-bit values fit in one register).460*/461#define SPH_64_TRUE462463/**464* This macro expands the token <code>x</code> into a suitable465* constant expression of type <code>sph_u64</code>. Depending on466* how this type is defined, a suffix such as <code>ULL</code> may467* be appended to the argument. This macro is defined only if a468* 64-bit type was detected and used for <code>sph_u64</code>.469*470* @param x the token to expand into a suitable constant expression471*/472#define SPH_C64(x)473474/**475* Truncate a 64-bit value to exactly 64 bits. On most systems, this is476* a no-op, recognized as such by the compiler. This macro is defined only477* if a 64-bit type was detected and used for <code>sph_u64</code>.478*479* @param x the value to truncate (of type <code>sph_u64</code>)480*/481#define SPH_T64(x)482483/**484* Rotate a 64-bit value by a number of bits to the left. The rotate485* count must reside between 1 and 63. This macro assumes that its486* first argument fits in 64 bits (no extra bit allowed on machines where487* <code>sph_u64</code> is wider); both arguments may be evaluated488* several times. This macro is defined only if a 64-bit type was detected489* and used for <code>sph_u64</code>.490*491* @param x the value to rotate (of type <code>sph_u64</code>)492* @param n the rotation count (between 1 and 63, inclusive)493*/494#define SPH_ROTL64(x, n)495496/**497* Rotate a 64-bit value by a number of bits to the left. The rotate498* count must reside between 1 and 63. This macro assumes that its499* first argument fits in 64 bits (no extra bit allowed on machines where500* <code>sph_u64</code> is wider); both arguments may be evaluated501* several times. This macro is defined only if a 64-bit type was detected502* and used for <code>sph_u64</code>.503*504* @param x the value to rotate (of type <code>sph_u64</code>)505* @param n the rotation count (between 1 and 63, inclusive)506*/507#define SPH_ROTR64(x, n)508509/**510* This macro evaluates to <code>inline</code> or an equivalent construction,511* if available on the compilation platform, or to nothing otherwise. This512* is used to declare inline functions, for which the compiler should513* endeavour to include the code directly in the caller. Inline functions514* are typically defined in header files as replacement for macros.515*/516#define SPH_INLINE517518/**519* This macro is defined if the platform has been detected as using520* little-endian convention. This implies that the <code>sph_u32</code>521* type (and the <code>sph_u64</code> type also, if it is defined) has522* an exact width (i.e. exactly 32-bit, respectively 64-bit).523*/524#define SPH_LITTLE_ENDIAN525526/**527* This macro is defined if the platform has been detected as using528* big-endian convention. This implies that the <code>sph_u32</code>529* type (and the <code>sph_u64</code> type also, if it is defined) has530* an exact width (i.e. exactly 32-bit, respectively 64-bit).531*/532#define SPH_BIG_ENDIAN533534/**535* This macro is defined if 32-bit words (and 64-bit words, if defined)536* can be read from and written to memory efficiently in little-endian537* convention. This is the case for little-endian platforms, and also538* for the big-endian platforms which have special little-endian access539* opcodes (e.g. Ultrasparc).540*/541#define SPH_LITTLE_FAST542543/**544* This macro is defined if 32-bit words (and 64-bit words, if defined)545* can be read from and written to memory efficiently in big-endian546* convention. This is the case for little-endian platforms, and also547* for the little-endian platforms which have special big-endian access548* opcodes.549*/550#define SPH_BIG_FAST551552/**553* On some platforms, this macro is defined to an unsigned integer type554* into which pointer values may be cast. The resulting value can then555* be tested for being a multiple of 2, 4 or 8, indicating an aligned556* pointer for, respectively, 16-bit, 32-bit or 64-bit memory accesses.557*/558#define SPH_UPTR559560/**561* When defined, this macro indicates that unaligned memory accesses562* are possible with only a minor penalty, and thus should be prefered563* over strategies which first copy data to an aligned buffer.564*/565#define SPH_UNALIGNED566567/**568* Byte-swap a 32-bit word (i.e. <code>0x12345678</code> becomes569* <code>0x78563412</code>). This is an inline function which resorts570* to inline assembly on some platforms, for better performance.571*572* @param x the 32-bit value to byte-swap573* @return the byte-swapped value574*/575static inline sph_u32 sph_bswap32(sph_u32 x);576577/**578* Byte-swap a 64-bit word. This is an inline function which resorts579* to inline assembly on some platforms, for better performance. This580* function is defined only if a suitable 64-bit type was found for581* <code>sph_u64</code>582*583* @param x the 64-bit value to byte-swap584* @return the byte-swapped value585*/586static inline sph_u64 sph_bswap64(sph_u64 x);587588/**589* Decode a 16-bit unsigned value from memory, in little-endian convention590* (least significant byte comes first).591*592* @param src the source address593* @return the decoded value594*/595static inline unsigned sph_dec16le(const void *src);596597/**598* Encode a 16-bit unsigned value into memory, in little-endian convention599* (least significant byte comes first).600*601* @param dst the destination buffer602* @param val the value to encode603*/604static inline void sph_enc16le(void *dst, unsigned val);605606/**607* Decode a 16-bit unsigned value from memory, in big-endian convention608* (most significant byte comes first).609*610* @param src the source address611* @return the decoded value612*/613static inline unsigned sph_dec16be(const void *src);614615/**616* Encode a 16-bit unsigned value into memory, in big-endian convention617* (most significant byte comes first).618*619* @param dst the destination buffer620* @param val the value to encode621*/622static inline void sph_enc16be(void *dst, unsigned val);623624/**625* Decode a 32-bit unsigned value from memory, in little-endian convention626* (least significant byte comes first).627*628* @param src the source address629* @return the decoded value630*/631static inline sph_u32 sph_dec32le(const void *src);632633/**634* Decode a 32-bit unsigned value from memory, in little-endian convention635* (least significant byte comes first). This function assumes that the636* source address is suitably aligned for a direct access, if the platform637* supports such things; it can thus be marginally faster than the generic638* <code>sph_dec32le()</code> function.639*640* @param src the source address641* @return the decoded value642*/643static inline sph_u32 sph_dec32le_aligned(const void *src);644645/**646* Encode a 32-bit unsigned value into memory, in little-endian convention647* (least significant byte comes first).648*649* @param dst the destination buffer650* @param val the value to encode651*/652static inline void sph_enc32le(void *dst, sph_u32 val);653654/**655* Encode a 32-bit unsigned value into memory, in little-endian convention656* (least significant byte comes first). This function assumes that the657* destination address is suitably aligned for a direct access, if the658* platform supports such things; it can thus be marginally faster than659* the generic <code>sph_enc32le()</code> function.660*661* @param dst the destination buffer662* @param val the value to encode663*/664static inline void sph_enc32le_aligned(void *dst, sph_u32 val);665666/**667* Decode a 32-bit unsigned value from memory, in big-endian convention668* (most significant byte comes first).669*670* @param src the source address671* @return the decoded value672*/673static inline sph_u32 sph_dec32be(const void *src);674675/**676* Decode a 32-bit unsigned value from memory, in big-endian convention677* (most significant byte comes first). This function assumes that the678* source address is suitably aligned for a direct access, if the platform679* supports such things; it can thus be marginally faster than the generic680* <code>sph_dec32be()</code> function.681*682* @param src the source address683* @return the decoded value684*/685static inline sph_u32 sph_dec32be_aligned(const void *src);686687/**688* Encode a 32-bit unsigned value into memory, in big-endian convention689* (most significant byte comes first).690*691* @param dst the destination buffer692* @param val the value to encode693*/694static inline void sph_enc32be(void *dst, sph_u32 val);695696/**697* Encode a 32-bit unsigned value into memory, in big-endian convention698* (most significant byte comes first). This function assumes that the699* destination address is suitably aligned for a direct access, if the700* platform supports such things; it can thus be marginally faster than701* the generic <code>sph_enc32be()</code> function.702*703* @param dst the destination buffer704* @param val the value to encode705*/706static inline void sph_enc32be_aligned(void *dst, sph_u32 val);707708/**709* Decode a 64-bit unsigned value from memory, in little-endian convention710* (least significant byte comes first). This function is defined only711* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.712*713* @param src the source address714* @return the decoded value715*/716static inline sph_u64 sph_dec64le(const void *src);717718/**719* Decode a 64-bit unsigned value from memory, in little-endian convention720* (least significant byte comes first). This function assumes that the721* source address is suitably aligned for a direct access, if the platform722* supports such things; it can thus be marginally faster than the generic723* <code>sph_dec64le()</code> function. This function is defined only724* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.725*726* @param src the source address727* @return the decoded value728*/729static inline sph_u64 sph_dec64le_aligned(const void *src);730731/**732* Encode a 64-bit unsigned value into memory, in little-endian convention733* (least significant byte comes first). This function is defined only734* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.735*736* @param dst the destination buffer737* @param val the value to encode738*/739static inline void sph_enc64le(void *dst, sph_u64 val);740741/**742* Encode a 64-bit unsigned value into memory, in little-endian convention743* (least significant byte comes first). This function assumes that the744* destination address is suitably aligned for a direct access, if the745* platform supports such things; it can thus be marginally faster than746* the generic <code>sph_enc64le()</code> function. This function is defined747* only if a suitable 64-bit type was detected and used for748* <code>sph_u64</code>.749*750* @param dst the destination buffer751* @param val the value to encode752*/753static inline void sph_enc64le_aligned(void *dst, sph_u64 val);754755/**756* Decode a 64-bit unsigned value from memory, in big-endian convention757* (most significant byte comes first). This function is defined only758* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.759*760* @param src the source address761* @return the decoded value762*/763static inline sph_u64 sph_dec64be(const void *src);764765/**766* Decode a 64-bit unsigned value from memory, in big-endian convention767* (most significant byte comes first). This function assumes that the768* source address is suitably aligned for a direct access, if the platform769* supports such things; it can thus be marginally faster than the generic770* <code>sph_dec64be()</code> function. This function is defined only771* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.772*773* @param src the source address774* @return the decoded value775*/776static inline sph_u64 sph_dec64be_aligned(const void *src);777778/**779* Encode a 64-bit unsigned value into memory, in big-endian convention780* (most significant byte comes first). This function is defined only781* if a suitable 64-bit type was detected and used for <code>sph_u64</code>.782*783* @param dst the destination buffer784* @param val the value to encode785*/786static inline void sph_enc64be(void *dst, sph_u64 val);787788/**789* Encode a 64-bit unsigned value into memory, in big-endian convention790* (most significant byte comes first). This function assumes that the791* destination address is suitably aligned for a direct access, if the792* platform supports such things; it can thus be marginally faster than793* the generic <code>sph_enc64be()</code> function. This function is defined794* only if a suitable 64-bit type was detected and used for795* <code>sph_u64</code>.796*797* @param dst the destination buffer798* @param val the value to encode799*/800static inline void sph_enc64be_aligned(void *dst, sph_u64 val);801802#endif803804/* ============== END documentation block for Doxygen ============= */805806#ifndef DOXYGEN_IGNORE807808/*809* We want to define the types "sph_u32" and "sph_u64" which hold810* unsigned values of at least, respectively, 32 and 64 bits. These811* tests should select appropriate types for most platforms. The812* macro "SPH_64" is defined if the 64-bit is supported.813*/814815#undef SPH_64816#undef SPH_64_TRUE817818#if defined __STDC__ && __STDC_VERSION__ >= 199901L819820/*821* On C99 implementations, we can use <stdint.h> to get an exact 64-bit822* type, if any, or otherwise use a wider type (which must exist, for823* C99 conformance).824*/825826#include <stdint.h>827828#ifdef UINT32_MAX829typedef uint32_t sph_u32;830typedef int32_t sph_s32;831#else832typedef uint_fast32_t sph_u32;833typedef int_fast32_t sph_s32;834#endif835#if !SPH_NO_64836#ifdef UINT64_MAX837typedef uint64_t sph_u64;838typedef int64_t sph_s64;839#else840typedef uint_fast64_t sph_u64;841typedef int_fast64_t sph_s64;842#endif843#endif844845#define SPH_C32(x) ((sph_u32)(x))846#if !SPH_NO_64847#define SPH_C64(x) ((sph_u64)(x))848#define SPH_64 1849#endif850851#else852853/*854* On non-C99 systems, we use "unsigned int" if it is wide enough,855* "unsigned long" otherwise. This supports all "reasonable" architectures.856* We have to be cautious: pre-C99 preprocessors handle constants857* differently in '#if' expressions. Hence the shifts to test UINT_MAX.858*/859860#if ((UINT_MAX >> 11) >> 11) >= 0x3FF861862typedef unsigned int sph_u32;863typedef int sph_s32;864865#define SPH_C32(x) ((sph_u32)(x ## U))866867#else868869typedef unsigned long sph_u32;870typedef long sph_s32;871872#define SPH_C32(x) ((sph_u32)(x ## UL))873874#endif875876#if !SPH_NO_64877878/*879* We want a 64-bit type. We use "unsigned long" if it is wide enough (as880* is common on 64-bit architectures such as AMD64, Alpha or Sparcv9),881* "unsigned long long" otherwise, if available. We use ULLONG_MAX to882* test whether "unsigned long long" is available; we also know that883* gcc features this type, even if the libc header do not know it.884*/885886#if ((ULONG_MAX >> 31) >> 31) >= 3887888typedef unsigned long sph_u64;889typedef long sph_s64;890891#define SPH_C64(x) ((sph_u64)(x ## UL))892893#define SPH_64 1894895#elif ((ULLONG_MAX >> 31) >> 31) >= 3 || defined __GNUC__896897typedef unsigned long long sph_u64;898typedef long long sph_s64;899900#define SPH_C64(x) ((sph_u64)(x ## ULL))901902#define SPH_64 1903904#else905906/*907* No 64-bit type...908*/909910#endif911912#endif913914#endif915916/*917* If the "unsigned long" type has length 64 bits or more, then this is918* a "true" 64-bit architectures. This is also true with Visual C on919* amd64, even though the "long" type is limited to 32 bits.920*/921#if SPH_64 && (((ULONG_MAX >> 31) >> 31) >= 3 || defined _M_X64)922#define SPH_64_TRUE 1923#endif924925/*926* Implementation note: some processors have specific opcodes to perform927* a rotation. Recent versions of gcc recognize the expression above and928* use the relevant opcodes, when appropriate.929*/930931#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF))932#ifdef _MSC_VER933#define SPH_ROTL32(x, n) _rotl(x, n)934#define SPH_ROTR32(x, n) _rotr(x, n)935#else936#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n))))937#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n)))938#endif939940#if SPH_64941942#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF))943#ifdef _MSC_VER944#define SPH_ROTL64(x, n) _rotl64(x, n)945#define SPH_ROTR64(x, n) _rotr64(x, n)946#else947#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n))))948#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n)))949#endif950951#endif952953#ifndef DOXYGEN_IGNORE954/*955* Define SPH_INLINE to be an "inline" qualifier, if available. We define956* some small macro-like functions which benefit greatly from being inlined.957*/958#if (defined __STDC__ && __STDC_VERSION__ >= 199901L) || defined __GNUC__959#define SPH_INLINE inline960#elif defined _MSC_VER961#define SPH_INLINE __inline962#else963#define SPH_INLINE964#endif965#endif966967/*968* We define some macros which qualify the architecture. These macros969* may be explicit set externally (e.g. as compiler parameters). The970* code below sets those macros if they are not already defined.971*972* Most macros are boolean, thus evaluate to either zero or non-zero.973* The SPH_UPTR macro is special, in that it evaluates to a C type,974* or is not defined.975*976* SPH_UPTR if defined: unsigned type to cast pointers into977*978* SPH_UNALIGNED non-zero if unaligned accesses are efficient979* SPH_LITTLE_ENDIAN non-zero if architecture is known to be little-endian980* SPH_BIG_ENDIAN non-zero if architecture is known to be big-endian981* SPH_LITTLE_FAST non-zero if little-endian decoding is fast982* SPH_BIG_FAST non-zero if big-endian decoding is fast983*984* If SPH_UPTR is defined, then encoding and decoding of 32-bit and 64-bit985* values will try to be "smart". Either SPH_LITTLE_ENDIAN or SPH_BIG_ENDIAN986* _must_ be non-zero in those situations. The 32-bit and 64-bit types987* _must_ also have an exact width.988*989* SPH_SPARCV9_GCC_32 UltraSPARC-compatible with gcc, 32-bit mode990* SPH_SPARCV9_GCC_64 UltraSPARC-compatible with gcc, 64-bit mode991* SPH_SPARCV9_GCC UltraSPARC-compatible with gcc992* SPH_I386_GCC x86-compatible (32-bit) with gcc993* SPH_I386_MSVC x86-compatible (32-bit) with Microsoft Visual C994* SPH_AMD64_GCC x86-compatible (64-bit) with gcc995* SPH_AMD64_MSVC x86-compatible (64-bit) with Microsoft Visual C996* SPH_PPC32_GCC PowerPC, 32-bit, with gcc997* SPH_PPC64_GCC PowerPC, 64-bit, with gcc998*999* TODO: enhance automatic detection, for more architectures and compilers.1000* Endianness is the most important. SPH_UNALIGNED and SPH_UPTR help with1001* some very fast functions (e.g. MD4) when using unaligned input data.1002* The CPU-specific-with-GCC macros are useful only for inline assembly,1003* normally restrained to this header file.1004*/10051006/*1007* 32-bit x86, aka "i386 compatible".1008*/1009#if defined __i386__ || defined _M_IX8610101011#define SPH_DETECT_UNALIGNED 11012#define SPH_DETECT_LITTLE_ENDIAN 11013#define SPH_DETECT_UPTR sph_u321014#ifdef __GNUC__1015#define SPH_DETECT_I386_GCC 11016#endif1017#ifdef _MSC_VER1018#define SPH_DETECT_I386_MSVC 11019#endif10201021/*1022* 64-bit x86, hereafter known as "amd64".1023*/1024#elif defined __x86_64 || defined _M_X6410251026#define SPH_DETECT_UNALIGNED 11027#define SPH_DETECT_LITTLE_ENDIAN 11028#define SPH_DETECT_UPTR sph_u641029#ifdef __GNUC__1030#define SPH_DETECT_AMD64_GCC 11031#endif1032#ifdef _MSC_VER1033#define SPH_DETECT_AMD64_MSVC 11034#endif10351036/*1037* 64-bit Sparc architecture (implies v9).1038*/1039#elif ((defined __sparc__ || defined __sparc) && defined __arch64__) \1040|| defined __sparcv910411042#define SPH_DETECT_BIG_ENDIAN 11043#define SPH_DETECT_UPTR sph_u641044#ifdef __GNUC__1045#define SPH_DETECT_SPARCV9_GCC_64 11046#define SPH_DETECT_LITTLE_FAST 11047#endif10481049/*1050* 32-bit Sparc.1051*/1052#elif (defined __sparc__ || defined __sparc) \1053&& !(defined __sparcv9 || defined __arch64__)10541055#define SPH_DETECT_BIG_ENDIAN 11056#define SPH_DETECT_UPTR sph_u321057#if defined __GNUC__ && defined __sparc_v9__1058#define SPH_DETECT_SPARCV9_GCC_32 11059#define SPH_DETECT_LITTLE_FAST 11060#endif10611062/*1063* ARM, little-endian.1064*/1065#elif defined __arm__ && __ARMEL__10661067#define SPH_DETECT_LITTLE_ENDIAN 110681069/*1070* MIPS, little-endian.1071*/1072#elif MIPSEL || _MIPSEL || __MIPSEL || __MIPSEL__10731074#define SPH_DETECT_LITTLE_ENDIAN 110751076/*1077* MIPS, big-endian.1078*/1079#elif MIPSEB || _MIPSEB || __MIPSEB || __MIPSEB__10801081#define SPH_DETECT_BIG_ENDIAN 110821083/*1084* PowerPC.1085*/1086#elif defined __powerpc__ || defined __POWERPC__ || defined __ppc__ \1087|| defined _ARCH_PPC10881089/*1090* Note: we do not declare cross-endian access to be "fast": even if1091* using inline assembly, implementation should still assume that1092* keeping the decoded word in a temporary is faster than decoding1093* it again.1094*/1095#if defined __GNUC__1096#if SPH_64_TRUE1097#define SPH_DETECT_PPC64_GCC 11098#else1099#define SPH_DETECT_PPC32_GCC 11100#endif1101#endif11021103#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN1104#define SPH_DETECT_BIG_ENDIAN 11105#elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN1106#define SPH_DETECT_LITTLE_ENDIAN 11107#endif11081109/*1110* Itanium, 64-bit.1111*/1112#elif defined __ia64 || defined __ia64__ \1113|| defined __itanium__ || defined _M_IA6411141115#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN1116#define SPH_DETECT_BIG_ENDIAN 11117#else1118#define SPH_DETECT_LITTLE_ENDIAN 11119#endif1120#if defined __LP64__ || defined _LP641121#define SPH_DETECT_UPTR sph_u641122#else1123#define SPH_DETECT_UPTR sph_u321124#endif11251126#endif11271128#if defined SPH_DETECT_SPARCV9_GCC_32 || defined SPH_DETECT_SPARCV9_GCC_641129#define SPH_DETECT_SPARCV9_GCC 11130#endif11311132#if defined SPH_DETECT_UNALIGNED && !defined SPH_UNALIGNED1133#define SPH_UNALIGNED SPH_DETECT_UNALIGNED1134#endif1135#if defined SPH_DETECT_UPTR && !defined SPH_UPTR1136#define SPH_UPTR SPH_DETECT_UPTR1137#endif1138#if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN1139#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN1140#endif1141#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN1142#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN1143#endif1144#if defined SPH_DETECT_LITTLE_FAST && !defined SPH_LITTLE_FAST1145#define SPH_LITTLE_FAST SPH_DETECT_LITTLE_FAST1146#endif1147#if defined SPH_DETECT_BIG_FAST && !defined SPH_BIG_FAST1148#define SPH_BIG_FAST SPH_DETECT_BIG_FAST1149#endif1150#if defined SPH_DETECT_SPARCV9_GCC_32 && !defined SPH_SPARCV9_GCC_321151#define SPH_SPARCV9_GCC_32 SPH_DETECT_SPARCV9_GCC_321152#endif1153#if defined SPH_DETECT_SPARCV9_GCC_64 && !defined SPH_SPARCV9_GCC_641154#define SPH_SPARCV9_GCC_64 SPH_DETECT_SPARCV9_GCC_641155#endif1156#if defined SPH_DETECT_SPARCV9_GCC && !defined SPH_SPARCV9_GCC1157#define SPH_SPARCV9_GCC SPH_DETECT_SPARCV9_GCC1158#endif1159#if defined SPH_DETECT_I386_GCC && !defined SPH_I386_GCC1160#define SPH_I386_GCC SPH_DETECT_I386_GCC1161#endif1162#if defined SPH_DETECT_I386_MSVC && !defined SPH_I386_MSVC1163#define SPH_I386_MSVC SPH_DETECT_I386_MSVC1164#endif1165#if defined SPH_DETECT_AMD64_GCC && !defined SPH_AMD64_GCC1166#define SPH_AMD64_GCC SPH_DETECT_AMD64_GCC1167#endif1168#if defined SPH_DETECT_AMD64_MSVC && !defined SPH_AMD64_MSVC1169#define SPH_AMD64_MSVC SPH_DETECT_AMD64_MSVC1170#endif1171#if defined SPH_DETECT_PPC32_GCC && !defined SPH_PPC32_GCC1172#define SPH_PPC32_GCC SPH_DETECT_PPC32_GCC1173#endif1174#if defined SPH_DETECT_PPC64_GCC && !defined SPH_PPC64_GCC1175#define SPH_PPC64_GCC SPH_DETECT_PPC64_GCC1176#endif11771178#if SPH_LITTLE_ENDIAN && !defined SPH_LITTLE_FAST1179#define SPH_LITTLE_FAST 11180#endif1181#if SPH_BIG_ENDIAN && !defined SPH_BIG_FAST1182#define SPH_BIG_FAST 11183#endif11841185#if defined SPH_UPTR && !(SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN)1186#error SPH_UPTR defined, but endianness is not known.1187#endif11881189#if SPH_I386_GCC && !SPH_NO_ASM11901191/*1192* On x86 32-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit1193* values.1194*/11951196static SPH_INLINE sph_u321197sph_bswap32(sph_u32 x)1198{1199__asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x));1200return x;1201}12021203#if SPH_6412041205static SPH_INLINE sph_u641206sph_bswap64(sph_u64 x)1207{1208return ((sph_u64)sph_bswap32((sph_u32)x) << 32)1209| (sph_u64)sph_bswap32((sph_u32)(x >> 32));1210}12111212#endif12131214#elif SPH_AMD64_GCC && !SPH_NO_ASM12151216/*1217* On x86 64-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit1218* and 64-bit values.1219*/12201221static SPH_INLINE sph_u321222sph_bswap32(sph_u32 x)1223{1224__asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x));1225return x;1226}12271228#if SPH_6412291230static SPH_INLINE sph_u641231sph_bswap64(sph_u64 x)1232{1233__asm__ __volatile__ ("bswapq %0" : "=r" (x) : "0" (x));1234return x;1235}12361237#endif12381239/*1240* Disabled code. Apparently, Microsoft Visual C 2005 is smart enough1241* to generate proper opcodes for endianness swapping with the pure C1242* implementation below.1243*12441245#elif SPH_I386_MSVC && !SPH_NO_ASM12461247static __inline sph_u32 __declspec(naked) __fastcall1248sph_bswap32(sph_u32 x)1249{1250__asm {1251bswap ecx1252mov eax,ecx1253ret1254}1255}12561257#if SPH_6412581259static SPH_INLINE sph_u641260sph_bswap64(sph_u64 x)1261{1262return ((sph_u64)sph_bswap32((sph_u32)x) << 32)1263| (sph_u64)sph_bswap32((sph_u32)(x >> 32));1264}12651266#endif12671268*1269* [end of disabled code]1270*/12711272#else12731274static SPH_INLINE sph_u321275sph_bswap32(sph_u32 x)1276{1277x = SPH_T32((x << 16) | (x >> 16));1278x = ((x & SPH_C32(0xFF00FF00)) >> 8)1279| ((x & SPH_C32(0x00FF00FF)) << 8);1280return x;1281}12821283#if SPH_6412841285/**1286* Byte-swap a 64-bit value.1287*1288* @param x the input value1289* @return the byte-swapped value1290*/1291static SPH_INLINE sph_u641292sph_bswap64(sph_u64 x)1293{1294x = SPH_T64((x << 32) | (x >> 32));1295x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16)1296| ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16);1297x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8)1298| ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8);1299return x;1300}13011302#endif13031304#endif13051306#if SPH_SPARCV9_GCC && !SPH_NO_ASM13071308/*1309* On UltraSPARC systems, native ordering is big-endian, but it is1310* possible to perform little-endian read accesses by specifying the1311* address space 0x88 (ASI_PRIMARY_LITTLE). Basically, either we use1312* the opcode "lda [%reg]0x88,%dst", where %reg is the register which1313* contains the source address and %dst is the destination register,1314* or we use "lda [%reg+imm]%asi,%dst", which uses the %asi register1315* to get the address space name. The latter format is better since it1316* combines an addition and the actual access in a single opcode; but1317* it requires the setting (and subsequent resetting) of %asi, which is1318* slow. Some operations (i.e. MD5 compression function) combine many1319* successive little-endian read accesses, which may share the same1320* %asi setting. The macros below contain the appropriate inline1321* assembly.1322*/13231324#define SPH_SPARCV9_SET_ASI \1325sph_u32 sph_sparcv9_asi; \1326__asm__ __volatile__ ( \1327"rd %%asi,%0\n\twr %%g0,0x88,%%asi" : "=r" (sph_sparcv9_asi));13281329#define SPH_SPARCV9_RESET_ASI \1330__asm__ __volatile__ ("wr %%g0,%0,%%asi" : : "r" (sph_sparcv9_asi));13311332#define SPH_SPARCV9_DEC32LE(base, idx) ({ \1333sph_u32 sph_sparcv9_tmp; \1334__asm__ __volatile__ ("lda [%1+" #idx "*4]%%asi,%0" \1335: "=r" (sph_sparcv9_tmp) : "r" (base)); \1336sph_sparcv9_tmp; \1337})13381339#endif13401341static SPH_INLINE void1342sph_enc16be(void *dst, unsigned val)1343{1344((unsigned char *)dst)[0] = (val >> 8);1345((unsigned char *)dst)[1] = val;1346}13471348static SPH_INLINE unsigned1349sph_dec16be(const void *src)1350{1351return ((unsigned)(((const unsigned char *)src)[0]) << 8)1352| (unsigned)(((const unsigned char *)src)[1]);1353}13541355static SPH_INLINE void1356sph_enc16le(void *dst, unsigned val)1357{1358((unsigned char *)dst)[0] = val;1359((unsigned char *)dst)[1] = val >> 8;1360}13611362static SPH_INLINE unsigned1363sph_dec16le(const void *src)1364{1365return (unsigned)(((const unsigned char *)src)[0])1366| ((unsigned)(((const unsigned char *)src)[1]) << 8);1367}13681369/**1370* Encode a 32-bit value into the provided buffer (big endian convention).1371*1372* @param dst the destination buffer1373* @param val the 32-bit value to encode1374*/1375static SPH_INLINE void1376sph_enc32be(void *dst, sph_u32 val)1377{1378#if defined SPH_UPTR1379#if SPH_UNALIGNED1380#if SPH_LITTLE_ENDIAN1381val = sph_bswap32(val);1382#endif1383*(sph_u32 *)dst = val;1384#else1385if (((SPH_UPTR)dst & 3) == 0) {1386#if SPH_LITTLE_ENDIAN1387val = sph_bswap32(val);1388#endif1389*(sph_u32 *)dst = val;1390} else {1391((unsigned char *)dst)[0] = (val >> 24);1392((unsigned char *)dst)[1] = (val >> 16);1393((unsigned char *)dst)[2] = (val >> 8);1394((unsigned char *)dst)[3] = val;1395}1396#endif1397#else1398((unsigned char *)dst)[0] = (val >> 24);1399((unsigned char *)dst)[1] = (val >> 16);1400((unsigned char *)dst)[2] = (val >> 8);1401((unsigned char *)dst)[3] = val;1402#endif1403}14041405/**1406* Encode a 32-bit value into the provided buffer (big endian convention).1407* The destination buffer must be properly aligned.1408*1409* @param dst the destination buffer (32-bit aligned)1410* @param val the value to encode1411*/1412static SPH_INLINE void1413sph_enc32be_aligned(void *dst, sph_u32 val)1414{1415#if SPH_LITTLE_ENDIAN1416*(sph_u32 *)dst = sph_bswap32(val);1417#elif SPH_BIG_ENDIAN1418*(sph_u32 *)dst = val;1419#else1420((unsigned char *)dst)[0] = (val >> 24);1421((unsigned char *)dst)[1] = (val >> 16);1422((unsigned char *)dst)[2] = (val >> 8);1423((unsigned char *)dst)[3] = val;1424#endif1425}14261427/**1428* Decode a 32-bit value from the provided buffer (big endian convention).1429*1430* @param src the source buffer1431* @return the decoded value1432*/1433static SPH_INLINE sph_u321434sph_dec32be(const void *src)1435{1436#if defined SPH_UPTR1437#if SPH_UNALIGNED1438#if SPH_LITTLE_ENDIAN1439return sph_bswap32(*(const sph_u32 *)src);1440#else1441return *(const sph_u32 *)src;1442#endif1443#else1444if (((SPH_UPTR)src & 3) == 0) {1445#if SPH_LITTLE_ENDIAN1446return sph_bswap32(*(const sph_u32 *)src);1447#else1448return *(const sph_u32 *)src;1449#endif1450} else {1451return ((sph_u32)(((const unsigned char *)src)[0]) << 24)1452| ((sph_u32)(((const unsigned char *)src)[1]) << 16)1453| ((sph_u32)(((const unsigned char *)src)[2]) << 8)1454| (sph_u32)(((const unsigned char *)src)[3]);1455}1456#endif1457#else1458return ((sph_u32)(((const unsigned char *)src)[0]) << 24)1459| ((sph_u32)(((const unsigned char *)src)[1]) << 16)1460| ((sph_u32)(((const unsigned char *)src)[2]) << 8)1461| (sph_u32)(((const unsigned char *)src)[3]);1462#endif1463}14641465/**1466* Decode a 32-bit value from the provided buffer (big endian convention).1467* The source buffer must be properly aligned.1468*1469* @param src the source buffer (32-bit aligned)1470* @return the decoded value1471*/1472static SPH_INLINE sph_u321473sph_dec32be_aligned(const void *src)1474{1475#if SPH_LITTLE_ENDIAN1476return sph_bswap32(*(const sph_u32 *)src);1477#elif SPH_BIG_ENDIAN1478return *(const sph_u32 *)src;1479#else1480return ((sph_u32)(((const unsigned char *)src)[0]) << 24)1481| ((sph_u32)(((const unsigned char *)src)[1]) << 16)1482| ((sph_u32)(((const unsigned char *)src)[2]) << 8)1483| (sph_u32)(((const unsigned char *)src)[3]);1484#endif1485}14861487/**1488* Encode a 32-bit value into the provided buffer (little endian convention).1489*1490* @param dst the destination buffer1491* @param val the 32-bit value to encode1492*/1493static SPH_INLINE void1494sph_enc32le(void *dst, sph_u32 val)1495{1496#if defined SPH_UPTR1497#if SPH_UNALIGNED1498#if SPH_BIG_ENDIAN1499val = sph_bswap32(val);1500#endif1501*(sph_u32 *)dst = val;1502#else1503if (((SPH_UPTR)dst & 3) == 0) {1504#if SPH_BIG_ENDIAN1505val = sph_bswap32(val);1506#endif1507*(sph_u32 *)dst = val;1508} else {1509((unsigned char *)dst)[0] = val;1510((unsigned char *)dst)[1] = (val >> 8);1511((unsigned char *)dst)[2] = (val >> 16);1512((unsigned char *)dst)[3] = (val >> 24);1513}1514#endif1515#else1516((unsigned char *)dst)[0] = val;1517((unsigned char *)dst)[1] = (val >> 8);1518((unsigned char *)dst)[2] = (val >> 16);1519((unsigned char *)dst)[3] = (val >> 24);1520#endif1521}15221523/**1524* Encode a 32-bit value into the provided buffer (little endian convention).1525* The destination buffer must be properly aligned.1526*1527* @param dst the destination buffer (32-bit aligned)1528* @param val the value to encode1529*/1530static SPH_INLINE void1531sph_enc32le_aligned(void *dst, sph_u32 val)1532{1533#if SPH_LITTLE_ENDIAN1534*(sph_u32 *)dst = val;1535#elif SPH_BIG_ENDIAN1536*(sph_u32 *)dst = sph_bswap32(val);1537#else1538((unsigned char *)dst)[0] = val;1539((unsigned char *)dst)[1] = (val >> 8);1540((unsigned char *)dst)[2] = (val >> 16);1541((unsigned char *)dst)[3] = (val >> 24);1542#endif1543}15441545/**1546* Decode a 32-bit value from the provided buffer (little endian convention).1547*1548* @param src the source buffer1549* @return the decoded value1550*/1551static SPH_INLINE sph_u321552sph_dec32le(const void *src)1553{1554#if defined SPH_UPTR1555#if SPH_UNALIGNED1556#if SPH_BIG_ENDIAN1557return sph_bswap32(*(const sph_u32 *)src);1558#else1559return *(const sph_u32 *)src;1560#endif1561#else1562if (((SPH_UPTR)src & 3) == 0) {1563#if SPH_BIG_ENDIAN1564#if SPH_SPARCV9_GCC && !SPH_NO_ASM1565sph_u32 tmp;15661567/*1568* "__volatile__" is needed here because without it,1569* gcc-3.4.3 miscompiles the code and performs the1570* access before the test on the address, thus triggering1571* a bus error...1572*/1573__asm__ __volatile__ (1574"lda [%1]0x88,%0" : "=r" (tmp) : "r" (src));1575return tmp;1576/*1577* On PowerPC, this turns out not to be worth the effort: the inline1578* assembly makes GCC optimizer uncomfortable, which tends to nullify1579* the decoding gains.1580*1581* For most hash functions, using this inline assembly trick changes1582* hashing speed by less than 5% and often _reduces_ it. The biggest1583* gains are for MD4 (+11%) and CubeHash (+30%). For all others, it is1584* less then 10%. The speed gain on CubeHash is probably due to the1585* chronic shortage of registers that CubeHash endures; for the other1586* functions, the generic code appears to be efficient enough already.1587*1588#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM1589sph_u32 tmp;15901591__asm__ __volatile__ (1592"lwbrx %0,0,%1" : "=r" (tmp) : "r" (src));1593return tmp;1594*/1595#else1596return sph_bswap32(*(const sph_u32 *)src);1597#endif1598#else1599return *(const sph_u32 *)src;1600#endif1601} else {1602return (sph_u32)(((const unsigned char *)src)[0])1603| ((sph_u32)(((const unsigned char *)src)[1]) << 8)1604| ((sph_u32)(((const unsigned char *)src)[2]) << 16)1605| ((sph_u32)(((const unsigned char *)src)[3]) << 24);1606}1607#endif1608#else1609return (sph_u32)(((const unsigned char *)src)[0])1610| ((sph_u32)(((const unsigned char *)src)[1]) << 8)1611| ((sph_u32)(((const unsigned char *)src)[2]) << 16)1612| ((sph_u32)(((const unsigned char *)src)[3]) << 24);1613#endif1614}16151616/**1617* Decode a 32-bit value from the provided buffer (little endian convention).1618* The source buffer must be properly aligned.1619*1620* @param src the source buffer (32-bit aligned)1621* @return the decoded value1622*/1623static SPH_INLINE sph_u321624sph_dec32le_aligned(const void *src)1625{1626#if SPH_LITTLE_ENDIAN1627return *(const sph_u32 *)src;1628#elif SPH_BIG_ENDIAN1629#if SPH_SPARCV9_GCC && !SPH_NO_ASM1630sph_u32 tmp;16311632__asm__ __volatile__ ("lda [%1]0x88,%0" : "=r" (tmp) : "r" (src));1633return tmp;1634/*1635* Not worth it generally.1636*1637#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM1638sph_u32 tmp;16391640__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (tmp) : "r" (src));1641return tmp;1642*/1643#else1644return sph_bswap32(*(const sph_u32 *)src);1645#endif1646#else1647return (sph_u32)(((const unsigned char *)src)[0])1648| ((sph_u32)(((const unsigned char *)src)[1]) << 8)1649| ((sph_u32)(((const unsigned char *)src)[2]) << 16)1650| ((sph_u32)(((const unsigned char *)src)[3]) << 24);1651#endif1652}16531654#if SPH_6416551656/**1657* Encode a 64-bit value into the provided buffer (big endian convention).1658*1659* @param dst the destination buffer1660* @param val the 64-bit value to encode1661*/1662static SPH_INLINE void1663sph_enc64be(void *dst, sph_u64 val)1664{1665#if defined SPH_UPTR1666#if SPH_UNALIGNED1667#if SPH_LITTLE_ENDIAN1668val = sph_bswap64(val);1669#endif1670*(sph_u64 *)dst = val;1671#else1672if (((SPH_UPTR)dst & 7) == 0) {1673#if SPH_LITTLE_ENDIAN1674val = sph_bswap64(val);1675#endif1676*(sph_u64 *)dst = val;1677} else {1678((unsigned char *)dst)[0] = (val >> 56);1679((unsigned char *)dst)[1] = (val >> 48);1680((unsigned char *)dst)[2] = (val >> 40);1681((unsigned char *)dst)[3] = (val >> 32);1682((unsigned char *)dst)[4] = (val >> 24);1683((unsigned char *)dst)[5] = (val >> 16);1684((unsigned char *)dst)[6] = (val >> 8);1685((unsigned char *)dst)[7] = val;1686}1687#endif1688#else1689((unsigned char *)dst)[0] = (val >> 56);1690((unsigned char *)dst)[1] = (val >> 48);1691((unsigned char *)dst)[2] = (val >> 40);1692((unsigned char *)dst)[3] = (val >> 32);1693((unsigned char *)dst)[4] = (val >> 24);1694((unsigned char *)dst)[5] = (val >> 16);1695((unsigned char *)dst)[6] = (val >> 8);1696((unsigned char *)dst)[7] = val;1697#endif1698}16991700/**1701* Encode a 64-bit value into the provided buffer (big endian convention).1702* The destination buffer must be properly aligned.1703*1704* @param dst the destination buffer (64-bit aligned)1705* @param val the value to encode1706*/1707static SPH_INLINE void1708sph_enc64be_aligned(void *dst, sph_u64 val)1709{1710#if SPH_LITTLE_ENDIAN1711*(sph_u64 *)dst = sph_bswap64(val);1712#elif SPH_BIG_ENDIAN1713*(sph_u64 *)dst = val;1714#else1715((unsigned char *)dst)[0] = (val >> 56);1716((unsigned char *)dst)[1] = (val >> 48);1717((unsigned char *)dst)[2] = (val >> 40);1718((unsigned char *)dst)[3] = (val >> 32);1719((unsigned char *)dst)[4] = (val >> 24);1720((unsigned char *)dst)[5] = (val >> 16);1721((unsigned char *)dst)[6] = (val >> 8);1722((unsigned char *)dst)[7] = val;1723#endif1724}17251726/**1727* Decode a 64-bit value from the provided buffer (big endian convention).1728*1729* @param src the source buffer1730* @return the decoded value1731*/1732static SPH_INLINE sph_u641733sph_dec64be(const void *src)1734{1735#if defined SPH_UPTR1736#if SPH_UNALIGNED1737#if SPH_LITTLE_ENDIAN1738return sph_bswap64(*(const sph_u64 *)src);1739#else1740return *(const sph_u64 *)src;1741#endif1742#else1743if (((SPH_UPTR)src & 7) == 0) {1744#if SPH_LITTLE_ENDIAN1745return sph_bswap64(*(const sph_u64 *)src);1746#else1747return *(const sph_u64 *)src;1748#endif1749} else {1750return ((sph_u64)(((const unsigned char *)src)[0]) << 56)1751| ((sph_u64)(((const unsigned char *)src)[1]) << 48)1752| ((sph_u64)(((const unsigned char *)src)[2]) << 40)1753| ((sph_u64)(((const unsigned char *)src)[3]) << 32)1754| ((sph_u64)(((const unsigned char *)src)[4]) << 24)1755| ((sph_u64)(((const unsigned char *)src)[5]) << 16)1756| ((sph_u64)(((const unsigned char *)src)[6]) << 8)1757| (sph_u64)(((const unsigned char *)src)[7]);1758}1759#endif1760#else1761return ((sph_u64)(((const unsigned char *)src)[0]) << 56)1762| ((sph_u64)(((const unsigned char *)src)[1]) << 48)1763| ((sph_u64)(((const unsigned char *)src)[2]) << 40)1764| ((sph_u64)(((const unsigned char *)src)[3]) << 32)1765| ((sph_u64)(((const unsigned char *)src)[4]) << 24)1766| ((sph_u64)(((const unsigned char *)src)[5]) << 16)1767| ((sph_u64)(((const unsigned char *)src)[6]) << 8)1768| (sph_u64)(((const unsigned char *)src)[7]);1769#endif1770}17711772/**1773* Decode a 64-bit value from the provided buffer (big endian convention).1774* The source buffer must be properly aligned.1775*1776* @param src the source buffer (64-bit aligned)1777* @return the decoded value1778*/1779static SPH_INLINE sph_u641780sph_dec64be_aligned(const void *src)1781{1782#if SPH_LITTLE_ENDIAN1783return sph_bswap64(*(const sph_u64 *)src);1784#elif SPH_BIG_ENDIAN1785return *(const sph_u64 *)src;1786#else1787return ((sph_u64)(((const unsigned char *)src)[0]) << 56)1788| ((sph_u64)(((const unsigned char *)src)[1]) << 48)1789| ((sph_u64)(((const unsigned char *)src)[2]) << 40)1790| ((sph_u64)(((const unsigned char *)src)[3]) << 32)1791| ((sph_u64)(((const unsigned char *)src)[4]) << 24)1792| ((sph_u64)(((const unsigned char *)src)[5]) << 16)1793| ((sph_u64)(((const unsigned char *)src)[6]) << 8)1794| (sph_u64)(((const unsigned char *)src)[7]);1795#endif1796}17971798/**1799* Encode a 64-bit value into the provided buffer (little endian convention).1800*1801* @param dst the destination buffer1802* @param val the 64-bit value to encode1803*/1804static SPH_INLINE void1805sph_enc64le(void *dst, sph_u64 val)1806{1807#if defined SPH_UPTR1808#if SPH_UNALIGNED1809#if SPH_BIG_ENDIAN1810val = sph_bswap64(val);1811#endif1812*(sph_u64 *)dst = val;1813#else1814if (((SPH_UPTR)dst & 7) == 0) {1815#if SPH_BIG_ENDIAN1816val = sph_bswap64(val);1817#endif1818*(sph_u64 *)dst = val;1819} else {1820((unsigned char *)dst)[0] = val;1821((unsigned char *)dst)[1] = (val >> 8);1822((unsigned char *)dst)[2] = (val >> 16);1823((unsigned char *)dst)[3] = (val >> 24);1824((unsigned char *)dst)[4] = (val >> 32);1825((unsigned char *)dst)[5] = (val >> 40);1826((unsigned char *)dst)[6] = (val >> 48);1827((unsigned char *)dst)[7] = (val >> 56);1828}1829#endif1830#else1831((unsigned char *)dst)[0] = val;1832((unsigned char *)dst)[1] = (val >> 8);1833((unsigned char *)dst)[2] = (val >> 16);1834((unsigned char *)dst)[3] = (val >> 24);1835((unsigned char *)dst)[4] = (val >> 32);1836((unsigned char *)dst)[5] = (val >> 40);1837((unsigned char *)dst)[6] = (val >> 48);1838((unsigned char *)dst)[7] = (val >> 56);1839#endif1840}18411842/**1843* Encode a 64-bit value into the provided buffer (little endian convention).1844* The destination buffer must be properly aligned.1845*1846* @param dst the destination buffer (64-bit aligned)1847* @param val the value to encode1848*/1849static SPH_INLINE void1850sph_enc64le_aligned(void *dst, sph_u64 val)1851{1852#if SPH_LITTLE_ENDIAN1853*(sph_u64 *)dst = val;1854#elif SPH_BIG_ENDIAN1855*(sph_u64 *)dst = sph_bswap64(val);1856#else1857((unsigned char *)dst)[0] = val;1858((unsigned char *)dst)[1] = (val >> 8);1859((unsigned char *)dst)[2] = (val >> 16);1860((unsigned char *)dst)[3] = (val >> 24);1861((unsigned char *)dst)[4] = (val >> 32);1862((unsigned char *)dst)[5] = (val >> 40);1863((unsigned char *)dst)[6] = (val >> 48);1864((unsigned char *)dst)[7] = (val >> 56);1865#endif1866}18671868/**1869* Decode a 64-bit value from the provided buffer (little endian convention).1870*1871* @param src the source buffer1872* @return the decoded value1873*/1874static SPH_INLINE sph_u641875sph_dec64le(const void *src)1876{1877#if defined SPH_UPTR1878#if SPH_UNALIGNED1879#if SPH_BIG_ENDIAN1880return sph_bswap64(*(const sph_u64 *)src);1881#else1882return *(const sph_u64 *)src;1883#endif1884#else1885if (((SPH_UPTR)src & 7) == 0) {1886#if SPH_BIG_ENDIAN1887#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM1888sph_u64 tmp;18891890__asm__ __volatile__ (1891"ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src));1892return tmp;1893/*1894* Not worth it generally.1895*1896#elif SPH_PPC32_GCC && !SPH_NO_ASM1897return (sph_u64)sph_dec32le_aligned(src)1898| ((sph_u64)sph_dec32le_aligned(1899(const char *)src + 4) << 32);1900#elif SPH_PPC64_GCC && !SPH_NO_ASM1901sph_u64 tmp;19021903__asm__ __volatile__ (1904"ldbrx %0,0,%1" : "=r" (tmp) : "r" (src));1905return tmp;1906*/1907#else1908return sph_bswap64(*(const sph_u64 *)src);1909#endif1910#else1911return *(const sph_u64 *)src;1912#endif1913} else {1914return (sph_u64)(((const unsigned char *)src)[0])1915| ((sph_u64)(((const unsigned char *)src)[1]) << 8)1916| ((sph_u64)(((const unsigned char *)src)[2]) << 16)1917| ((sph_u64)(((const unsigned char *)src)[3]) << 24)1918| ((sph_u64)(((const unsigned char *)src)[4]) << 32)1919| ((sph_u64)(((const unsigned char *)src)[5]) << 40)1920| ((sph_u64)(((const unsigned char *)src)[6]) << 48)1921| ((sph_u64)(((const unsigned char *)src)[7]) << 56);1922}1923#endif1924#else1925return (sph_u64)(((const unsigned char *)src)[0])1926| ((sph_u64)(((const unsigned char *)src)[1]) << 8)1927| ((sph_u64)(((const unsigned char *)src)[2]) << 16)1928| ((sph_u64)(((const unsigned char *)src)[3]) << 24)1929| ((sph_u64)(((const unsigned char *)src)[4]) << 32)1930| ((sph_u64)(((const unsigned char *)src)[5]) << 40)1931| ((sph_u64)(((const unsigned char *)src)[6]) << 48)1932| ((sph_u64)(((const unsigned char *)src)[7]) << 56);1933#endif1934}19351936/**1937* Decode a 64-bit value from the provided buffer (little endian convention).1938* The source buffer must be properly aligned.1939*1940* @param src the source buffer (64-bit aligned)1941* @return the decoded value1942*/1943static SPH_INLINE sph_u641944sph_dec64le_aligned(const void *src)1945{1946#if SPH_LITTLE_ENDIAN1947return *(const sph_u64 *)src;1948#elif SPH_BIG_ENDIAN1949#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM1950sph_u64 tmp;19511952__asm__ __volatile__ ("ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src));1953return tmp;1954/*1955* Not worth it generally.1956*1957#elif SPH_PPC32_GCC && !SPH_NO_ASM1958return (sph_u64)sph_dec32le_aligned(src)1959| ((sph_u64)sph_dec32le_aligned((const char *)src + 4) << 32);1960#elif SPH_PPC64_GCC && !SPH_NO_ASM1961sph_u64 tmp;19621963__asm__ __volatile__ ("ldbrx %0,0,%1" : "=r" (tmp) : "r" (src));1964return tmp;1965*/1966#else1967return sph_bswap64(*(const sph_u64 *)src);1968#endif1969#else1970return (sph_u64)(((const unsigned char *)src)[0])1971| ((sph_u64)(((const unsigned char *)src)[1]) << 8)1972| ((sph_u64)(((const unsigned char *)src)[2]) << 16)1973| ((sph_u64)(((const unsigned char *)src)[3]) << 24)1974| ((sph_u64)(((const unsigned char *)src)[4]) << 32)1975| ((sph_u64)(((const unsigned char *)src)[5]) << 40)1976| ((sph_u64)(((const unsigned char *)src)[6]) << 48)1977| ((sph_u64)(((const unsigned char *)src)[7]) << 56);1978#endif1979}19801981#endif19821983#endif /* Doxygen excluded block */19841985#endif198619871988