2de05fa9e2444b61156ac7bcd2995183530096c7
[ghc-hetmet.git] / ghc / lib / misc / cbits / ByteOps.c
1 #if 0
2 %---------------------------------------------------------------*
3 %
4 \section{Underlying code for converting to/from ``bytes''}
5 %
6 %---------------------------------------------------------------*
7
8 Stolen from HBC, more or less.
9
10 A \tr{I_ foo2bytes__(foo in, ptr arr)} routine takes a \tr{foo}
11 input \tr{in}, scribbles some appropriate bytes into the array passed
12 to it, \tr{arr}, and returns the number of bytes so put.
13
14 A \tr{I_ bytes2foo__(ptr arr, foo *out)} routine looks at the
15 array of bytes given to it (\tr{arr}) and gives them back interpreted
16 as a \tr{foo} (sticks it in the place pointed to by \tr{out}).  It
17 returns the number of bytes taken.
18
19 \begin{code}
20 #endif /* 0 */
21
22 #include "rtsdefs.h"
23 #include "ByteOps.h"
24
25 #if __STDC__
26     /* need the ANSI arg decl, so "short" and "float" args dont get promoted */
27 #define X2BYTES(type)                           \
28 I_                                              \
29 CAT2(type,2bytes__)(type in, unsigned char *arr)\
30 {                                               \
31     union {                                     \
32         type i;                                 \
33         unsigned char cs[sizeof (type)];        \
34     } u;                                        \
35     int k;                                      \
36                                                 \
37     u.i = in;                                   \
38     for (k = sizeof (type) - 1; k >= 0; k--)    \
39         arr[k] = u.cs[k];                       \
40                                                 \
41     return(sizeof (type));                      \
42 }
43
44 #else /* not STDC */
45 #define X2BYTES(type)                           \
46 I_                                              \
47 CAT2(type,2bytes__)(in, arr)                    \
48   type in;                                      \
49   unsigned char *arr;                           \
50 {                                               \
51     union {                                     \
52         type i;                                 \
53         unsigned char cs[sizeof (type)];        \
54     } u;                                        \
55     int k;                                      \
56                                                 \
57     u.i = in;                                   \
58     for (k = sizeof (type) - 1; k >= 0; k--)    \
59         arr[k] = u.cs[k];                       \
60                                                 \
61     return(sizeof (type));                      \
62 }
63 #endif /* not STDC */
64
65 X2BYTES(long)
66 X2BYTES(int)
67 X2BYTES(short)
68 X2BYTES(float)
69 X2BYTES(double)
70     
71 #define BYTES2X(ctype,htype)                    \
72 I_                                              \
73 CAT3(bytes2,ctype,__)(P_ in, htype *out)        \
74 {                                               \
75     union {                                     \
76         ctype i;                                \
77         unsigned char cs[sizeof (ctype)];       \
78     } u;                                        \
79     unsigned int k;                             \
80     unsigned char *arr = (unsigned char *) in;  \
81                                                 \
82     for (k = 0; k < sizeof(ctype); k++)         \
83         u.cs[k] = arr[k];                       \
84                                                 \
85     *out = (htype) u.i;                         \
86                                                 \
87     return(sizeof (ctype));                     \
88 }
89     
90 static STG_INLINE
91 void
92 assign_flt(W_ p_dest[], StgFloat src)
93
94     float_thing y;
95     y.f = src;
96     *p_dest = y.fu;
97 }
98
99
100 static STG_INLINE
101 void
102 assign_dbl(W_ p_dest[], StgDouble src)
103 {
104     double_thing y;
105     y.d = src;
106     p_dest[0] = y.du.dhi;
107     p_dest[1] = y.du.dlo;
108 }
109
110 #define BYTES2FX(ctype,htype,assign_fx)         \
111 I_                                              \
112 CAT3(bytes2,ctype,__)(P_ in, htype *out)        \
113 {                                               \
114     union {                                     \
115         ctype i;                                \
116         unsigned char cs[sizeof (ctype)];       \
117     } u;                                        \
118     unsigned int k;                             \
119     unsigned char *arr = (unsigned char *) in;  \
120                                                 \
121     for (k = 0; k < sizeof(ctype); k++)         \
122         u.cs[k] = arr[k];                       \
123                                                 \
124     assign_fx(out, (htype) u.i);                \
125                                                 \
126     return(sizeof (ctype));                     \
127 }
128     
129 BYTES2X(long,I_)
130 BYTES2X(int,I_)
131 BYTES2X(short,I_)
132
133 BYTES2FX(float,StgFloat,assign_flt)
134 BYTES2FX(double,StgDouble,assign_dbl)