sim: d10v: gut endian logic

The compiler should produce reasonable code here in general, so punt the
various arch checks and bswap defines.  This code will eventually go away
entirely when we convert it to the common memory code.
This commit is contained in:
Mike Frysinger 2016-01-04 03:58:09 -05:00
parent 43368e1d9a
commit 13adda68c5
2 changed files with 5 additions and 77 deletions

View file

@ -1,3 +1,8 @@
2016-01-04 Mike Frysinger <vapier@gentoo.org>
* endian.c (get_word): Delete all arch/big endian logic.
(get_longword, write_word, write_longword): Likewise.
2016-01-03 Mike Frysinger <vapier@gentoo.org>
* interp.c (sim_open): Update sim_parse_args comment.

View file

@ -10,53 +10,13 @@
ENDIAN_INLINE uint16
get_word (uint8 *x)
{
#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
unsigned short word = *(unsigned short *)x;
__asm__ ("xchgb %b0,%h0" : "=q" (word) : "0" (word));
return word;
#elif defined(WORDS_BIGENDIAN)
/* It is safe to do this on big endian hosts, since the d10v requires that words be
aligned on 16-bit boundaries. */
return *(uint16 *)x;
#else
return ((uint16)x[0]<<8) + x[1];
#endif
}
ENDIAN_INLINE uint32
get_longword (uint8 *x)
{
#if (defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__) && defined(USE_BSWAP)
unsigned int long_word = *(unsigned *)x;
__asm__ ("bswap %0" : "=r" (long_word) : "0" (long_word));
return long_word;
#elif (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
unsigned int long_word = *(unsigned *)x;
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (long_word)
: "0" (long_word));
return long_word;
#elif (defined(_POWER) && defined(_AIX)) || (defined(__PPC__) && defined(__BIG_ENDIAN__))
/* Power & PowerPC computers in big endian mode can handle unaligned loads&stores */
return *(uint32 *)x;
#elif defined(WORDS_BIGENDIAN)
/* long words must be aligned on at least 16-bit boundaries, so this should be safe. */
return (((uint32) *(uint16 *)x)<<16) | ((uint32) *(uint16 *)(x+2));
#else
return ((uint32)x[0]<<24) + ((uint32)x[1]<<16) + ((uint32)x[2]<<8) + ((uint32)x[3]);
#endif
}
ENDIAN_INLINE int64
@ -70,54 +30,17 @@ get_longlong (uint8 *x)
ENDIAN_INLINE void
write_word (uint8 *addr, uint16 data)
{
#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
__asm__ ("xchgb %b0,%h0" : "=q" (data) : "0" (data));
*(uint16 *)addr = data;
#elif defined(WORDS_BIGENDIAN)
/* It is safe to do this on big endian hosts, since the d10v requires that words be
aligned on 16-bit boundaries. */
*(uint16 *)addr = data;
#else
addr[0] = (data >> 8) & 0xff;
addr[1] = data & 0xff;
#endif
}
ENDIAN_INLINE void
write_longword (uint8 *addr, uint32 data)
{
#if (defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__) && defined(USE_BSWAP)
__asm__ ("bswap %0" : "=r" (data) : "0" (data));
*(uint32 *)addr = data;
#elif (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) && defined(__GNUC__)
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (data)
: "0" (data));
*(uint32 *)addr = data;
#elif (defined(_POWER) && defined(_AIX)) || (defined(__PPC__) && defined(__BIG_ENDIAN__))
/* Power & PowerPC computers in big endian mode can handle unaligned loads&stores */
*(uint32 *)addr = data;
#elif defined(WORDS_BIGENDIAN)
*(uint16 *)addr = (uint16)(data >> 16);
*(uint16 *)(addr + 2) = (uint16)data;
#else
addr[0] = (data >> 24) & 0xff;
addr[1] = (data >> 16) & 0xff;
addr[2] = (data >> 8) & 0xff;
addr[3] = data & 0xff;
#endif
}
ENDIAN_INLINE void