2929#endif
3030#endif
3131
32-
33- #if USE_NATIVE_INT128
34-
35- typedef int128 INT128 ;
36-
37- /*
38- * Add an unsigned int64 value into an INT128 variable.
39- */
40- static inline void
41- int128_add_uint64 (INT128 * i128 ,uint64 v )
42- {
43- * i128 += v ;
44- }
45-
4632/*
47- * Add a signed int64 value into an INT128 variable.
48- */
49- static inline void
50- int128_add_int64 (INT128 * i128 ,int64 v )
51- {
52- * i128 += v ;
53- }
54-
55- /*
56- * Add the 128-bit product of two int64 values into an INT128 variable.
33+ * If native int128 support is enabled, INT128 is just int128. Otherwise, it
34+ * is a structure with separate 64-bit high and low parts.
5735 *
58- * XXX with a stupid compiler, this could actually be less efficient than
59- * the other implementation; maybe we should do it by hand always?
60- */
61- static inline void
62- int128_add_int64_mul_int64 (INT128 * i128 ,int64 x ,int64 y )
63- {
64- * i128 += (int128 )x * (int128 )y ;
65- }
66-
67- /*
68- * Compare two INT128 values, return -1, 0, or +1.
69- */
70- static inline int
71- int128_compare (INT128 x ,INT128 y )
72- {
73- if (x < y )
74- return -1 ;
75- if (x > y )
76- return 1 ;
77- return 0 ;
78- }
79-
80- /*
81- * Widen int64 to INT128.
82- */
83- static inline INT128
84- int64_to_int128 (int64 v )
85- {
86- return (INT128 )v ;
87- }
88-
89- /*
90- * Convert INT128 to int64 (losing any high-order bits).
91- * This also works fine for casting down to uint64.
92- */
93- static inline int64
94- int128_to_int64 (INT128 val )
95- {
96- return (int64 )val ;
97- }
98-
99- #else /* !USE_NATIVE_INT128 */
100-
101- /*
10236 * We lay out the INT128 structure with the same content and byte ordering
10337 * that a native int128 type would (probably) have. This makes no difference
10438 * for ordinary use of INT128, but allows union'ing INT128 with int128 for
10539 * testing purposes.
10640 */
41+ #if USE_NATIVE_INT128
42+
43+ typedef int128 INT128 ;
44+
45+ #else
46+
10747typedef struct
10848{
10949#ifdef WORDS_BIGENDIAN
@@ -115,12 +55,17 @@ typedef struct
11555#endif
11656}INT128 ;
11757
58+ #endif
59+
11860/*
11961 * Add an unsigned int64 value into an INT128 variable.
12062 */
12163static inline void
12264int128_add_uint64 (INT128 * i128 ,uint64 v )
12365{
66+ #if USE_NATIVE_INT128
67+ * i128 += v ;
68+ #else
12469/*
12570 * First add the value to the .lo part, then check to see if a carry needs
12671 * to be propagated into the .hi part. A carry is needed if both inputs
@@ -134,6 +79,7 @@ int128_add_uint64(INT128 *i128, uint64 v)
13479if (((int64 )v < 0 && (int64 )oldlo < 0 )||
13580(((int64 )v < 0 || (int64 )oldlo < 0 )&& (int64 )i128 -> lo >=0 ))
13681i128 -> hi ++ ;
82+ #endif
13783}
13884
13985/*
@@ -142,6 +88,9 @@ int128_add_uint64(INT128 *i128, uint64 v)
14288static inline void
14389int128_add_int64 (INT128 * i128 ,int64 v )
14490{
91+ #if USE_NATIVE_INT128
92+ * i128 += v ;
93+ #else
14594/*
14695 * This is much like the above except that the carry logic differs for
14796 * negative v. Ordinarily we'd need to subtract 1 from the .hi part
@@ -161,6 +110,7 @@ int128_add_int64(INT128 *i128, int64 v)
161110if (!((int64 )oldlo < 0 || (int64 )i128 -> lo >=0 ))
162111i128 -> hi -- ;
163112}
113+ #endif
164114}
165115
166116/*
@@ -176,6 +126,13 @@ int128_add_int64(INT128 *i128, int64 v)
176126static inline void
177127int128_add_int64_mul_int64 (INT128 * i128 ,int64 x ,int64 y )
178128{
129+ #if USE_NATIVE_INT128
130+ /*
131+ * XXX with a stupid compiler, this could actually be less efficient than
132+ * the non-native implementation; maybe we should do it by hand always?
133+ */
134+ * i128 += (int128 )x * (int128 )y ;
135+ #else
179136/* INT64_AU32 must use arithmetic right shift */
180137StaticAssertDecl (((int64 )- 1 >>1 )== (int64 )- 1 ,
181138"arithmetic right shift is needed" );
@@ -229,6 +186,7 @@ int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
229186/* the fourth term: always unsigned */
230187int128_add_uint64 (i128 ,x_l32 * y_l32 );
231188}
189+ #endif
232190}
233191
234192/*
@@ -237,6 +195,13 @@ int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
237195static inline int
238196int128_compare (INT128 x ,INT128 y )
239197{
198+ #if USE_NATIVE_INT128
199+ if (x < y )
200+ return -1 ;
201+ if (x > y )
202+ return 1 ;
203+ return 0 ;
204+ #else
240205if (x .hi < y .hi )
241206return -1 ;
242207if (x .hi > y .hi )
@@ -246,6 +211,7 @@ int128_compare(INT128 x, INT128 y)
246211if (x .lo > y .lo )
247212return 1 ;
248213return 0 ;
214+ #endif
249215}
250216
251217/*
@@ -254,11 +220,15 @@ int128_compare(INT128 x, INT128 y)
254220static inline INT128
255221int64_to_int128 (int64 v )
256222{
223+ #if USE_NATIVE_INT128
224+ return (INT128 )v ;
225+ #else
257226INT128 val ;
258227
259228val .lo = (uint64 )v ;
260229val .hi = (v < 0 ) ?- INT64CONST (1 ) :INT64CONST (0 );
261230return val ;
231+ #endif
262232}
263233
264234/*
@@ -268,9 +238,11 @@ int64_to_int128(int64 v)
268238static inline int64
269239int128_to_int64 (INT128 val )
270240{
241+ #if USE_NATIVE_INT128
242+ return (int64 )val ;
243+ #else
271244return (int64 )val .lo ;
245+ #endif
272246}
273247
274- #endif /* USE_NATIVE_INT128 */
275-
276248#endif /* INT128_H */