upstream: https://github.com/mirage/mirage-crypto
at main 179 lines 5.5 kB view raw
1/* 2 * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#ifndef BITFN_H 26#define BITFN_H 27#include <stdint.h> 28 29# if (defined(__i386__)) 30# define ARCH_HAS_SWAP32 31static inline uint32_t bitfn_swap32(uint32_t a) 32{ 33 __asm__ ("bswap %0" : "=r" (a) : "0" (a)); 34 return a; 35} 36/**********************************************************/ 37# elif (defined(__arm__)) 38# define ARCH_HAS_SWAP32 39static inline uint32_t bitfn_swap32(uint32_t a) 40{ 41 uint32_t tmp = a; 42 __asm__ volatile ("eor %1, %0, %0, ror #16\n" 43 "bic %1, %1, #0xff0000\n" 44 "mov %0, %0, ror #8\n" 45 "eor %0, %0, %1, lsr #8\n" 46 : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp)); 47 return a; 48} 49/**********************************************************/ 50# elif defined(__x86_64__) 51# define ARCH_HAS_SWAP32 52# define ARCH_HAS_SWAP64 53static inline uint32_t bitfn_swap32(uint32_t a) 54{ 55 __asm__ ("bswap %0" : "=r" (a) : "0" (a)); 56 return a; 57} 58 59static inline uint64_t bitfn_swap64(uint64_t a) 60{ 61 __asm__ ("bswap %0" : "=r" (a) : "0" (a)); 62 return a; 63} 64 65# endif 66 67#ifndef ARCH_HAS_SWAP32 68static inline uint32_t bitfn_swap32(uint32_t a) 69{ 70 return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24); 71} 72#endif 73 74#ifndef ARCH_HAS_SWAP64 75static inline uint64_t bitfn_swap64(uint64_t a) 76{ 77 return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) | 78 (((uint64_t) bitfn_swap32((uint32_t) a)) << 32); 79} 80#endif 81 82static inline uint32_t rol32(uint32_t word, uint32_t shift) 83{ 84 return (word << shift) | (word >> (32 - shift)); 85} 86 87static inline uint32_t ror32(uint32_t word, uint32_t shift) 88{ 89 return (word >> shift) | (word << (32 - shift)); 90} 91 92static inline uint64_t rol64(uint64_t word, uint32_t shift) 93{ 94 return (word << shift) | (word >> (64 - shift)); 95} 96 97static inline uint64_t ror64(uint64_t word, uint32_t shift) 98{ 99 return (word >> shift) | (word << (64 - shift)); 100} 101 102static inline void array_swap32(uint32_t *d, const uint32_t *s, uint32_t nb) 103{ 104 while (nb--) 105 *d++ = bitfn_swap32(*s++); 106} 107 108static inline void array_swap64(uint64_t *d, const uint64_t *s, uint32_t nb) 109{ 110 while (nb--) 111 *d++ = bitfn_swap64(*s++); 112} 113 114static inline void array_copy32(uint32_t *d, const uint32_t *s, uint32_t nb) 115{ 116 while (nb--) *d++ = *s++; 117} 118 119static inline void array_copy64(uint64_t *d, const uint64_t *s, uint32_t nb) 120{ 121 while (nb--) *d++ = *s++; 122} 123 124#if defined(_MSC_VER) || defined(__BYTE_ORDER__) 125#if defined(_MSC_VER) || (__ORDER_LITTLE_ENDIAN__ == __BYTE_ORDER__) 126 127# define be32_to_cpu(a) bitfn_swap32(a) 128# define cpu_to_be32(a) bitfn_swap32(a) 129# define le32_to_cpu(a) (a) 130# define cpu_to_le32(a) (a) 131# define be64_to_cpu(a) bitfn_swap64(a) 132# define cpu_to_be64(a) bitfn_swap64(a) 133# define le64_to_cpu(a) (a) 134# define cpu_to_le64(a) (a) 135 136# define cpu_to_le32_array(d, s, l) array_copy32(d, s, l) 137# define le32_to_cpu_array(d, s, l) array_copy32(d, s, l) 138# define cpu_to_be32_array(d, s, l) array_swap32(d, s, l) 139# define be32_to_cpu_array(d, s, l) array_swap32(d, s, l) 140 141# define cpu_to_le64_array(d, s, l) array_copy64(d, s, l) 142# define le64_to_cpu_array(d, s, l) array_copy64(d, s, l) 143# define cpu_to_be64_array(d, s, l) array_swap64(d, s, l) 144# define be64_to_cpu_array(d, s, l) array_swap64(d, s, l) 145 146# define ARCH_IS_LITTLE_ENDIAN 147 148#elif __ORDER_BIG_ENDIAN__ == __BYTE_ORDER__ 149 150# define be32_to_cpu(a) (a) 151# define cpu_to_be32(a) (a) 152# define le32_to_cpu(a) bitfn_swap32(a) 153# define cpu_to_le32(a) bitfn_swap32(a) 154# define be64_to_cpu(a) (a) 155# define cpu_to_be64(a) (a) 156# define le64_to_cpu(a) bitfn_swap64(a) 157# define cpu_to_le64(a) bitfn_swap64(a) 158 159# define cpu_to_le32_array(d, s, l) array_swap32(d, s, l) 160# define le32_to_cpu_array(d, s, l) array_swap32(d, s, l) 161# define cpu_to_be32_array(d, s, l) array_copy32(d, s, l) 162# define be32_to_cpu_array(d, s, l) array_copy32(d, s, l) 163 164# define cpu_to_le64_array(d, s, l) array_swap64(d, s, l) 165# define le64_to_cpu_array(d, s, l) array_swap64(d, s, l) 166# define cpu_to_be64_array(d, s, l) array_copy64(d, s, l) 167# define be64_to_cpu_array(d, s, l) array_copy64(d, s, l) 168 169# define ARCH_IS_BIG_ENDIAN 170 171#else 172# error "endian is neither big nor little endian" 173#endif 174 175#else 176# error "__BYTE_ORDER__ is not defined" 177#endif 178 179#endif /* !BITFN_H */