BSD compatibility for <machine/endian.h>

Introduce <machine/_endian.h> to let target based customization of
<machine/endian.h> via

 * _LITTLE_ENDIAN,
 * _BIG_ENDIAN,
 * _PDP_ENDIAN, and
 * _BYTE_ORDER.

defines.  Add definitions expected by FreeBSD to
<machine/endian.h> like

 * _QUAD_HIGHWORD,
 * _QUAD_LOWWORD,
 * __bswap16(),
 * __bswap32(),
 * __bswap64(),
 * __htonl(),
 * __htons(),
 * __ntohl(), and
 * __ntohs().

Also, if __BSD_VISIBLE

 * LITTLE_ENDIAN,
 * BIG_ENDIAN,
 * PDP_ENDIAN, and
 * BYTE_ORDER.

Targets that define __machine_host_to_from_network_defined in
<machine/_endian.h> must provide their own implementation of

 * __htonl(),
 * __htons(),
 * __ntohl(), and
 * __ntohs(),

otherwise a default implementation is provided by <machine/endian.h>.
In case of GCC defines to builtins are used.

Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
This commit is contained in:
Sebastian Huber 2016-04-18 15:29:21 +02:00 committed by Corinna Vinschen
parent 7a5b452443
commit 76a2110b47
6 changed files with 163 additions and 50 deletions

View File

@ -0,0 +1,35 @@
#ifndef __MACHINE_ENDIAN_H__
#error "must be included via <machine/endian.h>"
#endif /* !__MACHINE_ENDIAN_H__ */
#include <sys/config.h>
#ifdef __PPC__
/* Get rid of GCC builtin defines on PowerPC */
#ifdef _BIG_ENDIAN
#undef _BIG_ENDIAN
#endif
#ifdef _LITTLE_ENDIAN
#undef _LITTLE_ENDIAN
#endif
#endif /* __PPC__ */
#ifndef _LITTLE_ENDIAN
#define _LITTLE_ENDIAN 1234
#endif
#ifndef _BIG_ENDIAN
#define _BIG_ENDIAN 4321
#endif
#ifndef _PDP_ENDIAN
#define _PDP_ENDIAN 3412
#endif
#ifndef _BYTE_ORDER
#if defined(__IEEE_LITTLE_ENDIAN) || defined(__IEEE_BYTES_LITTLE_ENDIAN)
#define _BYTE_ORDER _LITTLE_ENDIAN
#else
#define _BYTE_ORDER _BIG_ENDIAN
#endif
#endif

View File

@ -1,20 +1,69 @@
#ifndef __MACHINE_ENDIAN_H__ #ifndef __MACHINE_ENDIAN_H__
#define __MACHINE_ENDIAN_H__
#include <sys/config.h> #include <sys/cdefs.h>
#include <sys/_types.h>
#include <machine/_endian.h>
#ifndef BIG_ENDIAN #if _BYTE_ORDER == _LITTLE_ENDIAN
#define BIG_ENDIAN 4321 #define _QUAD_HIGHWORD 1
#endif #define _QUAD_LOWWORD 0
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BYTE_ORDER
#if defined(__IEEE_LITTLE_ENDIAN) || defined(__IEEE_BYTES_LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#else #else
#define BYTE_ORDER BIG_ENDIAN #define _QUAD_HIGHWORD 0
#define _QUAD_LOWWORD 1
#endif #endif
#if __BSD_VISIBLE
#define LITTLE_ENDIAN _LITTLE_ENDIAN
#define BIG_ENDIAN _BIG_ENDIAN
#define PDP_ENDIAN _PDP_ENDIAN
#define BYTE_ORDER _BYTE_ORDER
#endif #endif
#ifdef __GNUC__
#define __bswap16(_x) __builtin_bswap16(_x)
#define __bswap32(_x) __builtin_bswap32(_x)
#define __bswap64(_x) __builtin_bswap64(_x)
#else /* __GNUC__ */
static __inline __uint16_t
__bswap16(__uint16_t _x)
{
return ((__uint16_t)((_x >> 8) | ((_x << 8) & 0xff00)));
}
static __inline __uint32_t
__bswap32(__uint32_t _x)
{
return ((__uint32_t)((_x >> 24) | ((_x >> 8) & 0xff00) |
((_x << 8) & 0xff0000) | ((_x << 24) & 0xff000000)));
}
static __inline __uint64_t
__bswap64(__uint64_t _x)
{
return ((__uint64_t)((_x >> 56) | ((_x >> 40) & 0xff00) |
((_x >> 24) & 0xff0000) | ((_x >> 8) & 0xff000000) |
((_x << 8) & ((__uint64_t)0xff << 32)) |
((_x << 24) & ((__uint64_t)0xff << 40)) |
((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56))));
}
#endif /* !__GNUC__ */
#ifndef __machine_host_to_from_network_defined
#if _BYTE_ORDER == _LITTLE_ENDIAN
#define __htonl(_x) __bswap32(_x)
#define __htons(_x) __bswap16(_x)
#define __ntohl(_x) __bswap32(_x)
#define __ntohs(_x) __bswap16(_x)
#else
#define __htonl(_x) ((__uint32_t)(_x))
#define __htons(_x) ((__uint16_t)(_x))
#define __ntohl(_x) ((__uint32_t)(_x))
#define __ntohs(_x) ((__uint16_t)(_x))
#endif
#endif /* __machine_host_to_from_network_defined */
#endif /* __MACHINE_ENDIAN_H__ */ #endif /* __MACHINE_ENDIAN_H__ */

View File

@ -24,17 +24,16 @@
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef _MACHINE_ENDIAN_H #ifndef __MACHINE_ENDIAN_H__
#define _MACHINE_ENDIAN_H #error "must be included via <machine/endian.h>"
#endif /* !__MACHINE_ENDIAN_H__ */
/* Code relocated from libc/sys/arm/sys/param.h. */ #define _LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321 #define _BIG_ENDIAN 4321
#define LITTLE_ENDIAN 1234 #define _PDP_ENDIAN 3412
#ifdef __ARMEB__ #ifdef __ARMEB__
#define BYTE_ORDER BIG_ENDIAN #define _BYTE_ORDER _BIG_ENDIAN
#else #else
#define BYTE_ORDER LITTLE_ENDIAN #define _BYTE_ORDER _LITTLE_ENDIAN
#endif
#endif #endif

View File

@ -11,9 +11,8 @@ details. */
#ifndef _I386_BYTEORDER_H #ifndef _I386_BYTEORDER_H
#define _I386_BYTEORDER_H #define _I386_BYTEORDER_H
#include <_ansi.h>
#include <stdint.h> #include <stdint.h>
#include <bits/endian.h> #include <machine/endian.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -28,37 +27,16 @@ extern uint16_t ntohs(uint16_t);
extern uint32_t htonl(uint32_t); extern uint32_t htonl(uint32_t);
extern uint16_t htons(uint16_t); extern uint16_t htons(uint16_t);
_ELIDABLE_INLINE uint32_t __ntohl(uint32_t);
_ELIDABLE_INLINE uint16_t __ntohs(uint16_t);
_ELIDABLE_INLINE uint32_t
__ntohl(uint32_t x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
}
#define __constant_ntohl(x) \ #define __constant_ntohl(x) \
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \ ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
(((uint32_t)(x) & 0x0000ff00U) << 8) | \ (((uint32_t)(x) & 0x0000ff00U) << 8) | \
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \ (((uint32_t)(x) & 0x00ff0000U) >> 8) | \
(((uint32_t)(x) & 0xff000000U) >> 24))) (((uint32_t)(x) & 0xff000000U) >> 24)))
_ELIDABLE_INLINE uint16_t
__ntohs(uint16_t x)
{
__asm__("xchgb %b0,%h0" /* swap bytes */
: "=Q" (x)
: "0" (x));
return x;
}
#define __constant_ntohs(x) \ #define __constant_ntohs(x) \
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \ ((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
(((uint16_t)(x) & 0xff00) >> 8))) \ (((uint16_t)(x) & 0xff00) >> 8))) \
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
#define __constant_htonl(x) __constant_ntohl(x) #define __constant_htonl(x) __constant_ntohl(x)
#define __constant_htons(x) __constant_ntohs(x) #define __constant_htons(x) __constant_ntohs(x)

View File

@ -12,14 +12,21 @@ details. */
#define _ENDIAN_H_ #define _ENDIAN_H_
#include <sys/config.h> #include <sys/config.h>
#include <sys/cdefs.h> #include <machine/endian.h>
#include <bits/endian.h>
/*#ifdef __USE_BSD*/ /*#ifdef __USE_BSD*/
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN __LITTLE_ENDIAN # define LITTLE_ENDIAN __LITTLE_ENDIAN
# endif
# ifndef BIG_ENDIAN
# define BIG_ENDIAN __BIG_ENDIAN # define BIG_ENDIAN __BIG_ENDIAN
# endif
# ifndef PDP_ENDIAN
# define PDP_ENDIAN __PDP_ENDIAN # define PDP_ENDIAN __PDP_ENDIAN
# endif
# ifndef BYTE_ORDER
# define BYTE_ORDER __BYTE_ORDER # define BYTE_ORDER __BYTE_ORDER
# endif
/*#endif*/ /*#endif*/
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN

View File

@ -0,0 +1,45 @@
/* machine/_endian.h
Copyright 2005, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#ifndef __MACHINE_ENDIAN_H__
#error "must be included via <machine/endian.h>"
#endif /* !__MACHINE_ENDIAN_H__ */
#include <_ansi.h>
#include <bits/endian.h>
#define _LITTLE_ENDIAN __LITTLE_ENDIAN
#define _BIG_ENDIAN __BIG_ENDIAN
#define _PDP_ENDIAN __PDP_ENDIAN
#define _BYTE_ORDER __BYTE_ORDER
#define __machine_host_to_from_network_defined
_ELIDABLE_INLINE __uint32_t __ntohl(__uint32_t);
_ELIDABLE_INLINE __uint16_t __ntohs(__uint16_t);
_ELIDABLE_INLINE __uint32_t
__ntohl(__uint32_t _x)
{
__asm__("bswap %0" : "=r" (_x) : "0" (_x));
return _x;
}
_ELIDABLE_INLINE __uint16_t
__ntohs(__uint16_t _x)
{
__asm__("xchgb %b0,%h0" /* swap bytes */
: "=Q" (_x)
: "0" (_x));
return _x;
}
#define __htonl(_x) __ntohl(_x)
#define __htons(_x) __ntohs(_x)