mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-20 10:52:18 +02:00
Allow using bswap builtins even if no <byteswap.h> header
Closes issue #461
This commit is contained in:
@@ -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"
|
||||
|
||||
122
hbyteswp.h
122
hbyteswp.h
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user