Deleted Added
full compact
ntp_fp.h (54359) ntp_fp.h (132451)
1/*
2 * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic
3 */
4
5#ifndef NTP_FP_H
6#define NTP_FP_H
7
8#include <sys/types.h>
9#include <sys/socket.h>
1/*
2 * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic
3 */
4
5#ifndef NTP_FP_H
6#define NTP_FP_H
7
8#include <sys/types.h>
9#include <sys/socket.h>
10#include "ntp_rfc2553.h"
10#include <netinet/in.h>
11
12#include "ntp_types.h"
13
14/*
15 * NTP uses two fixed point formats. The first (l_fp) is the "long"
16 * format and is 64 bits long with the decimal between bits 31 and 32.
17 * This is used for time stamps in the NTP packet header (in network
18 * byte order) and for internal computations of offsets (in local host
19 * byte order). We use the same structure for both signed and unsigned
20 * values, which is a big hack but saves rewriting all the operators
21 * twice. Just to confuse this, we also sometimes just carry the
22 * fractional part in calculations, in both signed and unsigned forms.
23 * Anyway, an l_fp looks like:
24 *
25 * 0 1 2 3
26 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
27 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28 * | Integral Part |
29 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 * | Fractional Part |
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 *
33 */
34typedef struct {
35 union {
36 u_int32 Xl_ui;
37 int32 Xl_i;
38 } Ul_i;
39 union {
40 u_int32 Xl_uf;
41 int32 Xl_f;
42 } Ul_f;
43} l_fp;
44
45#define l_ui Ul_i.Xl_ui /* unsigned integral part */
46#define l_i Ul_i.Xl_i /* signed integral part */
47#define l_uf Ul_f.Xl_uf /* unsigned fractional part */
48#define l_f Ul_f.Xl_f /* signed fractional part */
49
50/*
51 * Fractional precision (of an l_fp) is actually the number of
52 * bits in a long.
53 */
54#define FRACTION_PREC (32)
55
56
57/*
58 * The second fixed point format is 32 bits, with the decimal between
59 * bits 15 and 16. There is a signed version (s_fp) and an unsigned
60 * version (u_fp). This is used to represent synchronizing distance
61 * and synchronizing dispersion in the NTP packet header (again, in
62 * network byte order) and internally to hold both distance and
63 * dispersion values (in local byte order). In network byte order
64 * it looks like:
65 *
66 * 0 1 2 3
67 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 * | Integer Part | Fraction Part |
70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 *
72 */
73typedef int32 s_fp;
74typedef u_int32 u_fp;
75
76/*
77 * A unit second in fp format. Actually 2**(half_the_bits_in_a_long)
78 */
79#define FP_SECOND (0x10000)
80
81/*
82 * Byte order conversions
83 */
84#define HTONS_FP(x) (htonl(x))
85#define HTONL_FP(h, n) do { (n)->l_ui = htonl((h)->l_ui); \
86 (n)->l_uf = htonl((h)->l_uf); } while (0)
87#define NTOHS_FP(x) (ntohl(x))
88#define NTOHL_FP(n, h) do { (h)->l_ui = ntohl((n)->l_ui); \
89 (h)->l_uf = ntohl((n)->l_uf); } while (0)
90#define NTOHL_MFP(ni, nf, hi, hf) \
91 do { (hi) = ntohl(ni); (hf) = ntohl(nf); } while (0)
92#define HTONL_MFP(hi, hf, ni, nf) \
93 do { (ni) = ntohl(hi); (nf) = ntohl(hf); } while (0)
94
95/* funny ones. Converts ts fractions to net order ts */
96#define HTONL_UF(uf, nts) \
97 do { (nts)->l_ui = 0; (nts)->l_uf = htonl(uf); } while (0)
98#define HTONL_F(f, nts) do { (nts)->l_uf = htonl(f); \
99 if ((f) & 0x80000000) \
100 (nts)->l_i = -1; \
101 else \
102 (nts)->l_i = 0; \
103 } while (0)
104
105/*
106 * Conversions between the two fixed point types
107 */
108#define MFPTOFP(x_i, x_f) (((x_i) >= 0x00010000) ? 0x7fffffff : \
109 (((x_i) <= -0x00010000) ? 0x80000000 : \
110 (((x_i)<<16) | (((x_f)>>16)&0xffff))))
111#define LFPTOFP(v) MFPTOFP((v)->l_i, (v)->l_f)
112
113#define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16)
114#define FPTOLFP(x, v) (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0)
115
116#define MAXLFP(v) ((v)->l_ui = 0x7fffffff, (v)->l_uf = 0xffffffff)
117#define MINLFP(v) ((v)->l_ui = 0x80000000, (v)->l_uf = 0)
118
119/*
120 * Primitive operations on long fixed point values. If these are
121 * reminiscent of assembler op codes it's only because some may
122 * be replaced by inline assembler for particular machines someday.
123 * These are the (kind of inefficient) run-anywhere versions.
124 */
125#define M_NEG(v_i, v_f) /* v = -v */ \
126 do { \
127 if ((v_f) == 0) \
128 (v_i) = -((s_fp)(v_i)); \
129 else { \
130 (v_f) = -((s_fp)(v_f)); \
131 (v_i) = ~(v_i); \
132 } \
133 } while(0)
134
135#define M_NEGM(r_i, r_f, a_i, a_f) /* r = -a */ \
136 do { \
137 if ((a_f) == 0) { \
138 (r_f) = 0; \
139 (r_i) = -(a_i); \
140 } else { \
141 (r_f) = -(a_f); \
142 (r_i) = ~(a_i); \
143 } \
144 } while(0)
145
146#define M_ADD(r_i, r_f, a_i, a_f) /* r += a */ \
147 do { \
148 register u_int32 lo_tmp; \
149 register u_int32 hi_tmp; \
150 \
151 lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
152 hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
153 if (lo_tmp & 0x10000) \
154 hi_tmp++; \
155 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
156 \
157 (r_i) += (a_i); \
158 if (hi_tmp & 0x10000) \
159 (r_i)++; \
160 } while (0)
161
162#define M_ADD3(r_ovr, r_i, r_f, a_ovr, a_i, a_f) /* r += a, three word */ \
163 do { \
164 register u_int32 lo_tmp; \
165 register u_int32 hi_tmp; \
166 \
167 lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
168 hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
169 if (lo_tmp & 0x10000) \
170 hi_tmp++; \
171 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
172 \
173 lo_tmp = ((r_i) & 0xffff) + ((a_i) & 0xffff); \
174 if (hi_tmp & 0x10000) \
175 lo_tmp++; \
176 hi_tmp = (((r_i) >> 16) & 0xffff) + (((a_i) >> 16) & 0xffff); \
177 if (lo_tmp & 0x10000) \
178 hi_tmp++; \
179 (r_i) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
180 \
181 (r_ovr) += (a_ovr); \
182 if (hi_tmp & 0x10000) \
183 (r_ovr)++; \
184 } while (0)
185
186#define M_SUB(r_i, r_f, a_i, a_f) /* r -= a */ \
187 do { \
188 register u_int32 lo_tmp; \
189 register u_int32 hi_tmp; \
190 \
191 if ((a_f) == 0) { \
192 (r_i) -= (a_i); \
193 } else { \
194 lo_tmp = ((r_f) & 0xffff) + ((-((s_fp)(a_f))) & 0xffff); \
195 hi_tmp = (((r_f) >> 16) & 0xffff) \
196 + (((-((s_fp)(a_f))) >> 16) & 0xffff); \
197 if (lo_tmp & 0x10000) \
198 hi_tmp++; \
199 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
200 \
201 (r_i) += ~(a_i); \
202 if (hi_tmp & 0x10000) \
203 (r_i)++; \
204 } \
205 } while (0)
206
207#define M_RSHIFTU(v_i, v_f) /* v >>= 1, v is unsigned */ \
208 do { \
209 (v_f) = (u_int32)(v_f) >> 1; \
210 if ((v_i) & 01) \
211 (v_f) |= 0x80000000; \
212 (v_i) = (u_int32)(v_i) >> 1; \
213 } while (0)
214
215#define M_RSHIFT(v_i, v_f) /* v >>= 1, v is signed */ \
216 do { \
217 (v_f) = (u_int32)(v_f) >> 1; \
218 if ((v_i) & 01) \
219 (v_f) |= 0x80000000; \
220 if ((v_i) & 0x80000000) \
221 (v_i) = ((v_i) >> 1) | 0x80000000; \
222 else \
223 (v_i) = (v_i) >> 1; \
224 } while (0)
225
226#define M_LSHIFT(v_i, v_f) /* v <<= 1 */ \
227 do { \
228 (v_i) <<= 1; \
229 if ((v_f) & 0x80000000) \
230 (v_i) |= 0x1; \
231 (v_f) <<= 1; \
232 } while (0)
233
234#define M_LSHIFT3(v_ovr, v_i, v_f) /* v <<= 1, with overflow */ \
235 do { \
236 (v_ovr) <<= 1; \
237 if ((v_i) & 0x80000000) \
238 (v_ovr) |= 0x1; \
239 (v_i) <<= 1; \
240 if ((v_f) & 0x80000000) \
241 (v_i) |= 0x1; \
242 (v_f) <<= 1; \
243 } while (0)
244
245#define M_ADDUF(r_i, r_f, uf) /* r += uf, uf is u_int32 fraction */ \
246 M_ADD((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
247
248#define M_SUBUF(r_i, r_f, uf) /* r -= uf, uf is u_int32 fraction */ \
249 M_SUB((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
250
251#define M_ADDF(r_i, r_f, f) /* r += f, f is a int32 fraction */ \
252 do { \
253 if ((f) > 0) \
254 M_ADD((r_i), (r_f), 0, (f)); \
255 else if ((f) < 0) \
256 M_ADD((r_i), (r_f), (-1), (f));\
257 } while(0)
258
259#define M_ISNEG(v_i, v_f) /* v < 0 */ \
260 (((v_i) & 0x80000000) != 0)
261
262#define M_ISHIS(a_i, a_f, b_i, b_f) /* a >= b unsigned */ \
263 (((u_int32)(a_i)) > ((u_int32)(b_i)) || \
264 ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f))))
265
266#define M_ISGEQ(a_i, a_f, b_i, b_f) /* a >= b signed */ \
267 (((int32)(a_i)) > ((int32)(b_i)) || \
268 ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f))))
269
270#define M_ISEQU(a_i, a_f, b_i, b_f) /* a == b unsigned */ \
271 ((a_i) == (b_i) && (a_f) == (b_f))
272
273/*
274 * Operations on the long fp format
275 */
276#define L_ADD(r, a) M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
277#define L_SUB(r, a) M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
278#define L_NEG(v) M_NEG((v)->l_ui, (v)->l_uf)
279#define L_ADDUF(r, uf) M_ADDUF((r)->l_ui, (r)->l_uf, (uf))
280#define L_SUBUF(r, uf) M_SUBUF((r)->l_ui, (r)->l_uf, (uf))
281#define L_ADDF(r, f) M_ADDF((r)->l_ui, (r)->l_uf, (f))
282#define L_RSHIFT(v) M_RSHIFT((v)->l_i, (v)->l_uf)
283#define L_RSHIFTU(v) M_RSHIFT((v)->l_ui, (v)->l_uf)
284#define L_LSHIFT(v) M_LSHIFT((v)->l_ui, (v)->l_uf)
285#define L_CLR(v) ((v)->l_ui = (v)->l_uf = 0)
286
287#define L_ISNEG(v) (((v)->l_ui & 0x80000000) != 0)
288#define L_ISZERO(v) ((v)->l_ui == 0 && (v)->l_uf == 0)
289#define L_ISHIS(a, b) ((a)->l_ui > (b)->l_ui || \
290 ((a)->l_ui == (b)->l_ui && (a)->l_uf >= (b)->l_uf))
291#define L_ISGEQ(a, b) ((a)->l_i > (b)->l_i || \
292 ((a)->l_i == (b)->l_i && (a)->l_uf >= (b)->l_uf))
293#define L_ISEQU(a, b) M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
294
295/*
296 * s_fp/double and u_fp/double conversions
297 */
298#define FRIC 65536. /* 2^16 as a double */
299#define DTOFP(r) ((s_fp)((r) * FRIC))
300#define DTOUFP(r) ((u_fp)((r) * FRIC))
301#define FPTOD(r) ((double)(r) / FRIC)
302
303/*
304 * l_fp/double conversions
305 */
306#define FRAC 4294967296. /* 2^32 as a double */
307#define M_DTOLFP(d, r_i, r_uf) /* double to l_fp */ \
308 do { \
309 register double d_tmp; \
310 \
311 d_tmp = (d); \
312 if (d_tmp < 0) { \
313 d_tmp = -d_tmp; \
314 (r_i) = (int32)(d_tmp); \
315 (r_uf) = (u_int32)(((d_tmp) - (double)(r_i)) * FRAC); \
316 M_NEG((r_i), (r_uf)); \
317 } else { \
318 (r_i) = (int32)(d_tmp); \
319 (r_uf) = (u_int32)(((d_tmp) - (double)(r_i)) * FRAC); \
320 } \
321 } while (0)
322#define M_LFPTOD(r_i, r_uf, d) /* l_fp to double */ \
323 do { \
324 register l_fp l_tmp; \
325 \
326 l_tmp.l_i = (r_i); \
327 l_tmp.l_f = (r_uf); \
328 if (l_tmp.l_i < 0) { \
329 M_NEG(l_tmp.l_i, l_tmp.l_uf); \
330 (d) = -((double)l_tmp.l_i + ((double)l_tmp.l_uf) / FRAC); \
331 } else { \
332 (d) = (double)l_tmp.l_i + ((double)l_tmp.l_uf) / FRAC; \
333 } \
334 } while (0)
335#define DTOLFP(d, v) M_DTOLFP((d), (v)->l_ui, (v)->l_uf)
336#define LFPTOD(v, d) M_LFPTOD((v)->l_ui, (v)->l_uf, (d))
337
338/*
339 * Prototypes
340 */
11#include <netinet/in.h>
12
13#include "ntp_types.h"
14
15/*
16 * NTP uses two fixed point formats. The first (l_fp) is the "long"
17 * format and is 64 bits long with the decimal between bits 31 and 32.
18 * This is used for time stamps in the NTP packet header (in network
19 * byte order) and for internal computations of offsets (in local host
20 * byte order). We use the same structure for both signed and unsigned
21 * values, which is a big hack but saves rewriting all the operators
22 * twice. Just to confuse this, we also sometimes just carry the
23 * fractional part in calculations, in both signed and unsigned forms.
24 * Anyway, an l_fp looks like:
25 *
26 * 0 1 2 3
27 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
28 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 * | Integral Part |
30 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 * | Fractional Part |
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 *
34 */
35typedef struct {
36 union {
37 u_int32 Xl_ui;
38 int32 Xl_i;
39 } Ul_i;
40 union {
41 u_int32 Xl_uf;
42 int32 Xl_f;
43 } Ul_f;
44} l_fp;
45
46#define l_ui Ul_i.Xl_ui /* unsigned integral part */
47#define l_i Ul_i.Xl_i /* signed integral part */
48#define l_uf Ul_f.Xl_uf /* unsigned fractional part */
49#define l_f Ul_f.Xl_f /* signed fractional part */
50
51/*
52 * Fractional precision (of an l_fp) is actually the number of
53 * bits in a long.
54 */
55#define FRACTION_PREC (32)
56
57
58/*
59 * The second fixed point format is 32 bits, with the decimal between
60 * bits 15 and 16. There is a signed version (s_fp) and an unsigned
61 * version (u_fp). This is used to represent synchronizing distance
62 * and synchronizing dispersion in the NTP packet header (again, in
63 * network byte order) and internally to hold both distance and
64 * dispersion values (in local byte order). In network byte order
65 * it looks like:
66 *
67 * 0 1 2 3
68 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
69 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 * | Integer Part | Fraction Part |
71 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 *
73 */
74typedef int32 s_fp;
75typedef u_int32 u_fp;
76
77/*
78 * A unit second in fp format. Actually 2**(half_the_bits_in_a_long)
79 */
80#define FP_SECOND (0x10000)
81
82/*
83 * Byte order conversions
84 */
85#define HTONS_FP(x) (htonl(x))
86#define HTONL_FP(h, n) do { (n)->l_ui = htonl((h)->l_ui); \
87 (n)->l_uf = htonl((h)->l_uf); } while (0)
88#define NTOHS_FP(x) (ntohl(x))
89#define NTOHL_FP(n, h) do { (h)->l_ui = ntohl((n)->l_ui); \
90 (h)->l_uf = ntohl((n)->l_uf); } while (0)
91#define NTOHL_MFP(ni, nf, hi, hf) \
92 do { (hi) = ntohl(ni); (hf) = ntohl(nf); } while (0)
93#define HTONL_MFP(hi, hf, ni, nf) \
94 do { (ni) = ntohl(hi); (nf) = ntohl(hf); } while (0)
95
96/* funny ones. Converts ts fractions to net order ts */
97#define HTONL_UF(uf, nts) \
98 do { (nts)->l_ui = 0; (nts)->l_uf = htonl(uf); } while (0)
99#define HTONL_F(f, nts) do { (nts)->l_uf = htonl(f); \
100 if ((f) & 0x80000000) \
101 (nts)->l_i = -1; \
102 else \
103 (nts)->l_i = 0; \
104 } while (0)
105
106/*
107 * Conversions between the two fixed point types
108 */
109#define MFPTOFP(x_i, x_f) (((x_i) >= 0x00010000) ? 0x7fffffff : \
110 (((x_i) <= -0x00010000) ? 0x80000000 : \
111 (((x_i)<<16) | (((x_f)>>16)&0xffff))))
112#define LFPTOFP(v) MFPTOFP((v)->l_i, (v)->l_f)
113
114#define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16)
115#define FPTOLFP(x, v) (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0)
116
117#define MAXLFP(v) ((v)->l_ui = 0x7fffffff, (v)->l_uf = 0xffffffff)
118#define MINLFP(v) ((v)->l_ui = 0x80000000, (v)->l_uf = 0)
119
120/*
121 * Primitive operations on long fixed point values. If these are
122 * reminiscent of assembler op codes it's only because some may
123 * be replaced by inline assembler for particular machines someday.
124 * These are the (kind of inefficient) run-anywhere versions.
125 */
126#define M_NEG(v_i, v_f) /* v = -v */ \
127 do { \
128 if ((v_f) == 0) \
129 (v_i) = -((s_fp)(v_i)); \
130 else { \
131 (v_f) = -((s_fp)(v_f)); \
132 (v_i) = ~(v_i); \
133 } \
134 } while(0)
135
136#define M_NEGM(r_i, r_f, a_i, a_f) /* r = -a */ \
137 do { \
138 if ((a_f) == 0) { \
139 (r_f) = 0; \
140 (r_i) = -(a_i); \
141 } else { \
142 (r_f) = -(a_f); \
143 (r_i) = ~(a_i); \
144 } \
145 } while(0)
146
147#define M_ADD(r_i, r_f, a_i, a_f) /* r += a */ \
148 do { \
149 register u_int32 lo_tmp; \
150 register u_int32 hi_tmp; \
151 \
152 lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
153 hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
154 if (lo_tmp & 0x10000) \
155 hi_tmp++; \
156 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
157 \
158 (r_i) += (a_i); \
159 if (hi_tmp & 0x10000) \
160 (r_i)++; \
161 } while (0)
162
163#define M_ADD3(r_ovr, r_i, r_f, a_ovr, a_i, a_f) /* r += a, three word */ \
164 do { \
165 register u_int32 lo_tmp; \
166 register u_int32 hi_tmp; \
167 \
168 lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
169 hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
170 if (lo_tmp & 0x10000) \
171 hi_tmp++; \
172 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
173 \
174 lo_tmp = ((r_i) & 0xffff) + ((a_i) & 0xffff); \
175 if (hi_tmp & 0x10000) \
176 lo_tmp++; \
177 hi_tmp = (((r_i) >> 16) & 0xffff) + (((a_i) >> 16) & 0xffff); \
178 if (lo_tmp & 0x10000) \
179 hi_tmp++; \
180 (r_i) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
181 \
182 (r_ovr) += (a_ovr); \
183 if (hi_tmp & 0x10000) \
184 (r_ovr)++; \
185 } while (0)
186
187#define M_SUB(r_i, r_f, a_i, a_f) /* r -= a */ \
188 do { \
189 register u_int32 lo_tmp; \
190 register u_int32 hi_tmp; \
191 \
192 if ((a_f) == 0) { \
193 (r_i) -= (a_i); \
194 } else { \
195 lo_tmp = ((r_f) & 0xffff) + ((-((s_fp)(a_f))) & 0xffff); \
196 hi_tmp = (((r_f) >> 16) & 0xffff) \
197 + (((-((s_fp)(a_f))) >> 16) & 0xffff); \
198 if (lo_tmp & 0x10000) \
199 hi_tmp++; \
200 (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
201 \
202 (r_i) += ~(a_i); \
203 if (hi_tmp & 0x10000) \
204 (r_i)++; \
205 } \
206 } while (0)
207
208#define M_RSHIFTU(v_i, v_f) /* v >>= 1, v is unsigned */ \
209 do { \
210 (v_f) = (u_int32)(v_f) >> 1; \
211 if ((v_i) & 01) \
212 (v_f) |= 0x80000000; \
213 (v_i) = (u_int32)(v_i) >> 1; \
214 } while (0)
215
216#define M_RSHIFT(v_i, v_f) /* v >>= 1, v is signed */ \
217 do { \
218 (v_f) = (u_int32)(v_f) >> 1; \
219 if ((v_i) & 01) \
220 (v_f) |= 0x80000000; \
221 if ((v_i) & 0x80000000) \
222 (v_i) = ((v_i) >> 1) | 0x80000000; \
223 else \
224 (v_i) = (v_i) >> 1; \
225 } while (0)
226
227#define M_LSHIFT(v_i, v_f) /* v <<= 1 */ \
228 do { \
229 (v_i) <<= 1; \
230 if ((v_f) & 0x80000000) \
231 (v_i) |= 0x1; \
232 (v_f) <<= 1; \
233 } while (0)
234
235#define M_LSHIFT3(v_ovr, v_i, v_f) /* v <<= 1, with overflow */ \
236 do { \
237 (v_ovr) <<= 1; \
238 if ((v_i) & 0x80000000) \
239 (v_ovr) |= 0x1; \
240 (v_i) <<= 1; \
241 if ((v_f) & 0x80000000) \
242 (v_i) |= 0x1; \
243 (v_f) <<= 1; \
244 } while (0)
245
246#define M_ADDUF(r_i, r_f, uf) /* r += uf, uf is u_int32 fraction */ \
247 M_ADD((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
248
249#define M_SUBUF(r_i, r_f, uf) /* r -= uf, uf is u_int32 fraction */ \
250 M_SUB((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
251
252#define M_ADDF(r_i, r_f, f) /* r += f, f is a int32 fraction */ \
253 do { \
254 if ((f) > 0) \
255 M_ADD((r_i), (r_f), 0, (f)); \
256 else if ((f) < 0) \
257 M_ADD((r_i), (r_f), (-1), (f));\
258 } while(0)
259
260#define M_ISNEG(v_i, v_f) /* v < 0 */ \
261 (((v_i) & 0x80000000) != 0)
262
263#define M_ISHIS(a_i, a_f, b_i, b_f) /* a >= b unsigned */ \
264 (((u_int32)(a_i)) > ((u_int32)(b_i)) || \
265 ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f))))
266
267#define M_ISGEQ(a_i, a_f, b_i, b_f) /* a >= b signed */ \
268 (((int32)(a_i)) > ((int32)(b_i)) || \
269 ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f))))
270
271#define M_ISEQU(a_i, a_f, b_i, b_f) /* a == b unsigned */ \
272 ((a_i) == (b_i) && (a_f) == (b_f))
273
274/*
275 * Operations on the long fp format
276 */
277#define L_ADD(r, a) M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
278#define L_SUB(r, a) M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
279#define L_NEG(v) M_NEG((v)->l_ui, (v)->l_uf)
280#define L_ADDUF(r, uf) M_ADDUF((r)->l_ui, (r)->l_uf, (uf))
281#define L_SUBUF(r, uf) M_SUBUF((r)->l_ui, (r)->l_uf, (uf))
282#define L_ADDF(r, f) M_ADDF((r)->l_ui, (r)->l_uf, (f))
283#define L_RSHIFT(v) M_RSHIFT((v)->l_i, (v)->l_uf)
284#define L_RSHIFTU(v) M_RSHIFT((v)->l_ui, (v)->l_uf)
285#define L_LSHIFT(v) M_LSHIFT((v)->l_ui, (v)->l_uf)
286#define L_CLR(v) ((v)->l_ui = (v)->l_uf = 0)
287
288#define L_ISNEG(v) (((v)->l_ui & 0x80000000) != 0)
289#define L_ISZERO(v) ((v)->l_ui == 0 && (v)->l_uf == 0)
290#define L_ISHIS(a, b) ((a)->l_ui > (b)->l_ui || \
291 ((a)->l_ui == (b)->l_ui && (a)->l_uf >= (b)->l_uf))
292#define L_ISGEQ(a, b) ((a)->l_i > (b)->l_i || \
293 ((a)->l_i == (b)->l_i && (a)->l_uf >= (b)->l_uf))
294#define L_ISEQU(a, b) M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
295
296/*
297 * s_fp/double and u_fp/double conversions
298 */
299#define FRIC 65536. /* 2^16 as a double */
300#define DTOFP(r) ((s_fp)((r) * FRIC))
301#define DTOUFP(r) ((u_fp)((r) * FRIC))
302#define FPTOD(r) ((double)(r) / FRIC)
303
304/*
305 * l_fp/double conversions
306 */
307#define FRAC 4294967296. /* 2^32 as a double */
308#define M_DTOLFP(d, r_i, r_uf) /* double to l_fp */ \
309 do { \
310 register double d_tmp; \
311 \
312 d_tmp = (d); \
313 if (d_tmp < 0) { \
314 d_tmp = -d_tmp; \
315 (r_i) = (int32)(d_tmp); \
316 (r_uf) = (u_int32)(((d_tmp) - (double)(r_i)) * FRAC); \
317 M_NEG((r_i), (r_uf)); \
318 } else { \
319 (r_i) = (int32)(d_tmp); \
320 (r_uf) = (u_int32)(((d_tmp) - (double)(r_i)) * FRAC); \
321 } \
322 } while (0)
323#define M_LFPTOD(r_i, r_uf, d) /* l_fp to double */ \
324 do { \
325 register l_fp l_tmp; \
326 \
327 l_tmp.l_i = (r_i); \
328 l_tmp.l_f = (r_uf); \
329 if (l_tmp.l_i < 0) { \
330 M_NEG(l_tmp.l_i, l_tmp.l_uf); \
331 (d) = -((double)l_tmp.l_i + ((double)l_tmp.l_uf) / FRAC); \
332 } else { \
333 (d) = (double)l_tmp.l_i + ((double)l_tmp.l_uf) / FRAC; \
334 } \
335 } while (0)
336#define DTOLFP(d, v) M_DTOLFP((d), (v)->l_ui, (v)->l_uf)
337#define LFPTOD(v, d) M_LFPTOD((v)->l_ui, (v)->l_uf, (d))
338
339/*
340 * Prototypes
341 */
341extern char * dofptoa P((u_fp, int, int, int));
342extern char * dolfptoa P((u_long, u_long, int, int, int));
342extern char * dofptoa P((u_fp, int, short, int));
343extern char * dolfptoa P((u_long, u_long, int, short, int));
343
344extern int atolfp P((const char *, l_fp *));
345extern int buftvtots P((const char *, l_fp *));
344
345extern int atolfp P((const char *, l_fp *));
346extern int buftvtots P((const char *, l_fp *));
346extern char * fptoa P((s_fp, int));
347extern char * fptoms P((s_fp, int));
348extern char * fptoms P((s_fp, int));
347extern char * fptoa P((s_fp, short));
348extern char * fptoms P((s_fp, short));
349extern int hextolfp P((const char *, l_fp *));
350extern void gpstolfp P((int, int, unsigned long, l_fp *));
351extern int mstolfp P((const char *, l_fp *));
352extern char * prettydate P((l_fp *));
353extern char * gmprettydate P((l_fp *));
354extern char * uglydate P((l_fp *));
355extern void mfp_mul P((int32 *, u_int32 *, int32, u_int32, int32, u_int32));
356
357extern void get_systime P((l_fp *));
358extern int step_systime P((double));
359extern int adj_systime P((double));
360
361#define lfptoa(_fpv, _ndec) mfptoa((_fpv)->l_ui, (_fpv)->l_uf, (_ndec))
362#define lfptoms(_fpv, _ndec) mfptoms((_fpv)->l_ui, (_fpv)->l_uf, (_ndec))
363
349extern int hextolfp P((const char *, l_fp *));
350extern void gpstolfp P((int, int, unsigned long, l_fp *));
351extern int mstolfp P((const char *, l_fp *));
352extern char * prettydate P((l_fp *));
353extern char * gmprettydate P((l_fp *));
354extern char * uglydate P((l_fp *));
355extern void mfp_mul P((int32 *, u_int32 *, int32, u_int32, int32, u_int32));
356
357extern void get_systime P((l_fp *));
358extern int step_systime P((double));
359extern int adj_systime P((double));
360
361#define lfptoa(_fpv, _ndec) mfptoa((_fpv)->l_ui, (_fpv)->l_uf, (_ndec))
362#define lfptoms(_fpv, _ndec) mfptoms((_fpv)->l_ui, (_fpv)->l_uf, (_ndec))
363
364#define ntoa(_sin) numtoa((_sin)->sin_addr.s_addr)
365#define ntohost(_sin) numtohost((_sin)->sin_addr.s_addr)
364#define stoa(_sin) socktoa((_sin))
365#define stohost(_sin) socktohost((_sin))
366
366
367#define ntoa(_sin) stoa(_sin)
368#define ntohost(_sin) stohost(_sin)
369
367#define ufptoa(_fpv, _ndec) dofptoa((_fpv), 0, (_ndec), 0)
368#define ufptoms(_fpv, _ndec) dofptoa((_fpv), 0, (_ndec), 1)
369#define ulfptoa(_fpv, _ndec) dolfptoa((_fpv)->l_ui, (_fpv)->l_uf, 0, (_ndec), 0)
370#define ulfptoms(_fpv, _ndec) dolfptoa((_fpv)->l_ui, (_fpv)->l_uf, 0, (_ndec), 1)
371#define umfptoa(_fpi, _fpf, _ndec) dolfptoa((_fpi), (_fpf), 0, (_ndec), 0)
372
373#endif /* NTP_FP_H */
370#define ufptoa(_fpv, _ndec) dofptoa((_fpv), 0, (_ndec), 0)
371#define ufptoms(_fpv, _ndec) dofptoa((_fpv), 0, (_ndec), 1)
372#define ulfptoa(_fpv, _ndec) dolfptoa((_fpv)->l_ui, (_fpv)->l_uf, 0, (_ndec), 0)
373#define ulfptoms(_fpv, _ndec) dolfptoa((_fpv)->l_ui, (_fpv)->l_uf, 0, (_ndec), 1)
374#define umfptoa(_fpi, _fpf, _ndec) dolfptoa((_fpi), (_fpf), 0, (_ndec), 0)
375
376#endif /* NTP_FP_H */