Allow using bswap builtins even if no <byteswap.h> header

Closes issue #461
This commit is contained in:
Fish (David B. Trout)
2022-02-04 15:37:36 -08:00
parent ff7c8892e4
commit 8b20ae3acb
3 changed files with 71 additions and 59 deletions

View File

@@ -1,4 +1,5 @@
/* HBYTESWP.C (C) Copyright Roger Bowler, 2012 */
/* (C) and others 2013-2022 */
/* Hercules Little <> Big Endian conversion */
/* */
/* Released under "The Q Public License Version 1" */
@@ -7,9 +8,9 @@
/*-------------------------------------------------------------------*/
/* These definitions are only nessesary when running on older */
/* versions of linux that do not have /usr/include/byteswap.h */
/* compile option -DNO_ASM_BYTESWAP will expand 'C' code */
/* otherwise Intel (486+) assember will be generated (Jan Jaeger) */
/* versions of linux that do not have /usr/include/byteswap.h. */
/* Compile option -DNO_ASM_BYTESWAP will expand 'C' code. */
/* Otherwise custom assember will be generated. (Jan Jaeger) */
/*-------------------------------------------------------------------*/
#include "hstdinc.h"

View File

@@ -1,4 +1,5 @@
/* HBYTESWP.H (C) Copyright Roger Bowler, 2012 */
/* (C) and others 2013-2022 */
/* Hercules Little <> Big Endian conversion */
/* */
/* Released under "The Q Public License Version 1" */
@@ -7,17 +8,27 @@
/*-------------------------------------------------------------------*/
/* These definitions are only nessesary when running on older */
/* versions of linux that do not have /usr/include/byteswap.h */
/* compile option -DNO_ASM_BYTESWAP will expand 'C' code */
/* otherwise Intel (486+) assember will be generated (Jan Jaeger) */
/* versions of linux that do not have /usr/include/byteswap.h. */
/* Compile option -DNO_ASM_BYTESWAP will expand 'C' code. */
/* Otherwise custom assember will be generated. (Jan Jaeger) */
/*-------------------------------------------------------------------*/
#ifndef _BYTESWAP_H
#define _BYTESWAP_H
#if !defined( NO_ASM_BYTESWAP )
/*--------------------------------------------------------------------
The following sequence of tests allows platforms to use a compiler's
builtin intrinsic byte swapping function even if it fails to provide
its own <byteswap.h> header.
-------------------------------------------------------------------*/
#include "htypes.h" // (need Hercules fixed-size data types)
#if defined( HAVE_BYTESWAP_H )
/* Do nothing; i.e. use the functions defined in <byteswap.h> */
#elif defined( HAVE_SWAP_BUILTINS )
#include "htypes.h" // (Hercules fixed-size data types)
#if defined( _MSVC_ )
@@ -27,62 +38,60 @@
#else // !defined( _MSVC_ )
#if defined( HAVE_SWAP_BUILTINS )
#define bswap_16(x) __builtin_bswap16((x))
#define bswap_32(x) __builtin_bswap32((x))
#define bswap_64(x) __builtin_bswap64((x))
#define bswap_16(x) __builtin_bswap16((x))
#define bswap_32(x) __builtin_bswap32((x))
#define bswap_64(x) __builtin_bswap64((x))
#endif
#else // !defined( HAVE_SWAP_BUILTINS )
#elif !defined( NO_ASM_BYTESWAP )
inline uint16_t (ATTR_REGPARM(1) bswap_16 )( uint16_t x )
#include "htypes.h" // (need Hercules fixed-size data types)
inline uint16_t (ATTR_REGPARM(1) bswap_16 )( uint16_t x )
{
#if defined(__x86_64__)
__asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x));
#else
__asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x));
#endif
return x;
}
inline uint32_t (ATTR_REGPARM(1) bswap_32 )( uint32_t x )
{
#if defined(__x86_64__)
__asm__("bswapl %0" : "=r" (x) : "0" (x));
#else
__asm__("bswap %0" : "=r" (x) : "0" (x));
#endif
return x;
}
inline uint64_t (ATTR_REGPARM(1) bswap_64 )( uint64_t x )
{
#if defined(__x86_64__)
__asm__("bswapq %0" : "=r" (x) : "0" (x));
return x;
#else // swap the two words after byteswapping them
union
{
#if defined(__x86_64__)
__asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x));
#else
__asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x));
#endif
return x;
}
inline uint32_t (ATTR_REGPARM(1) bswap_32 )( uint32_t x )
{
#if defined(__x86_64__)
__asm__("bswapl %0" : "=r" (x) : "0" (x));
#else
__asm__("bswap %0" : "=r" (x) : "0" (x));
#endif
return x;
}
inline uint64_t (ATTR_REGPARM(1) bswap_64 )( uint64_t x )
{
#if defined(__x86_64__)
__asm__("bswapq %0" : "=r" (x) : "0" (x));
return x;
#else // swap the two words after byteswapping them
union
struct
{
struct
{
uint32_t high, low;
} words;
uint64_t quad;
} value;
value.quad = x;
__asm__("bswap %0" : "=r" (value.words.high) : "0" (value.words.high));
__asm__("bswap %0" : "=r" (value.words.low) : "0" (value.words.low));
__asm__("xchgl %0,%1" : "=r" (value.words.high), "=r" (value.words.low) :
"0" (value.words.high), "1" (value.words.low));
return value.quad;
#endif
}
uint32_t high, low;
} words;
uint64_t quad;
} value;
value.quad = x;
__asm__("bswap %0" : "=r" (value.words.high) : "0" (value.words.high));
__asm__("bswap %0" : "=r" (value.words.low) : "0" (value.words.low));
__asm__("xchgl %0,%1" : "=r" (value.words.high), "=r" (value.words.low) :
"0" (value.words.high), "1" (value.words.low));
return value.quad;
#endif
}
#endif // defined( HAVE_SWAP_BUILTINS )
#endif // defined( _MSVC_ )
#else // defined( NO_ASM_BYTESWAP )
#else
#define bswap_16(_x) \
( (((_x) & 0xFF00) >> 8) \
@@ -104,5 +113,6 @@
| ((U64)((_x) & 0x000000000000FF00ULL) << 40) \
| ((U64)((_x) & 0x00000000000000FFULL) << 56) )
#endif // !defined( NO_ASM_BYTESWAP )
#endif
#endif // _BYTESWAP_H

View File

@@ -84,6 +84,7 @@ struct dirent
#define inline __inline
#define __inline__ __inline
#define HAVE_SWAP_BUILTINS
#define HAVE_STRUCT_IN_ADDR_S_ADDR
#define HAVE_SYS_MTIO_H // (ours is called 'w32mtio.h')
#define HAVE_ASSERT_H