Merge pull request #757 from mlintner/master
[mono.git] / mono / metadata / mono-endian.h
1 #ifndef _MONO_METADATA_ENDIAN_H_
2 #define _MONO_METADATA_ENDIAN_H_ 1
3
4 #include <glib.h>
5
6 typedef union {
7         guint32 ival;
8         float fval;
9 } mono_rfloat;
10
11 typedef union {
12         guint64 ival;
13         double fval;
14         unsigned char cval [8];
15 } mono_rdouble;
16
17 #if defined(__s390x__)
18
19 #define read16(x)       s390x_read16(*(guint16 *)(x))
20 #define read32(x)       s390x_read32(*(guint32 *)(x))
21 #define read64(x)       s390x_read64(*(guint64 *)(x))
22
23 static __inline__ guint16
24 s390x_read16(guint16 x)
25 {
26         guint16 ret;
27
28         __asm__ ("      lrvr    %0,%1\n"
29                  "      sra     %0,16\n"
30                  : "=r" (ret) : "r" (x));
31
32         return(ret);
33 }
34
35 static __inline__ guint32
36 s390x_read32(guint32 x)
37 {
38         guint32 ret;
39
40         __asm__ ("      lrvr    %0,%1\n"
41                  : "=r" (ret) : "r" (x));
42
43         return(ret);
44 }
45
46 static __inline__ guint64
47 s390x_read64(guint64 x)
48 {
49         guint64 ret;
50
51         __asm__ ("      lrvgr   %0,%1\n"
52                  : "=r" (ret) : "r" (x));
53
54         return(ret);
55 }
56
57 #else
58
59 # if NO_UNALIGNED_ACCESS
60
61 guint16 mono_read16 (const unsigned char *x);
62 guint32 mono_read32 (const unsigned char *x);
63 guint64 mono_read64 (const unsigned char *x);
64
65 #define read16(x) (mono_read16 ((const unsigned char *)(x)))
66 #define read32(x) (mono_read32 ((const unsigned char *)(x)))
67 #define read64(x) (mono_read64 ((const unsigned char *)(x)))
68
69 # else
70
71 #define read16(x) GUINT16_FROM_LE (*((const guint16 *) (x)))
72 #define read32(x) GUINT32_FROM_LE (*((const guint32 *) (x)))
73 #define read64(x) GUINT64_FROM_LE (*((const guint64 *) (x)))
74
75 # endif
76
77 #endif
78
79 #define readr4(x,dest)  \
80         do {    \
81                 mono_rfloat mf; \
82                 mf.ival = read32 ((x)); \
83                 *(dest) = mf.fval;      \
84         } while (0)
85
86 #define readr8(x,dest)  \
87         do {    \
88                 mono_rdouble mf;        \
89                 mf.ival = read64 ((x)); \
90                 *(dest) = mf.fval;      \
91         } while (0)
92
93 #endif /* _MONO_METADATA_ENDIAN_H_ */