/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <types.h>30#include <endian.h>3132/*33* Unconditional byte-swap functions.34*35* bswap16, 32, and 64 unconditionally swap byte order of integers of36* the respective bitsize.37*38* The advantage of writing them out like this is that the bit39* patterns are easily validated by inspection. Also, this form is40* more likely to be picked up by the compiler and converted into41* byte-swap machine instructions (if those exist) than something42* loop-based.43*/4445uint16_t46bswap16(uint16_t val)47{48return ((val & 0x00ff) << 8)49| ((val & 0xff00) >> 8);50}5152uint32_t53bswap32(uint32_t val)54{55return ((val & 0x000000ff) << 24)56| ((val & 0x0000ff00) << 8)57| ((val & 0x00ff0000) >> 8)58| ((val & 0xff000000) >> 24);59}6061uint64_t62bswap64(uint64_t val)63{64return ((val & 0x00000000000000ff) << 56)65| ((val & 0x000000000000ff00) << 40)66| ((val & 0x0000000000ff0000) << 24)67| ((val & 0x00000000ff000000) << 8)68| ((val & 0x000000ff00000000) << 8)69| ((val & 0x0000ff0000000000) << 24)70| ((val & 0x00ff000000000000) >> 40)71| ((val & 0xff00000000000000) >> 56);72}7374/*75* Network byte order byte-swap functions.76*77* For ntoh* and hton*:78* *s are for "short" (16-bit)79* *l are for "long" (32-bit)80* *ll are for "long long" (64-bit)81*82* hton* convert from host byte order to network byte order.83* ntoh* convert from network byte order to host byte order.84*85* Network byte order is big-endian.86*87* Note that right now the only platforms OS/161 runs on are88* big-endian, so these functions are actually all empty.89*90* These should maybe be made inline.91*/9293#if _BYTE_ORDER == _LITTLE_ENDIAN94#define TO(tag, bits, type) \95type ntoh##tag(type val) { return bswap##bits(val); } \96type hton##tag(type val) { return bswap##bits(val); }97#endif9899/*100* Use a separate #if, so if the header file defining the symbols gets101* omitted or messed up the build will fail instead of silently choosing102* the wrong option.103*/104#if _BYTE_ORDER == _BIG_ENDIAN105#define TO(tag, bits, type) \106type ntoh##tag(type val) { return val; } \107type hton##tag(type val) { return val; }108#endif109110#if _BYTE_ORDER == _PDP_ENDIAN111#error "You lose."112#endif113114#ifndef TO115#error "_BYTE_ORDER not set"116#endif117118TO(s, 16, uint16_t)119TO(l, 32, uint32_t)120TO(ll, 64, uint64_t)121122123/*124* Some utility functions for handling 64-bit values.125*126* join32to64 pastes two adjoining 32-bit values together in the right127* way to treat them as a 64-bit value, depending on endianness.128* split64to32 is the inverse operation.129*130* The 32-bit arguments should be passed in the order they appear in131* memory, not as high word and low word; the whole point of these132* functions is to know which is the high word and which is the low133* word.134*/135136void137join32to64(uint32_t x1, uint32_t x2, uint64_t *y2)138{139#if _BYTE_ORDER == _BIG_ENDIAN140*y2 = ((uint64_t)x1 << 32) | (uint64_t)x2;141#elif _BYTE_ORDER == _LITTLE_ENDIAN142*y2 = (uint64_t)x1 | ((uint64_t)x2 << 32);143#else144#error "Eh?"145#endif146}147148void149split64to32(uint64_t x, uint32_t *y1, uint32_t *y2)150{151#if _BYTE_ORDER == _BIG_ENDIAN152*y1 = x >> 32;153*y2 = x & 0xffffffff;154#elif _BYTE_ORDER == _LITTLE_ENDIAN155*y1 = x & 0xffffffff;156*y2 = x >> 32;157#else158#error "Eh?"159#endif160}161162163