diff options
-rw-r--r-- | sim/ppc/ChangeLog | 15 | ||||
-rw-r--r-- | sim/ppc/ppc-endian.c | 66 | ||||
-rw-r--r-- | sim/ppc/ppc-endian.h | 9 |
3 files changed, 79 insertions, 11 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 5e657ed..c4d314e 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,5 +1,20 @@ Thu Oct 12 11:35:53 1995 Michael Meissner <meissner@tiktok.cygnus.com> + * ppc-endian.c (SWAP_n): New macros to speed up byte swapping for + 2, 4, and 8 bytes. + (ENDIAN_N): If both target and host byte orders are known, don't + bother testing CURRENT_{TARGET,HOST}_BYTE_ORDER. + + * ppc-endian.h (target specific H2T_n/T2H_n macros): Remove #if 0 + to allow target specific H2T_n/T2H_n macros to be used. + (htonl, ntohl): If compiled on a 486 by GCC and WITH_BSWAP is + non-zero, redefine the htonl/ntohl macros to use the BSWAP instead + of the 3 instruction sequence that runs on 386s. + + * std-config.h (WITH_{HOST,TARGET}_BYTE_ORDER): Don't override if + specified on the compile line. + (WITH_BSWAP): If not defined, define as 0. + * Makefile.in (INLINE_CFLAGS): Add -DDEFAULT_INLINE=2 to add default inline support. Pass INLINE_CFLAGS when compiling. diff --git a/sim/ppc/ppc-endian.c b/sim/ppc/ppc-endian.c index 734ea21..daa749c 100644 --- a/sim/ppc/ppc-endian.c +++ b/sim/ppc/ppc-endian.c @@ -41,6 +41,61 @@ typedef union { unsigned_8 val_8[1]; } endian_map; +#define SWAP_N(RAW,BYTE_SIZE) \ + endian_map in; \ + endian_map out; \ + int byte_nr; \ + in.val_##BYTE_SIZE[0] = RAW; \ + for (byte_nr = 0; byte_nr < BYTE_SIZE; byte_nr++) { \ + out.val_1[BYTE_SIZE-1-byte_nr] = in.val_1[byte_nr]; \ + } \ + return out.val_##BYTE_SIZE[0]; \ + +#if (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH +#define SWAP_2(RAW) return htons (RAW) +#endif + +#ifndef SWAP_2 +#define SWAP_2(RAW) return (((RAW) >> 8) | ((RAW) << 8)) +#endif + +#if !defined(SWAP_4) && (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH +#define SWAP_4(RAW) return htonl (RAW) +#endif + +#ifndef SWAP_4 +#define SWAP_4(RAW) return (((RAW) << 24) | (((RAW) & 0xff00) << 8) | (((RAW) & 0xff0000) >> 8) | ((RAW) >> 24)) +#endif + +#ifndef SWAP_8 +#define SWAP_8(RAW) SWAP_N(RAW,4) +#endif + +/* no need to swap */ +#if (WITH_HOST_BYTE_ORDER \ + && WITH_TARGET_BYTE_ORDER \ + && WITH_HOST_BYTE_ORDER == WITH_TARGET_BYTE_ORDER ) +#define ENDIAN_N(NAME,BYTE_SIZE) \ +unsigned_##BYTE_SIZE \ +endian_##NAME##_##BYTE_SIZE(unsigned_##BYTE_SIZE raw_in) \ +{ \ + return raw_in; \ +} +#endif + +/* always need to swap */ +#if (WITH_HOST_BYTE_ORDER \ + && WITH_TARGET_BYTE_ORDER \ + && WITH_HOST_BYTE_ORDER != WITH_TARGET_BYTE_ORDER ) +#define ENDIAN_N(NAME,BYTE_SIZE) \ +unsigned_##BYTE_SIZE \ +endian_##NAME##_##BYTE_SIZE(unsigned_##BYTE_SIZE raw_in) \ +{ \ + SWAP_##BYTE_SIZE(raw_in); \ +} +#endif + +#ifndef ENDIAN_N #define ENDIAN_N(NAME,BYTE_SIZE) \ unsigned_##BYTE_SIZE \ endian_##NAME##_##BYTE_SIZE(unsigned_##BYTE_SIZE raw_in) \ @@ -49,17 +104,10 @@ endian_##NAME##_##BYTE_SIZE(unsigned_##BYTE_SIZE raw_in) \ return raw_in; \ } \ else { \ - endian_map in; \ - endian_map out; \ - int byte_nr; \ - in.val_##BYTE_SIZE[0] = raw_in; \ - for (byte_nr = 0; byte_nr < BYTE_SIZE; byte_nr++) { \ - out.val_1[BYTE_SIZE-1-byte_nr] = in.val_1[byte_nr]; \ - } \ - return out.val_##BYTE_SIZE[0]; \ + SWAP_##BYTE_SIZE(raw_in); \ } \ } - +#endif ENDIAN_N(h2t, 2) ENDIAN_N(h2t, 4) diff --git a/sim/ppc/ppc-endian.h b/sim/ppc/ppc-endian.h index 496d36a..748d2ef 100644 --- a/sim/ppc/ppc-endian.h +++ b/sim/ppc/ppc-endian.h @@ -199,7 +199,6 @@ do { \ Returns the value swapped according to the host/target byte order */ /* no need to swap */ -#if 0 #if (WITH_HOST_BYTE_ORDER \ && WITH_TARGET_BYTE_ORDER \ && WITH_HOST_BYTE_ORDER == WITH_TARGET_BYTE_ORDER ) @@ -227,6 +226,13 @@ do { \ #define T2H_1(X) (X) #endif +#if (defined (__i486__) || defined (__i586__)) && defined(__GNUC__) && WITH_BSWAP && WITH_NTOH +#undef htonl +#undef ntohl +#define htonl(IN) __extension__ ({ int _out; __asm__ ("bswap %0" : "=r" (_out) : "0" (IN)); _out; }) +#define ntohl(IN) __extension__ ({ int _out; __asm__ ("bswap %0" : "=r" (_out) : "0" (IN)); _out; }) +#endif + /* have ntoh, little host and unknown target */ #if (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN \ && WITH_TARGET_BYTE_ORDER == 0 \ @@ -240,7 +246,6 @@ do { \ #define T2H_2(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : htons(X)) #define T2H_1(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : (X)) #endif -#endif /* if all else fails use software */ #ifndef H2T_1 |