Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / mono-endian.h
index 6cee6415259bddbf97127c6dbf933e01494e6b7d..8704dc5959d768ec585df4cd4a2ce9596505d978 100644 (file)
@@ -1,3 +1,7 @@
+/**
+ * \file
+ */
+
 #ifndef _MONO_METADATA_ENDIAN_H_
 #define _MONO_METADATA_ENDIAN_H_ 1
 
@@ -14,20 +18,49 @@ typedef union {
        unsigned char cval [8];
 } mono_rdouble;
 
-#ifdef ARM_FPU_FPA
-#define MONO_DOUBLE_ASSERT_ENDIANITY(dbl_ptr) \
-       do { \
-               mono_rdouble r; \
-               r.fval = *dbl_ptr;      \
-               r.ival = (guint64) *((guint32 *) r.cval) << 32 |        \
-                               *((guint32 *) (r.cval + 4));    \
-               *dbl_ptr = r.fval;      \
-       } while (0)
+#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
-#define MONO_DOUBLE_ASSERT_ENDIANITY(dbl_ptr)
-#endif
 
-#if NO_UNALIGNED_ACCESS
+# if NO_UNALIGNED_ACCESS
 
 guint16 mono_read16 (const unsigned char *x);
 guint32 mono_read32 (const unsigned char *x);
@@ -37,12 +70,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) \
@@ -56,7 +91,6 @@ guint64 mono_read64 (const unsigned char *x);
        do {    \
                mono_rdouble mf;        \
                mf.ival = read64 ((x)); \
-               MONO_DOUBLE_ASSERT_ENDIANITY (&mf.fval);        \
                *(dest) = mf.fval;      \
        } while (0)