root/kern/lib/bswap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bswap16
  2. bswap32
  3. bswap64
  4. TO
  5. split64to32

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <types.h>
  31 #include <endian.h>
  32 
  33 /*
  34  * Unconditional byte-swap functions.
  35  *
  36  * bswap16, 32, and 64 unconditionally swap byte order of integers of
  37  * the respective bitsize.
  38  *
  39  * The advantage of writing them out like this is that the bit
  40  * patterns are easily validated by inspection. Also, this form is
  41  * more likely to be picked up by the compiler and converted into
  42  * byte-swap machine instructions (if those exist) than something
  43  * loop-based.
  44  */
  45 
  46 uint16_t
  47 bswap16(uint16_t val)
  48 {
  49         return    ((val & 0x00ff) << 8)
  50                 | ((val & 0xff00) >> 8);
  51 }
  52 
  53 uint32_t
  54 bswap32(uint32_t val)
  55 {
  56         return    ((val & 0x000000ff) << 24)
  57                 | ((val & 0x0000ff00) << 8)
  58                 | ((val & 0x00ff0000) >> 8)
  59                 | ((val & 0xff000000) >> 24);
  60 }
  61 
  62 uint64_t
  63 bswap64(uint64_t val)
  64 {
  65         return    ((val & 0x00000000000000ff) << 56)
  66                 | ((val & 0x000000000000ff00) << 40)
  67                 | ((val & 0x0000000000ff0000) << 24)
  68                 | ((val & 0x00000000ff000000) << 8)
  69                 | ((val & 0x000000ff00000000) << 8)
  70                 | ((val & 0x0000ff0000000000) << 24)
  71                 | ((val & 0x00ff000000000000) >> 40)
  72                 | ((val & 0xff00000000000000) >> 56);
  73 }
  74 
  75 /*
  76  * Network byte order byte-swap functions.
  77  *
  78  * For ntoh* and hton*:
  79  *    *s are for "short" (16-bit)
  80  *    *l are for "long" (32-bit)
  81  *    *ll are for "long long" (64-bit)
  82  *
  83  * hton* convert from host byte order to network byte order.
  84  * ntoh* convert from network byte order to host byte order.
  85  *
  86  * Network byte order is big-endian.
  87  *
  88  * Note that right now the only platforms OS/161 runs on are
  89  * big-endian, so these functions are actually all empty.
  90  *
  91  * These should maybe be made inline.
  92  */
  93 
  94 #if _BYTE_ORDER == _LITTLE_ENDIAN
  95 #define TO(tag, bits, type) \
  96     type ntoh##tag(type val) { return bswap##bits(val); } \
  97     type hton##tag(type val) { return bswap##bits(val); }
  98 #endif
  99 
 100 /*
 101  * Use a separate #if, so if the header file defining the symbols gets
 102  * omitted or messed up the build will fail instead of silently choosing
 103  * the wrong option.
 104  */
 105 #if _BYTE_ORDER == _BIG_ENDIAN
 106 #define TO(tag, bits, type) \
 107     type ntoh##tag(type val) { return val; } \
 108     type hton##tag(type val) { return val; }
 109 #endif
 110 
 111 #if _BYTE_ORDER == _PDP_ENDIAN
 112 #error "You lose."
 113 #endif
 114 
 115 #ifndef TO
 116 #error "_BYTE_ORDER not set"
 117 #endif
 118 
 119 TO(s,  16, uint16_t)
 120 TO(l,  32, uint32_t)
 121 TO(ll, 64, uint64_t)
 122 
 123 
 124 /*
 125  * Some utility functions for handling 64-bit values.
 126  *
 127  * join32to64 pastes two adjoining 32-bit values together in the right
 128  * way to treat them as a 64-bit value, depending on endianness.
 129  * split64to32 is the inverse operation.
 130  *
 131  * The 32-bit arguments should be passed in the order they appear in
 132  * memory, not as high word and low word; the whole point of these
 133  * functions is to know which is the high word and which is the low
 134  * word.
 135  */
 136 
 137 void
 138 join32to64(uint32_t x1, uint32_t x2, uint64_t *y2)
 139 {
 140 #if _BYTE_ORDER == _BIG_ENDIAN
 141         *y2 = ((uint64_t)x1 << 32) | (uint64_t)x2;
 142 #elif _BYTE_ORDER == _LITTLE_ENDIAN
 143         *y2 = (uint64_t)x1 | ((uint64_t)x2 << 32);
 144 #else
 145 #error "Eh?"
 146 #endif
 147 }
 148 
 149 void
 150 split64to32(uint64_t x, uint32_t *y1, uint32_t *y2)
 151 {
 152 #if _BYTE_ORDER == _BIG_ENDIAN
 153         *y1 = x >> 32;
 154         *y2 = x & 0xffffffff;
 155 #elif _BYTE_ORDER == _LITTLE_ENDIAN
 156         *y1 = x & 0xffffffff;
 157         *y2 = x >> 32;
 158 #else
 159 #error "Eh?"
 160 #endif
 161 }

/* [<][>][^][v][top][bottom][index][help] */