[project @ 1996-01-08 20:28:12 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,__)(in, out)                  \
71   P_ in;                                        \
72   htype *out;                                   \
73 {                                               \
74     union {                                     \
75         ctype i;                                \
76         unsigned char cs[sizeof (ctype)];       \
77     } u;                                        \
78     int k;                                      \
79     unsigned char *arr = (unsigned char *) in;  \
80                                                 \
81     for (k = 0; k < sizeof(ctype); k++)         \
82         u.cs[k] = arr[k];                       \
83                                                 \
84     *out = (htype) u.i;                         \
85                                                 \
86     return(sizeof (ctype));                     \
87 }
88     
89 static STG_INLINE
90 void
91 assign_flt(p_dest, src)
92   W_ p_dest[];
93   StgFloat src;
94
95     float_thing y;
96     y.f = src;
97     *p_dest = y.fu;
98 }
99
100
101 static STG_INLINE
102 void
103 assign_dbl(p_dest, src)
104   W_ p_dest[];
105   StgDouble src;
106 {
107     double_thing y;
108     y.d = src;
109     p_dest[0] = y.du.dhi;
110     p_dest[1] = y.du.dlo;
111 }
112
113 #define BYTES2FX(ctype,htype,assign_fx)         \
114 I_                                              \
115 CAT3(bytes2,ctype,__)(in, out)                  \
116   P_ in;                                        \
117   htype *out;                                   \
118 {                                               \
119     union {                                     \
120         ctype i;                                \
121         unsigned char cs[sizeof (ctype)];       \
122     } u;                                        \
123     int k;                                      \
124     unsigned char *arr = (unsigned char *) in;  \
125                                                 \
126     for (k = 0; k < sizeof(ctype); k++)         \
127         u.cs[k] = arr[k];                       \
128                                                 \
129     assign_fx(out, (htype) u.i);                \
130                                                 \
131     return(sizeof (ctype));                     \
132 }
133     
134 BYTES2X(long,I_)
135 BYTES2X(int,I_)
136 BYTES2X(short,I_)
137
138 BYTES2FX(float,StgFloat,assign_flt)
139 BYTES2FX(double,StgDouble,assign_dbl)
140 \end{code}