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