Hi, I am proposing the following changes to mono-endian.h to optimize little-endian to big-endian processing for s390x. The architecture defines instructions for just this purpose so instead of doing shifts etc. we can just do this:
--- a/mono/metadata/mono-endian.h +++ b/mono/metadata/mono-endian.h @@ -14,7 +14,49 @@ typedef union { unsigned char cval [8]; } mono_rdouble; -#if NO_UNALIGNED_ACCESS +#if defined(__s390x__) + +#define read16(x) s390x_read16(*(guint16 *)(x)) +#define read32(x) s390x_read32(*(guint32 *)(x)) +#define read64(x) s390x_read64(*(guint64 *)(x)) + +static __inline__ guint16 +s390x_read16(guint16 x) +{ + guint16 ret; + + __asm__ (" lrvr %0,%1\n" + " sra %0,16\n" + : "=r" (ret) : "r" (x)); + + return(ret); +} + +static __inline__ guint32 +s390x_read32(guint32 x) +{ + guint32 ret; + + __asm__ (" lrvr %0,%1\n" + : "=r" (ret) : "r" (x)); + + return(ret); +} + +static __inline__ guint64 +s390x_read64(guint64 x) +{ + guint64 ret; + + __asm__ (" lrvgr %0,%1\n" + : "=r" (ret) : "r" (x)); + + return(ret); +} + +#else + +# if NO_UNALIGNED_ACCESS guint16 mono_read16 (const unsigned char *x); guint32 mono_read32 (const unsigned char *x); @@ -24,12 +66,14 @@ guint64 mono_read64 (const unsigned char *x); #define read32(x) (mono_read32 ((const unsigned char *)(x))) #define read64(x) (mono_read64 ((const unsigned char *)(x))) -#else +# else #define read16(x) GUINT16_FROM_LE (*((const guint16 *) (x))) #define read32(x) GUINT32_FROM_LE (*((const guint32 *) (x))) #define read64(x) GUINT64_FROM_LE (*((const guint64 *) (x))) +# endif + #endif #define readr4(x,dest) \ Any objections? Neale _______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list